xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/IPO/SCCP.cpp (revision 370e009188ba90c3290b1479aa06ec98b66e140a)
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