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