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