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
run(Module & M,ModuleAnalysisManager & AM)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
IPSCCPLegacyPass()59 IPSCCPLegacyPass() : ModulePass(ID) {
60 initializeIPSCCPLegacyPassPass(*PassRegistry::getPassRegistry());
61 }
62
runOnModule(Module & M)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
getAnalysisUsage(AnalysisUsage & AU) const85 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)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)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
run(Module & M,ModuleAnalysisManager & AM)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
FunctionSpecializationLegacyPass__anon0b6597be0a11::FunctionSpecializationLegacyPass142 FunctionSpecializationLegacyPass() : ModulePass(ID) {}
143
getAnalysisUsage__anon0b6597be0a11::FunctionSpecializationLegacyPass144 void getAnalysisUsage(AnalysisUsage &AU) const override {
145 AU.addRequired<AssumptionCacheTracker>();
146 AU.addRequired<DominatorTreeWrapperPass>();
147 AU.addRequired<TargetLibraryInfoWrapperPass>();
148 AU.addRequired<TargetTransformInfoWrapperPass>();
149 }
150
runOnModule__anon0b6597be0a11::FunctionSpecializationLegacyPass151 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
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)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