SCCP.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //===-- SCCP.cpp ----------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements Interprocedural Sparse Conditional Constant Propagation.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Transforms/IPO/SCCP.h"
  13. #include "llvm/Analysis/AssumptionCache.h"
  14. #include "llvm/Analysis/PostDominators.h"
  15. #include "llvm/Analysis/TargetLibraryInfo.h"
  16. #include "llvm/Analysis/TargetTransformInfo.h"
  17. #include "llvm/InitializePasses.h"
  18. #include "llvm/Transforms/IPO.h"
  19. #include "llvm/Transforms/Scalar/SCCP.h"
  20. using namespace llvm;
  21. PreservedAnalyses IPSCCPPass::run(Module &M, ModuleAnalysisManager &AM) {
  22. const DataLayout &DL = M.getDataLayout();
  23. auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  24. auto GetTLI = [&FAM](Function &F) -> const TargetLibraryInfo & {
  25. return FAM.getResult<TargetLibraryAnalysis>(F);
  26. };
  27. auto getAnalysis = [&FAM](Function &F) -> AnalysisResultsForFn {
  28. DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
  29. return {
  30. std::make_unique<PredicateInfo>(F, DT, FAM.getResult<AssumptionAnalysis>(F)),
  31. &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F)};
  32. };
  33. if (!runIPSCCP(M, DL, GetTLI, getAnalysis))
  34. return PreservedAnalyses::all();
  35. PreservedAnalyses PA;
  36. PA.preserve<DominatorTreeAnalysis>();
  37. PA.preserve<PostDominatorTreeAnalysis>();
  38. PA.preserve<FunctionAnalysisManagerModuleProxy>();
  39. return PA;
  40. }
  41. namespace {
  42. //===--------------------------------------------------------------------===//
  43. //
  44. /// IPSCCP Class - This class implements interprocedural Sparse Conditional
  45. /// Constant Propagation.
  46. ///
  47. class IPSCCPLegacyPass : public ModulePass {
  48. public:
  49. static char ID;
  50. IPSCCPLegacyPass() : ModulePass(ID) {
  51. initializeIPSCCPLegacyPassPass(*PassRegistry::getPassRegistry());
  52. }
  53. bool runOnModule(Module &M) override {
  54. if (skipModule(M))
  55. return false;
  56. const DataLayout &DL = M.getDataLayout();
  57. auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & {
  58. return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
  59. };
  60. auto getAnalysis = [this](Function &F) -> AnalysisResultsForFn {
  61. DominatorTree &DT =
  62. this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
  63. return {
  64. std::make_unique<PredicateInfo>(
  65. F, DT,
  66. this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
  67. F)),
  68. nullptr, // We cannot preserve the DT or PDT with the legacy pass
  69. nullptr}; // manager, so set them to nullptr.
  70. };
  71. return runIPSCCP(M, DL, GetTLI, getAnalysis);
  72. }
  73. void getAnalysisUsage(AnalysisUsage &AU) const override {
  74. AU.addRequired<AssumptionCacheTracker>();
  75. AU.addRequired<DominatorTreeWrapperPass>();
  76. AU.addRequired<TargetLibraryInfoWrapperPass>();
  77. }
  78. };
  79. } // end anonymous namespace
  80. char IPSCCPLegacyPass::ID = 0;
  81. INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp",
  82. "Interprocedural Sparse Conditional Constant Propagation",
  83. false, false)
  84. INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
  85. INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
  86. INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
  87. INITIALIZE_PASS_END(IPSCCPLegacyPass, "ipsccp",
  88. "Interprocedural Sparse Conditional Constant Propagation",
  89. false, false)
  90. // createIPSCCPPass - This is the public interface to this file.
  91. ModulePass *llvm::createIPSCCPPass() { return new IPSCCPLegacyPass(); }
  92. PreservedAnalyses FunctionSpecializationPass::run(Module &M,
  93. ModuleAnalysisManager &AM) {
  94. const DataLayout &DL = M.getDataLayout();
  95. auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  96. auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
  97. return FAM.getResult<TargetLibraryAnalysis>(F);
  98. };
  99. auto GetTTI = [&FAM](Function &F) -> TargetTransformInfo & {
  100. return FAM.getResult<TargetIRAnalysis>(F);
  101. };
  102. auto GetAC = [&FAM](Function &F) -> AssumptionCache & {
  103. return FAM.getResult<AssumptionAnalysis>(F);
  104. };
  105. auto GetAnalysis = [&FAM](Function &F) -> AnalysisResultsForFn {
  106. DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
  107. return {std::make_unique<PredicateInfo>(
  108. F, DT, FAM.getResult<AssumptionAnalysis>(F)),
  109. &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F)};
  110. };
  111. if (!runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis))
  112. return PreservedAnalyses::all();
  113. PreservedAnalyses PA;
  114. PA.preserve<DominatorTreeAnalysis>();
  115. PA.preserve<PostDominatorTreeAnalysis>();
  116. PA.preserve<FunctionAnalysisManagerModuleProxy>();
  117. return PA;
  118. }
  119. namespace {
  120. struct FunctionSpecializationLegacyPass : public ModulePass {
  121. static char ID; // Pass identification, replacement for typeid
  122. FunctionSpecializationLegacyPass() : ModulePass(ID) {}
  123. void getAnalysisUsage(AnalysisUsage &AU) const override {
  124. AU.addRequired<AssumptionCacheTracker>();
  125. AU.addRequired<DominatorTreeWrapperPass>();
  126. AU.addRequired<TargetLibraryInfoWrapperPass>();
  127. AU.addRequired<TargetTransformInfoWrapperPass>();
  128. }
  129. virtual bool runOnModule(Module &M) override {
  130. if (skipModule(M))
  131. return false;
  132. const DataLayout &DL = M.getDataLayout();
  133. auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
  134. return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
  135. };
  136. auto GetTTI = [this](Function &F) -> TargetTransformInfo & {
  137. return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
  138. };
  139. auto GetAC = [this](Function &F) -> AssumptionCache & {
  140. return this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
  141. };
  142. auto GetAnalysis = [this](Function &F) -> AnalysisResultsForFn {
  143. DominatorTree &DT =
  144. this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
  145. return {
  146. std::make_unique<PredicateInfo>(
  147. F, DT,
  148. this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
  149. F)),
  150. nullptr, // We cannot preserve the DT or PDT with the legacy pass
  151. nullptr}; // manager, so set them to nullptr.
  152. };
  153. return runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis);
  154. }
  155. };
  156. } // namespace
  157. char FunctionSpecializationLegacyPass::ID = 0;
  158. INITIALIZE_PASS_BEGIN(
  159. FunctionSpecializationLegacyPass, "function-specialization",
  160. "Propagate constant arguments by specializing the function", false, false)
  161. INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
  162. INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
  163. INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
  164. INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
  165. INITIALIZE_PASS_END(FunctionSpecializationLegacyPass, "function-specialization",
  166. "Propagate constant arguments by specializing the function",
  167. false, false)
  168. ModulePass *llvm::createFunctionSpecializationPass() {
  169. return new FunctionSpecializationLegacyPass();
  170. }