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