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 namespace { 139 struct FunctionSpecializationLegacyPass : public ModulePass { 140 static char ID; // Pass identification, replacement for typeid 141 FunctionSpecializationLegacyPass() : ModulePass(ID) {} 142 143 void getAnalysisUsage(AnalysisUsage &AU) const override { 144 AU.addRequired<AssumptionCacheTracker>(); 145 AU.addRequired<DominatorTreeWrapperPass>(); 146 AU.addRequired<TargetLibraryInfoWrapperPass>(); 147 AU.addRequired<TargetTransformInfoWrapperPass>(); 148 } 149 150 virtual bool runOnModule(Module &M) override { 151 if (skipModule(M)) 152 return false; 153 154 const DataLayout &DL = M.getDataLayout(); 155 auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { 156 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 157 }; 158 auto GetTTI = [this](Function &F) -> TargetTransformInfo & { 159 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); 160 }; 161 auto GetAC = [this](Function &F) -> AssumptionCache & { 162 return this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); 163 }; 164 165 auto GetAnalysis = [this](Function &F) -> AnalysisResultsForFn { 166 DominatorTree &DT = 167 this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); 168 return { 169 std::make_unique<PredicateInfo>( 170 F, DT, 171 this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache( 172 F)), 173 nullptr, // We cannot preserve the DT or PDT with the legacy pass 174 nullptr}; // manager, so set them to nullptr. 175 }; 176 return runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis); 177 } 178 }; 179 } // namespace 180 181 char FunctionSpecializationLegacyPass::ID = 0; 182 183 INITIALIZE_PASS_BEGIN( 184 FunctionSpecializationLegacyPass, "function-specialization", 185 "Propagate constant arguments by specializing the function", false, false) 186 187 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 188 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 189 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) 190 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 191 INITIALIZE_PASS_END(FunctionSpecializationLegacyPass, "function-specialization", 192 "Propagate constant arguments by specializing the function", 193 false, false) 194 195 ModulePass *llvm::createFunctionSpecializationPass() { 196 return new FunctionSpecializationLegacyPass(); 197 } 198