95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===- Parsing, selection, and construction of pass pipelines -------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 /// \file
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 ///
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 /// This file provides the implementation of the PassBuilder based on our
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 /// static pass registry as well as related functionality. It also provides
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 /// helpers to aid in analyzing, debugging, and testing passes and pass
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 /// pipelines.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 ///
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 #include "llvm/Passes/PassBuilder.h"
|
120
|
19 #include "llvm/ADT/StringSwitch.h"
|
|
20 #include "llvm/Analysis/AliasAnalysis.h"
|
|
21 #include "llvm/Analysis/AliasAnalysisEvaluator.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/Analysis/AssumptionCache.h"
|
120
|
23 #include "llvm/Analysis/BasicAliasAnalysis.h"
|
|
24 #include "llvm/Analysis/BlockFrequencyInfo.h"
|
|
25 #include "llvm/Analysis/BranchProbabilityInfo.h"
|
|
26 #include "llvm/Analysis/CFGPrinter.h"
|
|
27 #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
|
|
28 #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 #include "llvm/Analysis/CGSCCPassManager.h"
|
120
|
30 #include "llvm/Analysis/CallGraph.h"
|
|
31 #include "llvm/Analysis/DemandedBits.h"
|
|
32 #include "llvm/Analysis/DependenceAnalysis.h"
|
|
33 #include "llvm/Analysis/DominanceFrontier.h"
|
|
34 #include "llvm/Analysis/GlobalsModRef.h"
|
|
35 #include "llvm/Analysis/IVUsers.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 #include "llvm/Analysis/LazyCallGraph.h"
|
120
|
37 #include "llvm/Analysis/LazyValueInfo.h"
|
|
38 #include "llvm/Analysis/LoopAccessAnalysis.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39 #include "llvm/Analysis/LoopInfo.h"
|
120
|
40 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
121
|
41 #include "llvm/Analysis/MemorySSA.h"
|
120
|
42 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
|
121
|
43 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
120
|
44 #include "llvm/Analysis/PostDominators.h"
|
|
45 #include "llvm/Analysis/ProfileSummaryInfo.h"
|
|
46 #include "llvm/Analysis/RegionInfo.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 #include "llvm/Analysis/ScalarEvolution.h"
|
120
|
48 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
|
49 #include "llvm/Analysis/ScopedNoAliasAA.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50 #include "llvm/Analysis/TargetLibraryInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 #include "llvm/Analysis/TargetTransformInfo.h"
|
120
|
52 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
|
53 #include "llvm/CodeGen/PreISelIntrinsicLowering.h"
|
|
54 #include "llvm/CodeGen/UnreachableBlockElim.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 #include "llvm/IR/Dominators.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
56 #include "llvm/IR/IRPrintingPasses.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 #include "llvm/IR/PassManager.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58 #include "llvm/IR/Verifier.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59 #include "llvm/Support/Debug.h"
|
120
|
60 #include "llvm/Support/Regex.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 #include "llvm/Target/TargetMachine.h"
|
134
|
62 #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
|
120
|
63 #include "llvm/Transforms/GCOVProfiler.h"
|
|
64 #include "llvm/Transforms/IPO/AlwaysInliner.h"
|
121
|
65 #include "llvm/Transforms/IPO/ArgumentPromotion.h"
|
|
66 #include "llvm/Transforms/IPO/CalledValuePropagation.h"
|
120
|
67 #include "llvm/Transforms/IPO/ConstantMerge.h"
|
|
68 #include "llvm/Transforms/IPO/CrossDSOCFI.h"
|
|
69 #include "llvm/Transforms/IPO/DeadArgumentElimination.h"
|
|
70 #include "llvm/Transforms/IPO/ElimAvailExtern.h"
|
100
|
71 #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
|
120
|
72 #include "llvm/Transforms/IPO/FunctionAttrs.h"
|
|
73 #include "llvm/Transforms/IPO/FunctionImport.h"
|
|
74 #include "llvm/Transforms/IPO/GlobalDCE.h"
|
|
75 #include "llvm/Transforms/IPO/GlobalOpt.h"
|
|
76 #include "llvm/Transforms/IPO/GlobalSplit.h"
|
100
|
77 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
|
121
|
78 #include "llvm/Transforms/IPO/Inliner.h"
|
120
|
79 #include "llvm/Transforms/IPO/Internalize.h"
|
|
80 #include "llvm/Transforms/IPO/LowerTypeTests.h"
|
|
81 #include "llvm/Transforms/IPO/PartialInlining.h"
|
|
82 #include "llvm/Transforms/IPO/SCCP.h"
|
100
|
83 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
|
134
|
84 #include "llvm/Transforms/IPO/SyntheticCountsPropagation.h"
|
120
|
85 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 #include "llvm/Transforms/InstCombine/InstCombine.h"
|
120
|
87 #include "llvm/Transforms/InstrProfiling.h"
|
134
|
88 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
|
120
|
89 #include "llvm/Transforms/PGOInstrumentation.h"
|
|
90 #include "llvm/Transforms/SampleProfile.h"
|
100
|
91 #include "llvm/Transforms/Scalar/ADCE.h"
|
120
|
92 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
|
|
93 #include "llvm/Transforms/Scalar/BDCE.h"
|
134
|
94 #include "llvm/Transforms/Scalar/CallSiteSplitting.h"
|
120
|
95 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
|
|
96 #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
|
|
97 #include "llvm/Transforms/Scalar/DCE.h"
|
|
98 #include "llvm/Transforms/Scalar/DeadStoreElimination.h"
|
121
|
99 #include "llvm/Transforms/Scalar/DivRemPairs.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 #include "llvm/Transforms/Scalar/EarlyCSE.h"
|
120
|
101 #include "llvm/Transforms/Scalar/Float2Int.h"
|
|
102 #include "llvm/Transforms/Scalar/GVN.h"
|
|
103 #include "llvm/Transforms/Scalar/GuardWidening.h"
|
121
|
104 #include "llvm/Transforms/Scalar/IVUsersPrinter.h"
|
120
|
105 #include "llvm/Transforms/Scalar/IndVarSimplify.h"
|
|
106 #include "llvm/Transforms/Scalar/JumpThreading.h"
|
|
107 #include "llvm/Transforms/Scalar/LICM.h"
|
121
|
108 #include "llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h"
|
120
|
109 #include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
|
|
110 #include "llvm/Transforms/Scalar/LoopDeletion.h"
|
|
111 #include "llvm/Transforms/Scalar/LoopDistribute.h"
|
|
112 #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
|
|
113 #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
|
121
|
114 #include "llvm/Transforms/Scalar/LoopLoadElimination.h"
|
|
115 #include "llvm/Transforms/Scalar/LoopPassManager.h"
|
|
116 #include "llvm/Transforms/Scalar/LoopPredication.h"
|
120
|
117 #include "llvm/Transforms/Scalar/LoopRotation.h"
|
|
118 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
|
121
|
119 #include "llvm/Transforms/Scalar/LoopSink.h"
|
120
|
120 #include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
|
|
121 #include "llvm/Transforms/Scalar/LoopUnrollPass.h"
|
|
122 #include "llvm/Transforms/Scalar/LowerAtomic.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
|
120
|
124 #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
|
|
125 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
|
|
126 #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
|
|
127 #include "llvm/Transforms/Scalar/NaryReassociate.h"
|
121
|
128 #include "llvm/Transforms/Scalar/NewGVN.h"
|
120
|
129 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
|
|
130 #include "llvm/Transforms/Scalar/Reassociate.h"
|
134
|
131 #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
|
120
|
132 #include "llvm/Transforms/Scalar/SCCP.h"
|
100
|
133 #include "llvm/Transforms/Scalar/SROA.h"
|
121
|
134 #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
120
|
136 #include "llvm/Transforms/Scalar/Sink.h"
|
134
|
137 #include "llvm/Transforms/Scalar/SpeculateAroundPHIs.h"
|
120
|
138 #include "llvm/Transforms/Scalar/SpeculativeExecution.h"
|
|
139 #include "llvm/Transforms/Scalar/TailRecursionElimination.h"
|
|
140 #include "llvm/Transforms/Utils/AddDiscriminators.h"
|
|
141 #include "llvm/Transforms/Utils/BreakCriticalEdges.h"
|
134
|
142 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
|
120
|
143 #include "llvm/Transforms/Utils/LCSSA.h"
|
|
144 #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
|
|
145 #include "llvm/Transforms/Utils/LoopSimplify.h"
|
|
146 #include "llvm/Transforms/Utils/LowerInvoke.h"
|
|
147 #include "llvm/Transforms/Utils/Mem2Reg.h"
|
|
148 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
|
|
149 #include "llvm/Transforms/Utils/SimplifyInstructions.h"
|
|
150 #include "llvm/Transforms/Utils/SymbolRewriter.h"
|
|
151 #include "llvm/Transforms/Vectorize/LoopVectorize.h"
|
|
152 #include "llvm/Transforms/Vectorize/SLPVectorizer.h"
|
|
153
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155
|
121
|
156 static cl::opt<unsigned> MaxDevirtIterations("pm-max-devirt-iterations",
|
|
157 cl::ReallyHidden, cl::init(4));
|
|
158 static cl::opt<bool>
|
|
159 RunPartialInlining("enable-npm-partial-inlining", cl::init(false),
|
|
160 cl::Hidden, cl::ZeroOrMore,
|
|
161 cl::desc("Run Partial inlinining pass"));
|
|
162
|
|
163 static cl::opt<bool>
|
|
164 RunNewGVN("enable-npm-newgvn", cl::init(false),
|
|
165 cl::Hidden, cl::ZeroOrMore,
|
|
166 cl::desc("Run NewGVN instead of GVN"));
|
|
167
|
|
168 static cl::opt<bool> EnableEarlyCSEMemSSA(
|
|
169 "enable-npm-earlycse-memssa", cl::init(true), cl::Hidden,
|
|
170 cl::desc("Enable the EarlyCSE w/ MemorySSA pass for the new PM (default = on)"));
|
|
171
|
|
172 static cl::opt<bool> EnableGVNHoist(
|
|
173 "enable-npm-gvn-hoist", cl::init(false), cl::Hidden,
|
|
174 cl::desc("Enable the GVN hoisting pass for the new PM (default = off)"));
|
|
175
|
|
176 static cl::opt<bool> EnableGVNSink(
|
|
177 "enable-npm-gvn-sink", cl::init(false), cl::Hidden,
|
|
178 cl::desc("Enable the GVN hoisting pass for the new PM (default = off)"));
|
|
179
|
134
|
180 static cl::opt<bool> EnableSyntheticCounts(
|
|
181 "enable-npm-synthetic-counts", cl::init(false), cl::Hidden, cl::ZeroOrMore,
|
|
182 cl::desc("Run synthetic function entry count generation "
|
|
183 "pass"));
|
|
184
|
121
|
185 static Regex DefaultAliasRegex(
|
|
186 "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
|
|
187
|
|
188 static bool isOptimizingForSize(PassBuilder::OptimizationLevel Level) {
|
|
189 switch (Level) {
|
|
190 case PassBuilder::O0:
|
|
191 case PassBuilder::O1:
|
|
192 case PassBuilder::O2:
|
|
193 case PassBuilder::O3:
|
|
194 return false;
|
|
195
|
|
196 case PassBuilder::Os:
|
|
197 case PassBuilder::Oz:
|
|
198 return true;
|
|
199 }
|
|
200 llvm_unreachable("Invalid optimization level!");
|
|
201 }
|
120
|
202
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 namespace {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 /// \brief No-op module pass which does nothing.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 struct NoOpModulePass {
|
120
|
207 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
|
|
208 return PreservedAnalyses::all();
|
|
209 }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210 static StringRef name() { return "NoOpModulePass"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 /// \brief No-op module analysis.
|
120
|
214 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
|
|
215 friend AnalysisInfoMixin<NoOpModuleAnalysis>;
|
|
216 static AnalysisKey Key;
|
|
217
|
|
218 public:
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
219 struct Result {};
|
120
|
220 Result run(Module &, ModuleAnalysisManager &) { return Result(); }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 static StringRef name() { return "NoOpModuleAnalysis"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224 /// \brief No-op CGSCC pass which does nothing.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 struct NoOpCGSCCPass {
|
120
|
226 PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
|
|
227 LazyCallGraph &, CGSCCUpdateResult &UR) {
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 return PreservedAnalyses::all();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 static StringRef name() { return "NoOpCGSCCPass"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233 /// \brief No-op CGSCC analysis.
|
120
|
234 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
|
|
235 friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
|
|
236 static AnalysisKey Key;
|
|
237
|
|
238 public:
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 struct Result {};
|
120
|
240 Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
|
|
241 return Result();
|
|
242 }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 static StringRef name() { return "NoOpCGSCCAnalysis"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 /// \brief No-op function pass which does nothing.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 struct NoOpFunctionPass {
|
120
|
248 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
|
|
249 return PreservedAnalyses::all();
|
|
250 }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 static StringRef name() { return "NoOpFunctionPass"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 /// \brief No-op function analysis.
|
120
|
255 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
|
|
256 friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
|
|
257 static AnalysisKey Key;
|
|
258
|
|
259 public:
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
260 struct Result {};
|
120
|
261 Result run(Function &, FunctionAnalysisManager &) { return Result(); }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 static StringRef name() { return "NoOpFunctionAnalysis"; }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264
|
120
|
265 /// \brief No-op loop pass which does nothing.
|
|
266 struct NoOpLoopPass {
|
121
|
267 PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
|
|
268 LoopStandardAnalysisResults &, LPMUpdater &) {
|
120
|
269 return PreservedAnalyses::all();
|
|
270 }
|
|
271 static StringRef name() { return "NoOpLoopPass"; }
|
|
272 };
|
|
273
|
|
274 /// \brief No-op loop analysis.
|
|
275 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
|
|
276 friend AnalysisInfoMixin<NoOpLoopAnalysis>;
|
|
277 static AnalysisKey Key;
|
|
278
|
|
279 public:
|
|
280 struct Result {};
|
121
|
281 Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
|
|
282 return Result();
|
|
283 }
|
120
|
284 static StringRef name() { return "NoOpLoopAnalysis"; }
|
|
285 };
|
|
286
|
|
287 AnalysisKey NoOpModuleAnalysis::Key;
|
|
288 AnalysisKey NoOpCGSCCAnalysis::Key;
|
|
289 AnalysisKey NoOpFunctionAnalysis::Key;
|
|
290 AnalysisKey NoOpLoopAnalysis::Key;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 } // End anonymous namespace.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293
|
121
|
294 void PassBuilder::invokePeepholeEPCallbacks(
|
|
295 FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
|
|
296 for (auto &C : PeepholeEPCallbacks)
|
|
297 C(FPM, Level);
|
|
298 }
|
|
299
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
|
120
|
301 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
|
302 MAM.registerPass([&] { return CREATE_PASS; });
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 #include "PassRegistry.def"
|
121
|
304
|
|
305 for (auto &C : ModuleAnalysisRegistrationCallbacks)
|
|
306 C(MAM);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
307 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
308
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309 void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
|
120
|
310 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
|
311 CGAM.registerPass([&] { return CREATE_PASS; });
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
312 #include "PassRegistry.def"
|
121
|
313
|
|
314 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
|
|
315 C(CGAM);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
|
120
|
319 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
|
320 FAM.registerPass([&] { return CREATE_PASS; });
|
|
321 #include "PassRegistry.def"
|
121
|
322
|
|
323 for (auto &C : FunctionAnalysisRegistrationCallbacks)
|
|
324 C(FAM);
|
120
|
325 }
|
|
326
|
|
327 void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
|
|
328 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
|
329 LAM.registerPass([&] { return CREATE_PASS; });
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
330 #include "PassRegistry.def"
|
121
|
331
|
|
332 for (auto &C : LoopAnalysisRegistrationCallbacks)
|
|
333 C(LAM);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
334 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335
|
121
|
336 FunctionPassManager
|
|
337 PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
|
|
338 ThinLTOPhase Phase,
|
|
339 bool DebugLogging) {
|
|
340 assert(Level != O0 && "Must request optimizations!");
|
|
341 FunctionPassManager FPM(DebugLogging);
|
|
342
|
|
343 // Form SSA out of local memory accesses after breaking apart aggregates into
|
|
344 // scalars.
|
|
345 FPM.addPass(SROA());
|
|
346
|
|
347 // Catch trivial redundancies
|
|
348 FPM.addPass(EarlyCSEPass(EnableEarlyCSEMemSSA));
|
|
349
|
|
350 // Hoisting of scalars and load expressions.
|
|
351 if (EnableGVNHoist)
|
|
352 FPM.addPass(GVNHoistPass());
|
|
353
|
|
354 // Global value numbering based sinking.
|
|
355 if (EnableGVNSink) {
|
|
356 FPM.addPass(GVNSinkPass());
|
|
357 FPM.addPass(SimplifyCFGPass());
|
|
358 }
|
|
359
|
|
360 // Speculative execution if the target has divergent branches; otherwise nop.
|
|
361 FPM.addPass(SpeculativeExecutionPass());
|
|
362
|
|
363 // Optimize based on known information about branches, and cleanup afterward.
|
|
364 FPM.addPass(JumpThreadingPass());
|
|
365 FPM.addPass(CorrelatedValuePropagationPass());
|
|
366 FPM.addPass(SimplifyCFGPass());
|
134
|
367 if (Level == O3)
|
|
368 FPM.addPass(AggressiveInstCombinePass());
|
121
|
369 FPM.addPass(InstCombinePass());
|
|
370
|
|
371 if (!isOptimizingForSize(Level))
|
|
372 FPM.addPass(LibCallsShrinkWrapPass());
|
|
373
|
|
374 invokePeepholeEPCallbacks(FPM, Level);
|
|
375
|
|
376 // For PGO use pipeline, try to optimize memory intrinsics such as memcpy
|
|
377 // using the size value profile. Don't perform this when optimizing for size.
|
|
378 if (PGOOpt && !PGOOpt->ProfileUseFile.empty() &&
|
|
379 !isOptimizingForSize(Level))
|
|
380 FPM.addPass(PGOMemOPSizeOpt());
|
|
381
|
|
382 FPM.addPass(TailCallElimPass());
|
|
383 FPM.addPass(SimplifyCFGPass());
|
|
384
|
|
385 // Form canonically associated expression trees, and simplify the trees using
|
|
386 // basic mathematical properties. For example, this will form (nearly)
|
|
387 // minimal multiplication trees.
|
|
388 FPM.addPass(ReassociatePass());
|
|
389
|
|
390 // Add the primary loop simplification pipeline.
|
|
391 // FIXME: Currently this is split into two loop pass pipelines because we run
|
|
392 // some function passes in between them. These can and should be replaced by
|
|
393 // loop pass equivalenst but those aren't ready yet. Specifically,
|
|
394 // `SimplifyCFGPass` and `InstCombinePass` are used. We have
|
|
395 // `LoopSimplifyCFGPass` which isn't yet powerful enough, and the closest to
|
|
396 // the other we have is `LoopInstSimplify`.
|
|
397 LoopPassManager LPM1(DebugLogging), LPM2(DebugLogging);
|
|
398
|
|
399 // Rotate Loop - disable header duplication at -Oz
|
|
400 LPM1.addPass(LoopRotatePass(Level != Oz));
|
|
401 LPM1.addPass(LICMPass());
|
|
402 LPM1.addPass(SimpleLoopUnswitchPass());
|
|
403 LPM2.addPass(IndVarSimplifyPass());
|
|
404 LPM2.addPass(LoopIdiomRecognizePass());
|
|
405
|
|
406 for (auto &C : LateLoopOptimizationsEPCallbacks)
|
|
407 C(LPM2, Level);
|
|
408
|
|
409 LPM2.addPass(LoopDeletionPass());
|
|
410 // Do not enable unrolling in PreLinkThinLTO phase during sample PGO
|
|
411 // because it changes IR to makes profile annotation in back compile
|
|
412 // inaccurate.
|
|
413 if (Phase != ThinLTOPhase::PreLink ||
|
|
414 !PGOOpt || PGOOpt->SampleProfileFile.empty())
|
|
415 LPM2.addPass(LoopFullUnrollPass(Level));
|
|
416
|
|
417 for (auto &C : LoopOptimizerEndEPCallbacks)
|
|
418 C(LPM2, Level);
|
|
419
|
|
420 // We provide the opt remark emitter pass for LICM to use. We only need to do
|
|
421 // this once as it is immutable.
|
|
422 FPM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>());
|
134
|
423 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM1), DebugLogging));
|
121
|
424 FPM.addPass(SimplifyCFGPass());
|
|
425 FPM.addPass(InstCombinePass());
|
134
|
426 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM2), DebugLogging));
|
121
|
427
|
|
428 // Eliminate redundancies.
|
|
429 if (Level != O1) {
|
|
430 // These passes add substantial compile time so skip them at O1.
|
|
431 FPM.addPass(MergedLoadStoreMotionPass());
|
|
432 if (RunNewGVN)
|
|
433 FPM.addPass(NewGVNPass());
|
|
434 else
|
|
435 FPM.addPass(GVN());
|
|
436 }
|
|
437
|
|
438 // Specially optimize memory movement as it doesn't look like dataflow in SSA.
|
|
439 FPM.addPass(MemCpyOptPass());
|
|
440
|
|
441 // Sparse conditional constant propagation.
|
|
442 // FIXME: It isn't clear why we do this *after* loop passes rather than
|
|
443 // before...
|
|
444 FPM.addPass(SCCPPass());
|
|
445
|
|
446 // Delete dead bit computations (instcombine runs after to fold away the dead
|
|
447 // computations, and then ADCE will run later to exploit any new DCE
|
|
448 // opportunities that creates).
|
|
449 FPM.addPass(BDCEPass());
|
|
450
|
|
451 // Run instcombine after redundancy and dead bit elimination to exploit
|
|
452 // opportunities opened up by them.
|
|
453 FPM.addPass(InstCombinePass());
|
|
454 invokePeepholeEPCallbacks(FPM, Level);
|
|
455
|
|
456 // Re-consider control flow based optimizations after redundancy elimination,
|
|
457 // redo DCE, etc.
|
|
458 FPM.addPass(JumpThreadingPass());
|
|
459 FPM.addPass(CorrelatedValuePropagationPass());
|
|
460 FPM.addPass(DSEPass());
|
134
|
461 FPM.addPass(createFunctionToLoopPassAdaptor(LICMPass(), DebugLogging));
|
121
|
462
|
|
463 for (auto &C : ScalarOptimizerLateEPCallbacks)
|
|
464 C(FPM, Level);
|
|
465
|
|
466 // Finally, do an expensive DCE pass to catch all the dead code exposed by
|
|
467 // the simplifications and basic cleanup after all the simplifications.
|
|
468 FPM.addPass(ADCEPass());
|
|
469 FPM.addPass(SimplifyCFGPass());
|
|
470 FPM.addPass(InstCombinePass());
|
|
471 invokePeepholeEPCallbacks(FPM, Level);
|
|
472
|
|
473 return FPM;
|
|
474 }
|
|
475
|
|
476 void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
|
|
477 PassBuilder::OptimizationLevel Level,
|
|
478 bool RunProfileGen,
|
|
479 std::string ProfileGenFile,
|
|
480 std::string ProfileUseFile) {
|
|
481 // Generally running simplification passes and the inliner with an high
|
|
482 // threshold results in smaller executables, but there may be cases where
|
|
483 // the size grows, so let's be conservative here and skip this simplification
|
|
484 // at -Os/Oz.
|
|
485 if (!isOptimizingForSize(Level)) {
|
|
486 InlineParams IP;
|
|
487
|
|
488 // In the old pass manager, this is a cl::opt. Should still this be one?
|
|
489 IP.DefaultThreshold = 75;
|
|
490
|
|
491 // FIXME: The hint threshold has the same value used by the regular inliner.
|
|
492 // This should probably be lowered after performance testing.
|
|
493 // FIXME: this comment is cargo culted from the old pass manager, revisit).
|
|
494 IP.HintThreshold = 325;
|
|
495
|
|
496 CGSCCPassManager CGPipeline(DebugLogging);
|
|
497
|
|
498 CGPipeline.addPass(InlinerPass(IP));
|
|
499
|
|
500 FunctionPassManager FPM;
|
|
501 FPM.addPass(SROA());
|
|
502 FPM.addPass(EarlyCSEPass()); // Catch trivial redundancies.
|
|
503 FPM.addPass(SimplifyCFGPass()); // Merge & remove basic blocks.
|
|
504 FPM.addPass(InstCombinePass()); // Combine silly sequences.
|
|
505 invokePeepholeEPCallbacks(FPM, Level);
|
|
506
|
|
507 CGPipeline.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM)));
|
|
508
|
|
509 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPipeline)));
|
|
510 }
|
|
511
|
|
512 // Delete anything that is now dead to make sure that we don't instrument
|
|
513 // dead code. Instrumentation can end up keeping dead code around and
|
|
514 // dramatically increase code size.
|
|
515 MPM.addPass(GlobalDCEPass());
|
|
516
|
|
517 if (RunProfileGen) {
|
|
518 MPM.addPass(PGOInstrumentationGen());
|
|
519
|
|
520 FunctionPassManager FPM;
|
134
|
521 FPM.addPass(
|
|
522 createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging));
|
121
|
523 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
|
524
|
|
525 // Add the profile lowering pass.
|
|
526 InstrProfOptions Options;
|
|
527 if (!ProfileGenFile.empty())
|
|
528 Options.InstrProfileOutput = ProfileGenFile;
|
|
529 Options.DoCounterPromotion = true;
|
|
530 MPM.addPass(InstrProfiling(Options));
|
|
531 }
|
|
532
|
|
533 if (!ProfileUseFile.empty())
|
|
534 MPM.addPass(PGOInstrumentationUse(ProfileUseFile));
|
|
535 }
|
|
536
|
|
537 static InlineParams
|
|
538 getInlineParamsFromOptLevel(PassBuilder::OptimizationLevel Level) {
|
|
539 auto O3 = PassBuilder::O3;
|
|
540 unsigned OptLevel = Level > O3 ? 2 : Level;
|
|
541 unsigned SizeLevel = Level > O3 ? Level - O3 : 0;
|
|
542 return getInlineParams(OptLevel, SizeLevel);
|
|
543 }
|
|
544
|
|
545 ModulePassManager
|
|
546 PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
|
|
547 ThinLTOPhase Phase,
|
|
548 bool DebugLogging) {
|
|
549 ModulePassManager MPM(DebugLogging);
|
|
550
|
|
551 // Do basic inference of function attributes from known properties of system
|
|
552 // libraries and other oracles.
|
|
553 MPM.addPass(InferFunctionAttrsPass());
|
|
554
|
|
555 // Create an early function pass manager to cleanup the output of the
|
|
556 // frontend.
|
120
|
557 FunctionPassManager EarlyFPM(DebugLogging);
|
|
558 EarlyFPM.addPass(SimplifyCFGPass());
|
|
559 EarlyFPM.addPass(SROA());
|
|
560 EarlyFPM.addPass(EarlyCSEPass());
|
|
561 EarlyFPM.addPass(LowerExpectIntrinsicPass());
|
134
|
562 if (Level == O3)
|
|
563 EarlyFPM.addPass(CallSiteSplittingPass());
|
|
564
|
121
|
565 // In SamplePGO ThinLTO backend, we need instcombine before profile annotation
|
|
566 // to convert bitcast to direct calls so that they can be inlined during the
|
|
567 // profile annotation prepration step.
|
|
568 // More details about SamplePGO design can be found in:
|
|
569 // https://research.google.com/pubs/pub45290.html
|
|
570 // FIXME: revisit how SampleProfileLoad/Inliner/ICP is structured.
|
|
571 if (PGOOpt && !PGOOpt->SampleProfileFile.empty() &&
|
|
572 Phase == ThinLTOPhase::PostLink)
|
|
573 EarlyFPM.addPass(InstCombinePass());
|
|
574 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
|
120
|
575
|
121
|
576 if (PGOOpt && !PGOOpt->SampleProfileFile.empty()) {
|
|
577 // Annotate sample profile right after early FPM to ensure freshness of
|
|
578 // the debug info.
|
|
579 MPM.addPass(SampleProfileLoaderPass(PGOOpt->SampleProfileFile,
|
|
580 Phase == ThinLTOPhase::PreLink));
|
|
581 // Do not invoke ICP in the ThinLTOPrelink phase as it makes it hard
|
|
582 // for the profile annotation to be accurate in the ThinLTO backend.
|
|
583 if (Phase != ThinLTOPhase::PreLink)
|
|
584 // We perform early indirect call promotion here, before globalopt.
|
|
585 // This is important for the ThinLTO backend phase because otherwise
|
|
586 // imported available_externally functions look unreferenced and are
|
|
587 // removed.
|
|
588 MPM.addPass(PGOIndirectCallPromotion(Phase == ThinLTOPhase::PostLink,
|
|
589 true));
|
|
590 }
|
|
591
|
134
|
592 // Interprocedural constant propagation now that basic cleanup has occurred
|
121
|
593 // and prior to optimizing globals.
|
|
594 // FIXME: This position in the pipeline hasn't been carefully considered in
|
|
595 // years, it should be re-analyzed.
|
|
596 MPM.addPass(IPSCCPPass());
|
|
597
|
|
598 // Attach metadata to indirect call sites indicating the set of functions
|
|
599 // they may target at run-time. This should follow IPSCCP.
|
|
600 MPM.addPass(CalledValuePropagationPass());
|
|
601
|
|
602 // Optimize globals to try and fold them into constants.
|
|
603 MPM.addPass(GlobalOptPass());
|
|
604
|
|
605 // Promote any localized globals to SSA registers.
|
|
606 // FIXME: Should this instead by a run of SROA?
|
|
607 // FIXME: We should probably run instcombine and simplify-cfg afterward to
|
|
608 // delete control flows that are dead once globals have been folded to
|
|
609 // constants.
|
|
610 MPM.addPass(createModuleToFunctionPassAdaptor(PromotePass()));
|
|
611
|
|
612 // Remove any dead arguments exposed by cleanups and constand folding
|
|
613 // globals.
|
|
614 MPM.addPass(DeadArgumentEliminationPass());
|
|
615
|
|
616 // Create a small function pass pipeline to cleanup after all the global
|
|
617 // optimizations.
|
|
618 FunctionPassManager GlobalCleanupPM(DebugLogging);
|
|
619 GlobalCleanupPM.addPass(InstCombinePass());
|
|
620 invokePeepholeEPCallbacks(GlobalCleanupPM, Level);
|
|
621
|
|
622 GlobalCleanupPM.addPass(SimplifyCFGPass());
|
|
623 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM)));
|
|
624
|
|
625 // Add all the requested passes for instrumentation PGO, if requested.
|
|
626 if (PGOOpt && Phase != ThinLTOPhase::PostLink &&
|
|
627 (!PGOOpt->ProfileGenFile.empty() || !PGOOpt->ProfileUseFile.empty())) {
|
|
628 addPGOInstrPasses(MPM, DebugLogging, Level, PGOOpt->RunProfileGen,
|
|
629 PGOOpt->ProfileGenFile, PGOOpt->ProfileUseFile);
|
|
630 MPM.addPass(PGOIndirectCallPromotion(false, false));
|
|
631 }
|
|
632
|
134
|
633 // Synthesize function entry counts for non-PGO compilation.
|
|
634 if (EnableSyntheticCounts && !PGOOpt)
|
|
635 MPM.addPass(SyntheticCountsPropagation());
|
|
636
|
121
|
637 // Require the GlobalsAA analysis for the module so we can query it within
|
|
638 // the CGSCC pipeline.
|
|
639 MPM.addPass(RequireAnalysisPass<GlobalsAA, Module>());
|
|
640
|
|
641 // Require the ProfileSummaryAnalysis for the module so we can query it within
|
|
642 // the inliner pass.
|
|
643 MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
|
|
644
|
|
645 // Now begin the main postorder CGSCC pipeline.
|
|
646 // FIXME: The current CGSCC pipeline has its origins in the legacy pass
|
|
647 // manager and trying to emulate its precise behavior. Much of this doesn't
|
|
648 // make a lot of sense and we should revisit the core CGSCC structure.
|
|
649 CGSCCPassManager MainCGPipeline(DebugLogging);
|
|
650
|
|
651 // Note: historically, the PruneEH pass was run first to deduce nounwind and
|
|
652 // generally clean up exception handling overhead. It isn't clear this is
|
|
653 // valuable as the inliner doesn't currently care whether it is inlining an
|
|
654 // invoke or a call.
|
|
655
|
|
656 // Run the inliner first. The theory is that we are walking bottom-up and so
|
|
657 // the callees have already been fully optimized, and we want to inline them
|
|
658 // into the callers so that our optimizations can reflect that.
|
|
659 // For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO
|
|
660 // because it makes profile annotation in the backend inaccurate.
|
|
661 InlineParams IP = getInlineParamsFromOptLevel(Level);
|
|
662 if (Phase == ThinLTOPhase::PreLink &&
|
|
663 PGOOpt && !PGOOpt->SampleProfileFile.empty())
|
|
664 IP.HotCallSiteThreshold = 0;
|
|
665 MainCGPipeline.addPass(InlinerPass(IP));
|
|
666
|
|
667 // Now deduce any function attributes based in the current code.
|
|
668 MainCGPipeline.addPass(PostOrderFunctionAttrsPass());
|
|
669
|
|
670 // When at O3 add argument promotion to the pass pipeline.
|
|
671 // FIXME: It isn't at all clear why this should be limited to O3.
|
|
672 if (Level == O3)
|
|
673 MainCGPipeline.addPass(ArgumentPromotionPass());
|
|
674
|
|
675 // Lastly, add the core function simplification pipeline nested inside the
|
|
676 // CGSCC walk.
|
|
677 MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor(
|
|
678 buildFunctionSimplificationPipeline(Level, Phase, DebugLogging)));
|
|
679
|
|
680 for (auto &C : CGSCCOptimizerLateEPCallbacks)
|
|
681 C(MainCGPipeline, Level);
|
|
682
|
|
683 // We wrap the CGSCC pipeline in a devirtualization repeater. This will try
|
|
684 // to detect when we devirtualize indirect calls and iterate the SCC passes
|
|
685 // in that case to try and catch knock-on inlining or function attrs
|
|
686 // opportunities. Then we add it to the module pipeline by walking the SCCs
|
|
687 // in postorder (or bottom-up).
|
|
688 MPM.addPass(
|
|
689 createModuleToPostOrderCGSCCPassAdaptor(createDevirtSCCRepeatedPass(
|
|
690 std::move(MainCGPipeline), MaxDevirtIterations)));
|
|
691
|
|
692 return MPM;
|
|
693 }
|
|
694
|
|
695 ModulePassManager
|
|
696 PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
|
|
697 bool DebugLogging) {
|
|
698 ModulePassManager MPM(DebugLogging);
|
|
699
|
|
700 // Optimize globals now that the module is fully simplified.
|
|
701 MPM.addPass(GlobalOptPass());
|
|
702 MPM.addPass(GlobalDCEPass());
|
|
703
|
|
704 // Run partial inlining pass to partially inline functions that have
|
|
705 // large bodies.
|
|
706 if (RunPartialInlining)
|
|
707 MPM.addPass(PartialInlinerPass());
|
|
708
|
|
709 // Remove avail extern fns and globals definitions since we aren't compiling
|
|
710 // an object file for later LTO. For LTO we want to preserve these so they
|
|
711 // are eligible for inlining at link-time. Note if they are unreferenced they
|
|
712 // will be removed by GlobalDCE later, so this only impacts referenced
|
|
713 // available externally globals. Eventually they will be suppressed during
|
|
714 // codegen, but eliminating here enables more opportunity for GlobalDCE as it
|
|
715 // may make globals referenced by available external functions dead and saves
|
|
716 // running remaining passes on the eliminated functions.
|
|
717 MPM.addPass(EliminateAvailableExternallyPass());
|
|
718
|
|
719 // Do RPO function attribute inference across the module to forward-propagate
|
|
720 // attributes where applicable.
|
|
721 // FIXME: Is this really an optimization rather than a canonicalization?
|
|
722 MPM.addPass(ReversePostOrderFunctionAttrsPass());
|
|
723
|
|
724 // Re-require GloblasAA here prior to function passes. This is particularly
|
|
725 // useful as the above will have inlined, DCE'ed, and function-attr
|
|
726 // propagated everything. We should at this point have a reasonably minimal
|
|
727 // and richly annotated call graph. By computing aliasing and mod/ref
|
|
728 // information for all local globals here, the late loop passes and notably
|
|
729 // the vectorizer will be able to use them to help recognize vectorizable
|
|
730 // memory operations.
|
|
731 MPM.addPass(RequireAnalysisPass<GlobalsAA, Module>());
|
|
732
|
|
733 FunctionPassManager OptimizePM(DebugLogging);
|
|
734 OptimizePM.addPass(Float2IntPass());
|
|
735 // FIXME: We need to run some loop optimizations to re-rotate loops after
|
|
736 // simplify-cfg and others undo their rotation.
|
|
737
|
|
738 // Optimize the loop execution. These passes operate on entire loop nests
|
|
739 // rather than on each loop in an inside-out manner, and so they are actually
|
|
740 // function passes.
|
|
741
|
|
742 for (auto &C : VectorizerStartEPCallbacks)
|
|
743 C(OptimizePM, Level);
|
|
744
|
|
745 // First rotate loops that may have been un-rotated by prior passes.
|
134
|
746 OptimizePM.addPass(
|
|
747 createFunctionToLoopPassAdaptor(LoopRotatePass(), DebugLogging));
|
121
|
748
|
|
749 // Distribute loops to allow partial vectorization. I.e. isolate dependences
|
|
750 // into separate loop that would otherwise inhibit vectorization. This is
|
|
751 // currently only performed for loops marked with the metadata
|
|
752 // llvm.loop.distribute=true or when -enable-loop-distribute is specified.
|
|
753 OptimizePM.addPass(LoopDistributePass());
|
|
754
|
|
755 // Now run the core loop vectorizer.
|
|
756 OptimizePM.addPass(LoopVectorizePass());
|
|
757
|
|
758 // Eliminate loads by forwarding stores from the previous iteration to loads
|
|
759 // of the current iteration.
|
|
760 OptimizePM.addPass(LoopLoadEliminationPass());
|
|
761
|
|
762 // Cleanup after the loop optimization passes.
|
|
763 OptimizePM.addPass(InstCombinePass());
|
|
764
|
|
765 // Now that we've formed fast to execute loop structures, we do further
|
|
766 // optimizations. These are run afterward as they might block doing complex
|
|
767 // analyses and transforms such as what are needed for loop vectorization.
|
|
768
|
134
|
769 // Cleanup after loop vectorization, etc. Simplification passes like CVP and
|
|
770 // GVN, loop transforms, and others have already run, so it's now better to
|
|
771 // convert to more optimized IR using more aggressive simplify CFG options.
|
|
772 // The extra sinking transform can create larger basic blocks, so do this
|
|
773 // before SLP vectorization.
|
|
774 OptimizePM.addPass(SimplifyCFGPass(SimplifyCFGOptions().
|
|
775 forwardSwitchCondToPhi(true).
|
|
776 convertSwitchToLookupTable(true).
|
|
777 needCanonicalLoops(false).
|
|
778 sinkCommonInsts(true)));
|
|
779
|
121
|
780 // Optimize parallel scalar instruction chains into SIMD instructions.
|
|
781 OptimizePM.addPass(SLPVectorizerPass());
|
|
782
|
|
783 OptimizePM.addPass(InstCombinePass());
|
|
784
|
|
785 // Unroll small loops to hide loop backedge latency and saturate any parallel
|
|
786 // execution resources of an out-of-order processor. We also then need to
|
|
787 // clean up redundancies and loop invariant code.
|
|
788 // FIXME: It would be really good to use a loop-integrated instruction
|
|
789 // combiner for cleanup here so that the unrolling and LICM can be pipelined
|
|
790 // across the loop nests.
|
|
791 OptimizePM.addPass(LoopUnrollPass(Level));
|
|
792 OptimizePM.addPass(InstCombinePass());
|
|
793 OptimizePM.addPass(RequireAnalysisPass<OptimizationRemarkEmitterAnalysis, Function>());
|
134
|
794 OptimizePM.addPass(createFunctionToLoopPassAdaptor(LICMPass(), DebugLogging));
|
121
|
795
|
|
796 // Now that we've vectorized and unrolled loops, we may have more refined
|
|
797 // alignment information, try to re-derive it here.
|
|
798 OptimizePM.addPass(AlignmentFromAssumptionsPass());
|
|
799
|
|
800 // LoopSink pass sinks instructions hoisted by LICM, which serves as a
|
|
801 // canonicalization pass that enables other optimizations. As a result,
|
|
802 // LoopSink pass needs to be a very late IR pass to avoid undoing LICM
|
|
803 // result too early.
|
|
804 OptimizePM.addPass(LoopSinkPass());
|
|
805
|
|
806 // And finally clean up LCSSA form before generating code.
|
|
807 OptimizePM.addPass(InstSimplifierPass());
|
|
808
|
|
809 // This hoists/decomposes div/rem ops. It should run after other sink/hoist
|
|
810 // passes to avoid re-sinking, but before SimplifyCFG because it can allow
|
|
811 // flattening of blocks.
|
|
812 OptimizePM.addPass(DivRemPairsPass());
|
|
813
|
|
814 // LoopSink (and other loop passes since the last simplifyCFG) might have
|
|
815 // resulted in single-entry-single-exit or empty blocks. Clean up the CFG.
|
|
816 OptimizePM.addPass(SimplifyCFGPass());
|
|
817
|
134
|
818 // Optimize PHIs by speculating around them when profitable. Note that this
|
|
819 // pass needs to be run after any PRE or similar pass as it is essentially
|
|
820 // inserting redudnancies into the progrem. This even includes SimplifyCFG.
|
|
821 OptimizePM.addPass(SpeculateAroundPHIsPass());
|
|
822
|
121
|
823 // Add the core optimizing pipeline.
|
|
824 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM)));
|
|
825
|
|
826 // Now we need to do some global optimization transforms.
|
|
827 // FIXME: It would seem like these should come first in the optimization
|
|
828 // pipeline and maybe be the bottom of the canonicalization pipeline? Weird
|
|
829 // ordering here.
|
|
830 MPM.addPass(GlobalDCEPass());
|
|
831 MPM.addPass(ConstantMergePass());
|
|
832
|
|
833 return MPM;
|
|
834 }
|
|
835
|
|
836 ModulePassManager
|
|
837 PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
|
|
838 bool DebugLogging) {
|
|
839 assert(Level != O0 && "Must request optimizations for the default pipeline!");
|
|
840
|
|
841 ModulePassManager MPM(DebugLogging);
|
|
842
|
|
843 // Force any function attributes we want the rest of the pipeline to observe.
|
|
844 MPM.addPass(ForceFunctionAttrsPass());
|
|
845
|
134
|
846 // Apply module pipeline start EP callback.
|
|
847 for (auto &C : PipelineStartEPCallbacks)
|
|
848 C(MPM);
|
|
849
|
121
|
850 if (PGOOpt && PGOOpt->SamplePGOSupport)
|
|
851 MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
|
|
852
|
|
853 // Add the core simplification pipeline.
|
|
854 MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::None,
|
|
855 DebugLogging));
|
|
856
|
|
857 // Now add the optimization pipeline.
|
|
858 MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging));
|
|
859
|
|
860 return MPM;
|
120
|
861 }
|
|
862
|
121
|
863 ModulePassManager
|
|
864 PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level,
|
|
865 bool DebugLogging) {
|
|
866 assert(Level != O0 && "Must request optimizations for the default pipeline!");
|
|
867
|
|
868 ModulePassManager MPM(DebugLogging);
|
|
869
|
|
870 // Force any function attributes we want the rest of the pipeline to observe.
|
|
871 MPM.addPass(ForceFunctionAttrsPass());
|
|
872
|
|
873 if (PGOOpt && PGOOpt->SamplePGOSupport)
|
|
874 MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
|
|
875
|
134
|
876 // Apply module pipeline start EP callback.
|
|
877 for (auto &C : PipelineStartEPCallbacks)
|
|
878 C(MPM);
|
|
879
|
121
|
880 // If we are planning to perform ThinLTO later, we don't bloat the code with
|
|
881 // unrolling/vectorization/... now. Just simplify the module as much as we
|
|
882 // can.
|
|
883 MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::PreLink,
|
|
884 DebugLogging));
|
|
885
|
|
886 // Run partial inlining pass to partially inline functions that have
|
|
887 // large bodies.
|
|
888 // FIXME: It isn't clear whether this is really the right place to run this
|
|
889 // in ThinLTO. Because there is another canonicalization and simplification
|
|
890 // phase that will run after the thin link, running this here ends up with
|
|
891 // less information than will be available later and it may grow functions in
|
|
892 // ways that aren't beneficial.
|
|
893 if (RunPartialInlining)
|
|
894 MPM.addPass(PartialInlinerPass());
|
|
895
|
|
896 // Reduce the size of the IR as much as possible.
|
|
897 MPM.addPass(GlobalOptPass());
|
|
898
|
|
899 return MPM;
|
|
900 }
|
|
901
|
|
902 ModulePassManager
|
|
903 PassBuilder::buildThinLTODefaultPipeline(OptimizationLevel Level,
|
|
904 bool DebugLogging) {
|
|
905 // FIXME: The summary index is not hooked in the new pass manager yet.
|
|
906 // When it's going to be hooked, enable WholeProgramDevirt and LowerTypeTest
|
|
907 // here.
|
|
908
|
|
909 ModulePassManager MPM(DebugLogging);
|
|
910
|
|
911 // Force any function attributes we want the rest of the pipeline to observe.
|
|
912 MPM.addPass(ForceFunctionAttrsPass());
|
|
913
|
|
914 // During the ThinLTO backend phase we perform early indirect call promotion
|
|
915 // here, before globalopt. Otherwise imported available_externally functions
|
|
916 // look unreferenced and are removed.
|
|
917 // FIXME: move this into buildModuleSimplificationPipeline to merge the logic
|
|
918 // with SamplePGO.
|
|
919 if (!PGOOpt || PGOOpt->SampleProfileFile.empty())
|
|
920 MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */,
|
|
921 false /* SamplePGO */));
|
|
922
|
|
923 // Add the core simplification pipeline.
|
|
924 MPM.addPass(buildModuleSimplificationPipeline(Level, ThinLTOPhase::PostLink,
|
|
925 DebugLogging));
|
|
926
|
|
927 // Now add the optimization pipeline.
|
|
928 MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging));
|
|
929
|
|
930 return MPM;
|
|
931 }
|
|
932
|
|
933 ModulePassManager
|
|
934 PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level,
|
|
935 bool DebugLogging) {
|
|
936 assert(Level != O0 && "Must request optimizations for the default pipeline!");
|
120
|
937 // FIXME: We should use a customized pre-link pipeline!
|
121
|
938 return buildPerModuleDefaultPipeline(Level, DebugLogging);
|
120
|
939 }
|
|
940
|
121
|
941 ModulePassManager PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
|
|
942 bool DebugLogging) {
|
|
943 assert(Level != O0 && "Must request optimizations for the default pipeline!");
|
|
944 ModulePassManager MPM(DebugLogging);
|
|
945
|
|
946 // Remove unused virtual tables to improve the quality of code generated by
|
|
947 // whole-program devirtualization and bitset lowering.
|
|
948 MPM.addPass(GlobalDCEPass());
|
|
949
|
|
950 // Force any function attributes we want the rest of the pipeline to observe.
|
|
951 MPM.addPass(ForceFunctionAttrsPass());
|
|
952
|
|
953 // Do basic inference of function attributes from known properties of system
|
|
954 // libraries and other oracles.
|
|
955 MPM.addPass(InferFunctionAttrsPass());
|
|
956
|
|
957 if (Level > 1) {
|
134
|
958 FunctionPassManager EarlyFPM(DebugLogging);
|
|
959 EarlyFPM.addPass(CallSiteSplittingPass());
|
|
960 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
|
|
961
|
121
|
962 // Indirect call promotion. This should promote all the targets that are
|
|
963 // left by the earlier promotion pass that promotes intra-module targets.
|
|
964 // This two-step promotion is to save the compile time. For LTO, it should
|
|
965 // produce the same result as if we only do promotion here.
|
|
966 MPM.addPass(PGOIndirectCallPromotion(
|
|
967 true /* InLTO */, PGOOpt && !PGOOpt->SampleProfileFile.empty()));
|
|
968 // Propagate constants at call sites into the functions they call. This
|
|
969 // opens opportunities for globalopt (and inlining) by substituting function
|
|
970 // pointers passed as arguments to direct uses of functions.
|
|
971 MPM.addPass(IPSCCPPass());
|
|
972
|
|
973 // Attach metadata to indirect call sites indicating the set of functions
|
|
974 // they may target at run-time. This should follow IPSCCP.
|
|
975 MPM.addPass(CalledValuePropagationPass());
|
|
976 }
|
|
977
|
|
978 // Now deduce any function attributes based in the current code.
|
|
979 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
|
980 PostOrderFunctionAttrsPass()));
|
|
981
|
|
982 // Do RPO function attribute inference across the module to forward-propagate
|
|
983 // attributes where applicable.
|
|
984 // FIXME: Is this really an optimization rather than a canonicalization?
|
|
985 MPM.addPass(ReversePostOrderFunctionAttrsPass());
|
|
986
|
|
987 // Use inragne annotations on GEP indices to split globals where beneficial.
|
|
988 MPM.addPass(GlobalSplitPass());
|
|
989
|
|
990 // Run whole program optimization of virtual call when the list of callees
|
|
991 // is fixed.
|
|
992 MPM.addPass(WholeProgramDevirtPass());
|
|
993
|
|
994 // Stop here at -O1.
|
|
995 if (Level == 1)
|
|
996 return MPM;
|
|
997
|
|
998 // Optimize globals to try and fold them into constants.
|
|
999 MPM.addPass(GlobalOptPass());
|
|
1000
|
|
1001 // Promote any localized globals to SSA registers.
|
|
1002 MPM.addPass(createModuleToFunctionPassAdaptor(PromotePass()));
|
|
1003
|
|
1004 // Linking modules together can lead to duplicate global constant, only
|
|
1005 // keep one copy of each constant.
|
|
1006 MPM.addPass(ConstantMergePass());
|
|
1007
|
|
1008 // Remove unused arguments from functions.
|
|
1009 MPM.addPass(DeadArgumentEliminationPass());
|
|
1010
|
|
1011 // Reduce the code after globalopt and ipsccp. Both can open up significant
|
|
1012 // simplification opportunities, and both can propagate functions through
|
|
1013 // function pointers. When this happens, we often have to resolve varargs
|
|
1014 // calls, etc, so let instcombine do this.
|
|
1015 FunctionPassManager PeepholeFPM(DebugLogging);
|
134
|
1016 if (Level == O3)
|
|
1017 PeepholeFPM.addPass(AggressiveInstCombinePass());
|
121
|
1018 PeepholeFPM.addPass(InstCombinePass());
|
|
1019 invokePeepholeEPCallbacks(PeepholeFPM, Level);
|
|
1020
|
|
1021 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(PeepholeFPM)));
|
|
1022
|
|
1023 // Note: historically, the PruneEH pass was run first to deduce nounwind and
|
|
1024 // generally clean up exception handling overhead. It isn't clear this is
|
|
1025 // valuable as the inliner doesn't currently care whether it is inlining an
|
|
1026 // invoke or a call.
|
|
1027 // Run the inliner now.
|
|
1028 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
|
1029 InlinerPass(getInlineParamsFromOptLevel(Level))));
|
|
1030
|
|
1031 // Optimize globals again after we ran the inliner.
|
|
1032 MPM.addPass(GlobalOptPass());
|
|
1033
|
|
1034 // Garbage collect dead functions.
|
|
1035 // FIXME: Add ArgumentPromotion pass after once it's ported.
|
|
1036 MPM.addPass(GlobalDCEPass());
|
|
1037
|
|
1038 FunctionPassManager FPM(DebugLogging);
|
|
1039 // The IPO Passes may leave cruft around. Clean up after them.
|
|
1040 FPM.addPass(InstCombinePass());
|
|
1041 invokePeepholeEPCallbacks(FPM, Level);
|
|
1042
|
|
1043 FPM.addPass(JumpThreadingPass());
|
|
1044
|
|
1045 // Break up allocas
|
|
1046 FPM.addPass(SROA());
|
120
|
1047
|
121
|
1048 // Run a few AA driver optimizations here and now to cleanup the code.
|
|
1049 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
|
1050
|
|
1051 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
|
1052 PostOrderFunctionAttrsPass()));
|
|
1053 // FIXME: here we run IP alias analysis in the legacy PM.
|
|
1054
|
|
1055 FunctionPassManager MainFPM;
|
|
1056
|
|
1057 // FIXME: once we fix LoopPass Manager, add LICM here.
|
|
1058 // FIXME: once we provide support for enabling MLSM, add it here.
|
|
1059 // FIXME: once we provide support for enabling NewGVN, add it here.
|
|
1060 if (RunNewGVN)
|
|
1061 MainFPM.addPass(NewGVNPass());
|
|
1062 else
|
|
1063 MainFPM.addPass(GVN());
|
|
1064
|
|
1065 // Remove dead memcpy()'s.
|
|
1066 MainFPM.addPass(MemCpyOptPass());
|
|
1067
|
|
1068 // Nuke dead stores.
|
|
1069 MainFPM.addPass(DSEPass());
|
|
1070
|
|
1071 // FIXME: at this point, we run a bunch of loop passes:
|
|
1072 // indVarSimplify, loopDeletion, loopInterchange, loopUnrool,
|
|
1073 // loopVectorize. Enable them once the remaining issue with LPM
|
|
1074 // are sorted out.
|
|
1075
|
|
1076 MainFPM.addPass(InstCombinePass());
|
|
1077 MainFPM.addPass(SimplifyCFGPass());
|
|
1078 MainFPM.addPass(SCCPPass());
|
|
1079 MainFPM.addPass(InstCombinePass());
|
|
1080 MainFPM.addPass(BDCEPass());
|
|
1081
|
|
1082 // FIXME: We may want to run SLPVectorizer here.
|
|
1083 // After vectorization, assume intrinsics may tell us more
|
|
1084 // about pointer alignments.
|
|
1085 #if 0
|
|
1086 MainFPM.add(AlignmentFromAssumptionsPass());
|
|
1087 #endif
|
|
1088
|
|
1089 // FIXME: Conditionally run LoadCombine here, after it's ported
|
|
1090 // (in case we still have this pass, given its questionable usefulness).
|
|
1091
|
|
1092 MainFPM.addPass(InstCombinePass());
|
|
1093 invokePeepholeEPCallbacks(MainFPM, Level);
|
|
1094 MainFPM.addPass(JumpThreadingPass());
|
|
1095 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(MainFPM)));
|
|
1096
|
|
1097 // Create a function that performs CFI checks for cross-DSO calls with
|
|
1098 // targets in the current module.
|
|
1099 MPM.addPass(CrossDSOCFIPass());
|
|
1100
|
|
1101 // Lower type metadata and the type.test intrinsic. This pass supports
|
|
1102 // clang's control flow integrity mechanisms (-fsanitize=cfi*) and needs
|
|
1103 // to be run at link time if CFI is enabled. This pass does nothing if
|
|
1104 // CFI is disabled.
|
|
1105 // Enable once we add support for the summary in the new PM.
|
|
1106 #if 0
|
|
1107 MPM.addPass(LowerTypeTestsPass(Summary ? PassSummaryAction::Export :
|
|
1108 PassSummaryAction::None,
|
|
1109 Summary));
|
|
1110 #endif
|
|
1111
|
|
1112 // Add late LTO optimization passes.
|
|
1113 // Delete basic blocks, which optimization passes may have killed.
|
|
1114 MPM.addPass(createModuleToFunctionPassAdaptor(SimplifyCFGPass()));
|
|
1115
|
|
1116 // Drop bodies of available eternally objects to improve GlobalDCE.
|
|
1117 MPM.addPass(EliminateAvailableExternallyPass());
|
|
1118
|
|
1119 // Now that we have optimized the program, discard unreachable functions.
|
|
1120 MPM.addPass(GlobalDCEPass());
|
|
1121
|
|
1122 // FIXME: Enable MergeFuncs, conditionally, after ported, maybe.
|
|
1123 return MPM;
|
|
1124 }
|
|
1125
|
|
1126 AAManager PassBuilder::buildDefaultAAPipeline() {
|
|
1127 AAManager AA;
|
|
1128
|
|
1129 // The order in which these are registered determines their priority when
|
|
1130 // being queried.
|
|
1131
|
|
1132 // First we register the basic alias analysis that provides the majority of
|
|
1133 // per-function local AA logic. This is a stateless, on-demand local set of
|
|
1134 // AA techniques.
|
|
1135 AA.registerFunctionAnalysis<BasicAA>();
|
|
1136
|
|
1137 // Next we query fast, specialized alias analyses that wrap IR-embedded
|
|
1138 // information about aliasing.
|
|
1139 AA.registerFunctionAnalysis<ScopedNoAliasAA>();
|
|
1140 AA.registerFunctionAnalysis<TypeBasedAA>();
|
|
1141
|
|
1142 // Add support for querying global aliasing information when available.
|
|
1143 // Because the `AAManager` is a function analysis and `GlobalsAA` is a module
|
|
1144 // analysis, all that the `AAManager` can do is query for any *cached*
|
|
1145 // results from `GlobalsAA` through a readonly proxy.
|
|
1146 AA.registerModuleAnalysis<GlobalsAA>();
|
|
1147
|
|
1148 return AA;
|
120
|
1149 }
|
|
1150
|
|
1151 static Optional<int> parseRepeatPassName(StringRef Name) {
|
|
1152 if (!Name.consume_front("repeat<") || !Name.consume_back(">"))
|
|
1153 return None;
|
|
1154 int Count;
|
|
1155 if (Name.getAsInteger(0, Count) || Count <= 0)
|
|
1156 return None;
|
|
1157 return Count;
|
|
1158 }
|
|
1159
|
121
|
1160 static Optional<int> parseDevirtPassName(StringRef Name) {
|
|
1161 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
|
|
1162 return None;
|
|
1163 int Count;
|
|
1164 if (Name.getAsInteger(0, Count) || Count <= 0)
|
|
1165 return None;
|
|
1166 return Count;
|
|
1167 }
|
|
1168
|
|
1169 /// Tests whether a pass name starts with a valid prefix for a default pipeline
|
|
1170 /// alias.
|
|
1171 static bool startsWithDefaultPipelineAliasPrefix(StringRef Name) {
|
|
1172 return Name.startswith("default") || Name.startswith("thinlto") ||
|
|
1173 Name.startswith("lto");
|
|
1174 }
|
|
1175
|
|
1176 /// Tests whether registered callbacks will accept a given pass name.
|
|
1177 ///
|
|
1178 /// When parsing a pipeline text, the type of the outermost pipeline may be
|
|
1179 /// omitted, in which case the type is automatically determined from the first
|
|
1180 /// pass name in the text. This may be a name that is handled through one of the
|
|
1181 /// callbacks. We check this through the oridinary parsing callbacks by setting
|
|
1182 /// up a dummy PassManager in order to not force the client to also handle this
|
|
1183 /// type of query.
|
|
1184 template <typename PassManagerT, typename CallbacksT>
|
|
1185 static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
|
|
1186 if (!Callbacks.empty()) {
|
|
1187 PassManagerT DummyPM;
|
|
1188 for (auto &CB : Callbacks)
|
|
1189 if (CB(Name, DummyPM, {}))
|
|
1190 return true;
|
|
1191 }
|
|
1192 return false;
|
|
1193 }
|
|
1194
|
|
1195 template <typename CallbacksT>
|
|
1196 static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
|
120
|
1197 // Manually handle aliases for pre-configured pipeline fragments.
|
121
|
1198 if (startsWithDefaultPipelineAliasPrefix(Name))
|
120
|
1199 return DefaultAliasRegex.match(Name);
|
|
1200
|
|
1201 // Explicitly handle pass manager names.
|
|
1202 if (Name == "module")
|
|
1203 return true;
|
|
1204 if (Name == "cgscc")
|
|
1205 return true;
|
|
1206 if (Name == "function")
|
|
1207 return true;
|
|
1208
|
|
1209 // Explicitly handle custom-parsed pass names.
|
|
1210 if (parseRepeatPassName(Name))
|
|
1211 return true;
|
|
1212
|
|
1213 #define MODULE_PASS(NAME, CREATE_PASS) \
|
|
1214 if (Name == NAME) \
|
|
1215 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1216 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1217 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1218 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1219 #include "PassRegistry.def"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1220
|
121
|
1221 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1222 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1223
|
121
|
1224 template <typename CallbacksT>
|
|
1225 static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
|
120
|
1226 // Explicitly handle pass manager names.
|
|
1227 if (Name == "cgscc")
|
|
1228 return true;
|
|
1229 if (Name == "function")
|
|
1230 return true;
|
|
1231
|
|
1232 // Explicitly handle custom-parsed pass names.
|
|
1233 if (parseRepeatPassName(Name))
|
|
1234 return true;
|
121
|
1235 if (parseDevirtPassName(Name))
|
|
1236 return true;
|
120
|
1237
|
|
1238 #define CGSCC_PASS(NAME, CREATE_PASS) \
|
|
1239 if (Name == NAME) \
|
|
1240 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1241 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1242 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1243 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1244 #include "PassRegistry.def"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1245
|
121
|
1246 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1247 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1248
|
121
|
1249 template <typename CallbacksT>
|
|
1250 static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
|
120
|
1251 // Explicitly handle pass manager names.
|
|
1252 if (Name == "function")
|
|
1253 return true;
|
|
1254 if (Name == "loop")
|
|
1255 return true;
|
|
1256
|
|
1257 // Explicitly handle custom-parsed pass names.
|
|
1258 if (parseRepeatPassName(Name))
|
|
1259 return true;
|
|
1260
|
|
1261 #define FUNCTION_PASS(NAME, CREATE_PASS) \
|
|
1262 if (Name == NAME) \
|
|
1263 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1264 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1265 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1266 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1267 #include "PassRegistry.def"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1268
|
121
|
1269 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1270 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1271
|
121
|
1272 template <typename CallbacksT>
|
|
1273 static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks) {
|
120
|
1274 // Explicitly handle pass manager names.
|
|
1275 if (Name == "loop")
|
|
1276 return true;
|
|
1277
|
|
1278 // Explicitly handle custom-parsed pass names.
|
|
1279 if (parseRepeatPassName(Name))
|
|
1280 return true;
|
|
1281
|
|
1282 #define LOOP_PASS(NAME, CREATE_PASS) \
|
|
1283 if (Name == NAME) \
|
|
1284 return true;
|
|
1285 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
|
1286 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
|
1287 return true;
|
|
1288 #include "PassRegistry.def"
|
|
1289
|
121
|
1290 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
|
120
|
1291 }
|
|
1292
|
|
1293 Optional<std::vector<PassBuilder::PipelineElement>>
|
|
1294 PassBuilder::parsePipelineText(StringRef Text) {
|
|
1295 std::vector<PipelineElement> ResultPipeline;
|
|
1296
|
|
1297 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
|
|
1298 &ResultPipeline};
|
|
1299 for (;;) {
|
|
1300 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
|
|
1301 size_t Pos = Text.find_first_of(",()");
|
|
1302 Pipeline.push_back({Text.substr(0, Pos), {}});
|
|
1303
|
|
1304 // If we have a single terminating name, we're done.
|
|
1305 if (Pos == Text.npos)
|
|
1306 break;
|
|
1307
|
|
1308 char Sep = Text[Pos];
|
|
1309 Text = Text.substr(Pos + 1);
|
|
1310 if (Sep == ',')
|
|
1311 // Just a name ending in a comma, continue.
|
|
1312 continue;
|
|
1313
|
|
1314 if (Sep == '(') {
|
|
1315 // Push the inner pipeline onto the stack to continue processing.
|
|
1316 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
|
|
1317 continue;
|
|
1318 }
|
|
1319
|
|
1320 assert(Sep == ')' && "Bogus separator!");
|
|
1321 // When handling the close parenthesis, we greedily consume them to avoid
|
|
1322 // empty strings in the pipeline.
|
|
1323 do {
|
|
1324 // If we try to pop the outer pipeline we have unbalanced parentheses.
|
|
1325 if (PipelineStack.size() == 1)
|
|
1326 return None;
|
|
1327
|
|
1328 PipelineStack.pop_back();
|
|
1329 } while (Text.consume_front(")"));
|
|
1330
|
|
1331 // Check if we've finished parsing.
|
|
1332 if (Text.empty())
|
|
1333 break;
|
|
1334
|
|
1335 // Otherwise, the end of an inner pipeline always has to be followed by
|
|
1336 // a comma, and then we can continue.
|
|
1337 if (!Text.consume_front(","))
|
|
1338 return None;
|
|
1339 }
|
|
1340
|
|
1341 if (PipelineStack.size() > 1)
|
|
1342 // Unbalanced paretheses.
|
|
1343 return None;
|
|
1344
|
|
1345 assert(PipelineStack.back() == &ResultPipeline &&
|
|
1346 "Wrong pipeline at the bottom of the stack!");
|
|
1347 return {std::move(ResultPipeline)};
|
|
1348 }
|
|
1349
|
|
1350 bool PassBuilder::parseModulePass(ModulePassManager &MPM,
|
|
1351 const PipelineElement &E, bool VerifyEachPass,
|
|
1352 bool DebugLogging) {
|
|
1353 auto &Name = E.Name;
|
|
1354 auto &InnerPipeline = E.InnerPipeline;
|
|
1355
|
|
1356 // First handle complex passes like the pass managers which carry pipelines.
|
|
1357 if (!InnerPipeline.empty()) {
|
|
1358 if (Name == "module") {
|
|
1359 ModulePassManager NestedMPM(DebugLogging);
|
|
1360 if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,
|
|
1361 DebugLogging))
|
|
1362 return false;
|
|
1363 MPM.addPass(std::move(NestedMPM));
|
|
1364 return true;
|
|
1365 }
|
|
1366 if (Name == "cgscc") {
|
|
1367 CGSCCPassManager CGPM(DebugLogging);
|
|
1368 if (!parseCGSCCPassPipeline(CGPM, InnerPipeline, VerifyEachPass,
|
|
1369 DebugLogging))
|
|
1370 return false;
|
121
|
1371 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
|
120
|
1372 return true;
|
|
1373 }
|
|
1374 if (Name == "function") {
|
|
1375 FunctionPassManager FPM(DebugLogging);
|
|
1376 if (!parseFunctionPassPipeline(FPM, InnerPipeline, VerifyEachPass,
|
|
1377 DebugLogging))
|
|
1378 return false;
|
|
1379 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
|
1380 return true;
|
|
1381 }
|
|
1382 if (auto Count = parseRepeatPassName(Name)) {
|
|
1383 ModulePassManager NestedMPM(DebugLogging);
|
|
1384 if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,
|
|
1385 DebugLogging))
|
|
1386 return false;
|
|
1387 MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
|
|
1388 return true;
|
|
1389 }
|
121
|
1390
|
|
1391 for (auto &C : ModulePipelineParsingCallbacks)
|
|
1392 if (C(Name, MPM, InnerPipeline))
|
|
1393 return true;
|
|
1394
|
120
|
1395 // Normal passes can't have pipelines.
|
|
1396 return false;
|
|
1397 }
|
|
1398
|
|
1399 // Manually handle aliases for pre-configured pipeline fragments.
|
121
|
1400 if (startsWithDefaultPipelineAliasPrefix(Name)) {
|
120
|
1401 SmallVector<StringRef, 3> Matches;
|
|
1402 if (!DefaultAliasRegex.match(Name, &Matches))
|
|
1403 return false;
|
|
1404 assert(Matches.size() == 3 && "Must capture two matched strings!");
|
|
1405
|
|
1406 OptimizationLevel L = StringSwitch<OptimizationLevel>(Matches[2])
|
121
|
1407 .Case("O0", O0)
|
|
1408 .Case("O1", O1)
|
|
1409 .Case("O2", O2)
|
|
1410 .Case("O3", O3)
|
|
1411 .Case("Os", Os)
|
|
1412 .Case("Oz", Oz);
|
|
1413 if (L == O0)
|
|
1414 // At O0 we do nothing at all!
|
|
1415 return true;
|
120
|
1416
|
|
1417 if (Matches[1] == "default") {
|
121
|
1418 MPM.addPass(buildPerModuleDefaultPipeline(L, DebugLogging));
|
|
1419 } else if (Matches[1] == "thinlto-pre-link") {
|
|
1420 MPM.addPass(buildThinLTOPreLinkDefaultPipeline(L, DebugLogging));
|
|
1421 } else if (Matches[1] == "thinlto") {
|
|
1422 MPM.addPass(buildThinLTODefaultPipeline(L, DebugLogging));
|
120
|
1423 } else if (Matches[1] == "lto-pre-link") {
|
121
|
1424 MPM.addPass(buildLTOPreLinkDefaultPipeline(L, DebugLogging));
|
120
|
1425 } else {
|
|
1426 assert(Matches[1] == "lto" && "Not one of the matched options!");
|
121
|
1427 MPM.addPass(buildLTODefaultPipeline(L, DebugLogging));
|
120
|
1428 }
|
|
1429 return true;
|
|
1430 }
|
|
1431
|
|
1432 // Finally expand the basic registered passes from the .inc file.
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1433 #define MODULE_PASS(NAME, CREATE_PASS) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1434 if (Name == NAME) { \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1435 MPM.addPass(CREATE_PASS); \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1436 return true; \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1437 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1438 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1439 if (Name == "require<" NAME ">") { \
|
120
|
1440 MPM.addPass( \
|
|
1441 RequireAnalysisPass< \
|
|
1442 std::remove_reference<decltype(CREATE_PASS)>::type, Module>()); \
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1443 return true; \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1444 } \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1445 if (Name == "invalidate<" NAME ">") { \
|
120
|
1446 MPM.addPass(InvalidateAnalysisPass< \
|
|
1447 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1448 return true; \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1449 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1450 #include "PassRegistry.def"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1451
|
121
|
1452 for (auto &C : ModulePipelineParsingCallbacks)
|
|
1453 if (C(Name, MPM, InnerPipeline))
|
|
1454 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1455 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1456 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1457
|
120
|
1458 bool PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
|
|
1459 const PipelineElement &E, bool VerifyEachPass,
|
|
1460 bool DebugLogging) {
|
|
1461 auto &Name = E.Name;
|
|
1462 auto &InnerPipeline = E.InnerPipeline;
|
|
1463
|
|
1464 // First handle complex passes like the pass managers which carry pipelines.
|
|
1465 if (!InnerPipeline.empty()) {
|
|
1466 if (Name == "cgscc") {
|
|
1467 CGSCCPassManager NestedCGPM(DebugLogging);
|
|
1468 if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,
|
|
1469 DebugLogging))
|
|
1470 return false;
|
|
1471 // Add the nested pass manager with the appropriate adaptor.
|
|
1472 CGPM.addPass(std::move(NestedCGPM));
|
|
1473 return true;
|
|
1474 }
|
|
1475 if (Name == "function") {
|
|
1476 FunctionPassManager FPM(DebugLogging);
|
|
1477 if (!parseFunctionPassPipeline(FPM, InnerPipeline, VerifyEachPass,
|
|
1478 DebugLogging))
|
|
1479 return false;
|
|
1480 // Add the nested pass manager with the appropriate adaptor.
|
121
|
1481 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM)));
|
120
|
1482 return true;
|
|
1483 }
|
|
1484 if (auto Count = parseRepeatPassName(Name)) {
|
|
1485 CGSCCPassManager NestedCGPM(DebugLogging);
|
|
1486 if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,
|
|
1487 DebugLogging))
|
|
1488 return false;
|
|
1489 CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM)));
|
|
1490 return true;
|
|
1491 }
|
121
|
1492 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
|
|
1493 CGSCCPassManager NestedCGPM(DebugLogging);
|
|
1494 if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,
|
|
1495 DebugLogging))
|
|
1496 return false;
|
|
1497 CGPM.addPass(
|
|
1498 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
|
|
1499 return true;
|
|
1500 }
|
|
1501
|
|
1502 for (auto &C : CGSCCPipelineParsingCallbacks)
|
|
1503 if (C(Name, CGPM, InnerPipeline))
|
|
1504 return true;
|
|
1505
|
120
|
1506 // Normal passes can't have pipelines.
|
|
1507 return false;
|
|
1508 }
|
|
1509
|
121
|
1510 // Now expand the basic registered passes from the .inc file.
|
120
|
1511 #define CGSCC_PASS(NAME, CREATE_PASS) \
|
|
1512 if (Name == NAME) { \
|
|
1513 CGPM.addPass(CREATE_PASS); \
|
|
1514 return true; \
|
|
1515 }
|
|
1516 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
|
1517 if (Name == "require<" NAME ">") { \
|
|
1518 CGPM.addPass(RequireAnalysisPass< \
|
|
1519 std::remove_reference<decltype(CREATE_PASS)>::type, \
|
|
1520 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
|
|
1521 CGSCCUpdateResult &>()); \
|
|
1522 return true; \
|
|
1523 } \
|
|
1524 if (Name == "invalidate<" NAME ">") { \
|
|
1525 CGPM.addPass(InvalidateAnalysisPass< \
|
|
1526 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
|
1527 return true; \
|
|
1528 }
|
|
1529 #include "PassRegistry.def"
|
|
1530
|
121
|
1531 for (auto &C : CGSCCPipelineParsingCallbacks)
|
|
1532 if (C(Name, CGPM, InnerPipeline))
|
|
1533 return true;
|
120
|
1534 return false;
|
|
1535 }
|
|
1536
|
|
1537 bool PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
|
|
1538 const PipelineElement &E,
|
|
1539 bool VerifyEachPass, bool DebugLogging) {
|
|
1540 auto &Name = E.Name;
|
|
1541 auto &InnerPipeline = E.InnerPipeline;
|
|
1542
|
|
1543 // First handle complex passes like the pass managers which carry pipelines.
|
|
1544 if (!InnerPipeline.empty()) {
|
|
1545 if (Name == "function") {
|
|
1546 FunctionPassManager NestedFPM(DebugLogging);
|
|
1547 if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass,
|
|
1548 DebugLogging))
|
|
1549 return false;
|
|
1550 // Add the nested pass manager with the appropriate adaptor.
|
|
1551 FPM.addPass(std::move(NestedFPM));
|
|
1552 return true;
|
|
1553 }
|
|
1554 if (Name == "loop") {
|
|
1555 LoopPassManager LPM(DebugLogging);
|
|
1556 if (!parseLoopPassPipeline(LPM, InnerPipeline, VerifyEachPass,
|
|
1557 DebugLogging))
|
|
1558 return false;
|
|
1559 // Add the nested pass manager with the appropriate adaptor.
|
134
|
1560 FPM.addPass(
|
|
1561 createFunctionToLoopPassAdaptor(std::move(LPM), DebugLogging));
|
120
|
1562 return true;
|
|
1563 }
|
|
1564 if (auto Count = parseRepeatPassName(Name)) {
|
|
1565 FunctionPassManager NestedFPM(DebugLogging);
|
|
1566 if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass,
|
|
1567 DebugLogging))
|
|
1568 return false;
|
|
1569 FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM)));
|
|
1570 return true;
|
|
1571 }
|
121
|
1572
|
|
1573 for (auto &C : FunctionPipelineParsingCallbacks)
|
|
1574 if (C(Name, FPM, InnerPipeline))
|
|
1575 return true;
|
|
1576
|
120
|
1577 // Normal passes can't have pipelines.
|
|
1578 return false;
|
|
1579 }
|
|
1580
|
121
|
1581 // Now expand the basic registered passes from the .inc file.
|
120
|
1582 #define FUNCTION_PASS(NAME, CREATE_PASS) \
|
|
1583 if (Name == NAME) { \
|
|
1584 FPM.addPass(CREATE_PASS); \
|
|
1585 return true; \
|
|
1586 }
|
|
1587 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
|
1588 if (Name == "require<" NAME ">") { \
|
|
1589 FPM.addPass( \
|
|
1590 RequireAnalysisPass< \
|
|
1591 std::remove_reference<decltype(CREATE_PASS)>::type, Function>()); \
|
|
1592 return true; \
|
|
1593 } \
|
|
1594 if (Name == "invalidate<" NAME ">") { \
|
|
1595 FPM.addPass(InvalidateAnalysisPass< \
|
|
1596 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
|
1597 return true; \
|
|
1598 }
|
|
1599 #include "PassRegistry.def"
|
|
1600
|
121
|
1601 for (auto &C : FunctionPipelineParsingCallbacks)
|
|
1602 if (C(Name, FPM, InnerPipeline))
|
|
1603 return true;
|
120
|
1604 return false;
|
|
1605 }
|
|
1606
|
|
1607 bool PassBuilder::parseLoopPass(LoopPassManager &LPM, const PipelineElement &E,
|
|
1608 bool VerifyEachPass, bool DebugLogging) {
|
|
1609 StringRef Name = E.Name;
|
|
1610 auto &InnerPipeline = E.InnerPipeline;
|
|
1611
|
|
1612 // First handle complex passes like the pass managers which carry pipelines.
|
|
1613 if (!InnerPipeline.empty()) {
|
|
1614 if (Name == "loop") {
|
|
1615 LoopPassManager NestedLPM(DebugLogging);
|
|
1616 if (!parseLoopPassPipeline(NestedLPM, InnerPipeline, VerifyEachPass,
|
|
1617 DebugLogging))
|
|
1618 return false;
|
|
1619 // Add the nested pass manager with the appropriate adaptor.
|
|
1620 LPM.addPass(std::move(NestedLPM));
|
|
1621 return true;
|
|
1622 }
|
|
1623 if (auto Count = parseRepeatPassName(Name)) {
|
|
1624 LoopPassManager NestedLPM(DebugLogging);
|
|
1625 if (!parseLoopPassPipeline(NestedLPM, InnerPipeline, VerifyEachPass,
|
|
1626 DebugLogging))
|
|
1627 return false;
|
|
1628 LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM)));
|
|
1629 return true;
|
|
1630 }
|
121
|
1631
|
|
1632 for (auto &C : LoopPipelineParsingCallbacks)
|
|
1633 if (C(Name, LPM, InnerPipeline))
|
|
1634 return true;
|
|
1635
|
120
|
1636 // Normal passes can't have pipelines.
|
|
1637 return false;
|
|
1638 }
|
|
1639
|
121
|
1640 // Now expand the basic registered passes from the .inc file.
|
120
|
1641 #define LOOP_PASS(NAME, CREATE_PASS) \
|
|
1642 if (Name == NAME) { \
|
|
1643 LPM.addPass(CREATE_PASS); \
|
|
1644 return true; \
|
|
1645 }
|
|
1646 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
|
1647 if (Name == "require<" NAME ">") { \
|
|
1648 LPM.addPass(RequireAnalysisPass< \
|
121
|
1649 std::remove_reference<decltype(CREATE_PASS)>::type, Loop, \
|
|
1650 LoopAnalysisManager, LoopStandardAnalysisResults &, \
|
|
1651 LPMUpdater &>()); \
|
120
|
1652 return true; \
|
|
1653 } \
|
|
1654 if (Name == "invalidate<" NAME ">") { \
|
|
1655 LPM.addPass(InvalidateAnalysisPass< \
|
|
1656 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
|
1657 return true; \
|
|
1658 }
|
|
1659 #include "PassRegistry.def"
|
|
1660
|
121
|
1661 for (auto &C : LoopPipelineParsingCallbacks)
|
|
1662 if (C(Name, LPM, InnerPipeline))
|
|
1663 return true;
|
120
|
1664 return false;
|
|
1665 }
|
|
1666
|
|
1667 bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
|
|
1668 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
|
|
1669 if (Name == NAME) { \
|
|
1670 AA.registerModuleAnalysis< \
|
|
1671 std::remove_reference<decltype(CREATE_PASS)>::type>(); \
|
|
1672 return true; \
|
|
1673 }
|
|
1674 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
|
|
1675 if (Name == NAME) { \
|
|
1676 AA.registerFunctionAnalysis< \
|
|
1677 std::remove_reference<decltype(CREATE_PASS)>::type>(); \
|
|
1678 return true; \
|
|
1679 }
|
|
1680 #include "PassRegistry.def"
|
|
1681
|
121
|
1682 for (auto &C : AAParsingCallbacks)
|
|
1683 if (C(Name, AA))
|
|
1684 return true;
|
120
|
1685 return false;
|
|
1686 }
|
|
1687
|
|
1688 bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
|
|
1689 ArrayRef<PipelineElement> Pipeline,
|
|
1690 bool VerifyEachPass,
|
|
1691 bool DebugLogging) {
|
|
1692 for (const auto &Element : Pipeline) {
|
|
1693 if (!parseLoopPass(LPM, Element, VerifyEachPass, DebugLogging))
|
|
1694 return false;
|
|
1695 // FIXME: No verifier support for Loop passes!
|
|
1696 }
|
|
1697 return true;
|
|
1698 }
|
|
1699
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1700 bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
|
120
|
1701 ArrayRef<PipelineElement> Pipeline,
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1702 bool VerifyEachPass,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1703 bool DebugLogging) {
|
120
|
1704 for (const auto &Element : Pipeline) {
|
|
1705 if (!parseFunctionPass(FPM, Element, VerifyEachPass, DebugLogging))
|
|
1706 return false;
|
|
1707 if (VerifyEachPass)
|
|
1708 FPM.addPass(VerifierPass());
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1709 }
|
120
|
1710 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1711 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1712
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1713 bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
|
120
|
1714 ArrayRef<PipelineElement> Pipeline,
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1715 bool VerifyEachPass,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1716 bool DebugLogging) {
|
120
|
1717 for (const auto &Element : Pipeline) {
|
|
1718 if (!parseCGSCCPass(CGPM, Element, VerifyEachPass, DebugLogging))
|
|
1719 return false;
|
|
1720 // FIXME: No verifier support for CGSCC passes!
|
|
1721 }
|
|
1722 return true;
|
|
1723 }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1724
|
120
|
1725 void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM,
|
|
1726 FunctionAnalysisManager &FAM,
|
|
1727 CGSCCAnalysisManager &CGAM,
|
|
1728 ModuleAnalysisManager &MAM) {
|
|
1729 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
|
|
1730 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
|
|
1731 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
|
|
1732 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
|
|
1733 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
|
|
1734 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
|
|
1735 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1736 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1737
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1738 bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
|
120
|
1739 ArrayRef<PipelineElement> Pipeline,
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1740 bool VerifyEachPass,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1741 bool DebugLogging) {
|
120
|
1742 for (const auto &Element : Pipeline) {
|
|
1743 if (!parseModulePass(MPM, Element, VerifyEachPass, DebugLogging))
|
|
1744 return false;
|
|
1745 if (VerifyEachPass)
|
|
1746 MPM.addPass(VerifierPass());
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1747 }
|
120
|
1748 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1749 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1750
|
121
|
1751 // Primary pass pipeline description parsing routine for a \c ModulePassManager
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1752 // FIXME: Should this routine accept a TargetMachine or require the caller to
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1753 // pre-populate the analysis managers with target-specific stuff?
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1754 bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1755 StringRef PipelineText, bool VerifyEachPass,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1756 bool DebugLogging) {
|
120
|
1757 auto Pipeline = parsePipelineText(PipelineText);
|
|
1758 if (!Pipeline || Pipeline->empty())
|
|
1759 return false;
|
|
1760
|
|
1761 // If the first name isn't at the module layer, wrap the pipeline up
|
|
1762 // automatically.
|
|
1763 StringRef FirstName = Pipeline->front().Name;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1764
|
121
|
1765 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
|
|
1766 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
|
120
|
1767 Pipeline = {{"cgscc", std::move(*Pipeline)}};
|
121
|
1768 } else if (isFunctionPassName(FirstName,
|
|
1769 FunctionPipelineParsingCallbacks)) {
|
120
|
1770 Pipeline = {{"function", std::move(*Pipeline)}};
|
121
|
1771 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks)) {
|
120
|
1772 Pipeline = {{"function", {{"loop", std::move(*Pipeline)}}}};
|
121
|
1773 } else {
|
|
1774 for (auto &C : TopLevelPipelineParsingCallbacks)
|
|
1775 if (C(MPM, *Pipeline, VerifyEachPass, DebugLogging))
|
|
1776 return true;
|
|
1777
|
120
|
1778 // Unknown pass name!
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1779 return false;
|
121
|
1780 }
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1781 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1782
|
120
|
1783 return parseModulePassPipeline(MPM, *Pipeline, VerifyEachPass, DebugLogging);
|
|
1784 }
|
|
1785
|
121
|
1786 // Primary pass pipeline description parsing routine for a \c CGSCCPassManager
|
|
1787 bool PassBuilder::parsePassPipeline(CGSCCPassManager &CGPM,
|
|
1788 StringRef PipelineText, bool VerifyEachPass,
|
|
1789 bool DebugLogging) {
|
|
1790 auto Pipeline = parsePipelineText(PipelineText);
|
|
1791 if (!Pipeline || Pipeline->empty())
|
|
1792 return false;
|
|
1793
|
|
1794 StringRef FirstName = Pipeline->front().Name;
|
|
1795 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
|
|
1796 return false;
|
|
1797
|
|
1798 return parseCGSCCPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging);
|
|
1799 }
|
|
1800
|
|
1801 // Primary pass pipeline description parsing routine for a \c
|
|
1802 // FunctionPassManager
|
|
1803 bool PassBuilder::parsePassPipeline(FunctionPassManager &FPM,
|
|
1804 StringRef PipelineText, bool VerifyEachPass,
|
|
1805 bool DebugLogging) {
|
|
1806 auto Pipeline = parsePipelineText(PipelineText);
|
|
1807 if (!Pipeline || Pipeline->empty())
|
|
1808 return false;
|
|
1809
|
|
1810 StringRef FirstName = Pipeline->front().Name;
|
|
1811 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
|
|
1812 return false;
|
|
1813
|
|
1814 return parseFunctionPassPipeline(FPM, *Pipeline, VerifyEachPass,
|
|
1815 DebugLogging);
|
|
1816 }
|
|
1817
|
|
1818 // Primary pass pipeline description parsing routine for a \c LoopPassManager
|
|
1819 bool PassBuilder::parsePassPipeline(LoopPassManager &CGPM,
|
|
1820 StringRef PipelineText, bool VerifyEachPass,
|
|
1821 bool DebugLogging) {
|
|
1822 auto Pipeline = parsePipelineText(PipelineText);
|
|
1823 if (!Pipeline || Pipeline->empty())
|
|
1824 return false;
|
|
1825
|
|
1826 return parseLoopPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging);
|
|
1827 }
|
|
1828
|
120
|
1829 bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
|
121
|
1830 // If the pipeline just consists of the word 'default' just replace the AA
|
|
1831 // manager with our default one.
|
|
1832 if (PipelineText == "default") {
|
|
1833 AA = buildDefaultAAPipeline();
|
|
1834 return true;
|
|
1835 }
|
|
1836
|
120
|
1837 while (!PipelineText.empty()) {
|
|
1838 StringRef Name;
|
|
1839 std::tie(Name, PipelineText) = PipelineText.split(',');
|
|
1840 if (!parseAAPassName(AA, Name))
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1841 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1842 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1843
|
120
|
1844 return true;
|
95
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1845 }
|