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