1 //===- Parsing and selection of pass pipelines ----------------------------===//
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 /// \file
9 ///
10 /// This file provides the implementation of the PassBuilder based on our
11 /// static pass registry as well as related functionality. It also provides
12 /// helpers to aid in analyzing, debugging, and testing passes and pass
13 /// pipelines.
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/Passes/PassBuilder.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Analysis/AliasAnalysisEvaluator.h"
20 #include "llvm/Analysis/AliasSetTracker.h"
21 #include "llvm/Analysis/AssumptionCache.h"
22 #include "llvm/Analysis/BasicAliasAnalysis.h"
23 #include "llvm/Analysis/BlockFrequencyInfo.h"
24 #include "llvm/Analysis/BranchProbabilityInfo.h"
25 #include "llvm/Analysis/CFGPrinter.h"
26 #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
27 #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
28 #include "llvm/Analysis/CGSCCPassManager.h"
29 #include "llvm/Analysis/CallGraph.h"
30 #include "llvm/Analysis/CallPrinter.h"
31 #include "llvm/Analysis/CostModel.h"
32 #include "llvm/Analysis/CycleAnalysis.h"
33 #include "llvm/Analysis/DDG.h"
34 #include "llvm/Analysis/DDGPrinter.h"
35 #include "llvm/Analysis/Delinearization.h"
36 #include "llvm/Analysis/DemandedBits.h"
37 #include "llvm/Analysis/DependenceAnalysis.h"
38 #include "llvm/Analysis/DivergenceAnalysis.h"
39 #include "llvm/Analysis/DomPrinter.h"
40 #include "llvm/Analysis/DominanceFrontier.h"
41 #include "llvm/Analysis/FunctionPropertiesAnalysis.h"
42 #include "llvm/Analysis/GlobalsModRef.h"
43 #include "llvm/Analysis/IRSimilarityIdentifier.h"
44 #include "llvm/Analysis/IVUsers.h"
45 #include "llvm/Analysis/InlineAdvisor.h"
46 #include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
47 #include "llvm/Analysis/InstCount.h"
48 #include "llvm/Analysis/LazyCallGraph.h"
49 #include "llvm/Analysis/LazyValueInfo.h"
50 #include "llvm/Analysis/Lint.h"
51 #include "llvm/Analysis/LoopAccessAnalysis.h"
52 #include "llvm/Analysis/LoopCacheAnalysis.h"
53 #include "llvm/Analysis/LoopInfo.h"
54 #include "llvm/Analysis/LoopNestAnalysis.h"
55 #include "llvm/Analysis/MemDerefPrinter.h"
56 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
57 #include "llvm/Analysis/MemorySSA.h"
58 #include "llvm/Analysis/ModuleDebugInfoPrinter.h"
59 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
60 #include "llvm/Analysis/MustExecute.h"
61 #include "llvm/Analysis/ObjCARCAliasAnalysis.h"
62 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
63 #include "llvm/Analysis/PhiValues.h"
64 #include "llvm/Analysis/PostDominators.h"
65 #include "llvm/Analysis/ProfileSummaryInfo.h"
66 #include "llvm/Analysis/RegionInfo.h"
67 #include "llvm/Analysis/ScalarEvolution.h"
68 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
69 #include "llvm/Analysis/ScopedNoAliasAA.h"
70 #include "llvm/Analysis/StackLifetime.h"
71 #include "llvm/Analysis/StackSafetyAnalysis.h"
72 #include "llvm/Analysis/TargetLibraryInfo.h"
73 #include "llvm/Analysis/TargetTransformInfo.h"
74 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
75 #include "llvm/IR/Dominators.h"
76 #include "llvm/IR/IRPrintingPasses.h"
77 #include "llvm/IR/PassManager.h"
78 #include "llvm/IR/PrintPasses.h"
79 #include "llvm/IR/SafepointIRVerifier.h"
80 #include "llvm/IR/Verifier.h"
81 #include "llvm/Support/CommandLine.h"
82 #include "llvm/Support/Debug.h"
83 #include "llvm/Support/ErrorHandling.h"
84 #include "llvm/Support/FormatVariadic.h"
85 #include "llvm/Support/Regex.h"
86 #include "llvm/Target/TargetMachine.h"
87 #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
88 #include "llvm/Transforms/Coroutines/CoroCleanup.h"
89 #include "llvm/Transforms/Coroutines/CoroEarly.h"
90 #include "llvm/Transforms/Coroutines/CoroElide.h"
91 #include "llvm/Transforms/Coroutines/CoroSplit.h"
92 #include "llvm/Transforms/IPO/AlwaysInliner.h"
93 #include "llvm/Transforms/IPO/Annotation2Metadata.h"
94 #include "llvm/Transforms/IPO/ArgumentPromotion.h"
95 #include "llvm/Transforms/IPO/Attributor.h"
96 #include "llvm/Transforms/IPO/BlockExtractor.h"
97 #include "llvm/Transforms/IPO/CalledValuePropagation.h"
98 #include "llvm/Transforms/IPO/ConstantMerge.h"
99 #include "llvm/Transforms/IPO/CrossDSOCFI.h"
100 #include "llvm/Transforms/IPO/DeadArgumentElimination.h"
101 #include "llvm/Transforms/IPO/ElimAvailExtern.h"
102 #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
103 #include "llvm/Transforms/IPO/FunctionAttrs.h"
104 #include "llvm/Transforms/IPO/FunctionImport.h"
105 #include "llvm/Transforms/IPO/GlobalDCE.h"
106 #include "llvm/Transforms/IPO/GlobalOpt.h"
107 #include "llvm/Transforms/IPO/GlobalSplit.h"
108 #include "llvm/Transforms/IPO/HotColdSplitting.h"
109 #include "llvm/Transforms/IPO/IROutliner.h"
110 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
111 #include "llvm/Transforms/IPO/Inliner.h"
112 #include "llvm/Transforms/IPO/Internalize.h"
113 #include "llvm/Transforms/IPO/LoopExtractor.h"
114 #include "llvm/Transforms/IPO/LowerTypeTests.h"
115 #include "llvm/Transforms/IPO/MergeFunctions.h"
116 #include "llvm/Transforms/IPO/ModuleInliner.h"
117 #include "llvm/Transforms/IPO/OpenMPOpt.h"
118 #include "llvm/Transforms/IPO/PartialInlining.h"
119 #include "llvm/Transforms/IPO/SCCP.h"
120 #include "llvm/Transforms/IPO/SampleProfile.h"
121 #include "llvm/Transforms/IPO/SampleProfileProbe.h"
122 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
123 #include "llvm/Transforms/IPO/StripSymbols.h"
124 #include "llvm/Transforms/IPO/SyntheticCountsPropagation.h"
125 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
126 #include "llvm/Transforms/InstCombine/InstCombine.h"
127 #include "llvm/Transforms/Instrumentation.h"
128 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
129 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
130 #include "llvm/Transforms/Instrumentation/CGProfile.h"
131 #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h"
132 #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
133 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
134 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
135 #include "llvm/Transforms/Instrumentation/InstrOrderFile.h"
136 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
137 #include "llvm/Transforms/Instrumentation/MemProfiler.h"
138 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
139 #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
140 #include "llvm/Transforms/Instrumentation/PoisonChecking.h"
141 #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
142 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
143 #include "llvm/Transforms/ObjCARC.h"
144 #include "llvm/Transforms/Scalar/ADCE.h"
145 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
146 #include "llvm/Transforms/Scalar/AnnotationRemarks.h"
147 #include "llvm/Transforms/Scalar/BDCE.h"
148 #include "llvm/Transforms/Scalar/CallSiteSplitting.h"
149 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
150 #include "llvm/Transforms/Scalar/ConstraintElimination.h"
151 #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
152 #include "llvm/Transforms/Scalar/DCE.h"
153 #include "llvm/Transforms/Scalar/DFAJumpThreading.h"
154 #include "llvm/Transforms/Scalar/DeadStoreElimination.h"
155 #include "llvm/Transforms/Scalar/DivRemPairs.h"
156 #include "llvm/Transforms/Scalar/EarlyCSE.h"
157 #include "llvm/Transforms/Scalar/FlattenCFG.h"
158 #include "llvm/Transforms/Scalar/Float2Int.h"
159 #include "llvm/Transforms/Scalar/GVN.h"
160 #include "llvm/Transforms/Scalar/GuardWidening.h"
161 #include "llvm/Transforms/Scalar/IVUsersPrinter.h"
162 #include "llvm/Transforms/Scalar/IndVarSimplify.h"
163 #include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h"
164 #include "llvm/Transforms/Scalar/InferAddressSpaces.h"
165 #include "llvm/Transforms/Scalar/InstSimplifyPass.h"
166 #include "llvm/Transforms/Scalar/JumpThreading.h"
167 #include "llvm/Transforms/Scalar/LICM.h"
168 #include "llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h"
169 #include "llvm/Transforms/Scalar/LoopBoundSplit.h"
170 #include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
171 #include "llvm/Transforms/Scalar/LoopDeletion.h"
172 #include "llvm/Transforms/Scalar/LoopDistribute.h"
173 #include "llvm/Transforms/Scalar/LoopFlatten.h"
174 #include "llvm/Transforms/Scalar/LoopFuse.h"
175 #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
176 #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
177 #include "llvm/Transforms/Scalar/LoopInterchange.h"
178 #include "llvm/Transforms/Scalar/LoopLoadElimination.h"
179 #include "llvm/Transforms/Scalar/LoopPassManager.h"
180 #include "llvm/Transforms/Scalar/LoopPredication.h"
181 #include "llvm/Transforms/Scalar/LoopReroll.h"
182 #include "llvm/Transforms/Scalar/LoopRotation.h"
183 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
184 #include "llvm/Transforms/Scalar/LoopSink.h"
185 #include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
186 #include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h"
187 #include "llvm/Transforms/Scalar/LoopUnrollPass.h"
188 #include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
189 #include "llvm/Transforms/Scalar/LowerAtomicPass.h"
190 #include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
191 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
192 #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
193 #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
194 #include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
195 #include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
196 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
197 #include "llvm/Transforms/Scalar/MergeICmps.h"
198 #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
199 #include "llvm/Transforms/Scalar/NaryReassociate.h"
200 #include "llvm/Transforms/Scalar/NewGVN.h"
201 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
202 #include "llvm/Transforms/Scalar/Reassociate.h"
203 #include "llvm/Transforms/Scalar/Reg2Mem.h"
204 #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
205 #include "llvm/Transforms/Scalar/SCCP.h"
206 #include "llvm/Transforms/Scalar/SROA.h"
207 #include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
208 #include "llvm/Transforms/Scalar/Scalarizer.h"
209 #include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
210 #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
211 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
212 #include "llvm/Transforms/Scalar/Sink.h"
213 #include "llvm/Transforms/Scalar/SpeculativeExecution.h"
214 #include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
215 #include "llvm/Transforms/Scalar/StructurizeCFG.h"
216 #include "llvm/Transforms/Scalar/TLSVariableHoist.h"
217 #include "llvm/Transforms/Scalar/TailRecursionElimination.h"
218 #include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
219 #include "llvm/Transforms/Utils/AddDiscriminators.h"
220 #include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
221 #include "llvm/Transforms/Utils/BreakCriticalEdges.h"
222 #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
223 #include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
224 #include "llvm/Transforms/Utils/Debugify.h"
225 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
226 #include "llvm/Transforms/Utils/FixIrreducible.h"
227 #include "llvm/Transforms/Utils/HelloWorld.h"
228 #include "llvm/Transforms/Utils/InjectTLIMappings.h"
229 #include "llvm/Transforms/Utils/InstructionNamer.h"
230 #include "llvm/Transforms/Utils/LCSSA.h"
231 #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
232 #include "llvm/Transforms/Utils/LoopSimplify.h"
233 #include "llvm/Transforms/Utils/LoopVersioning.h"
234 #include "llvm/Transforms/Utils/LowerGlobalDtors.h"
235 #include "llvm/Transforms/Utils/LowerInvoke.h"
236 #include "llvm/Transforms/Utils/LowerSwitch.h"
237 #include "llvm/Transforms/Utils/Mem2Reg.h"
238 #include "llvm/Transforms/Utils/MetaRenamer.h"
239 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
240 #include "llvm/Transforms/Utils/PredicateInfo.h"
241 #include "llvm/Transforms/Utils/RelLookupTableConverter.h"
242 #include "llvm/Transforms/Utils/StripGCRelocates.h"
243 #include "llvm/Transforms/Utils/StripNonLineTableDebugInfo.h"
244 #include "llvm/Transforms/Utils/SymbolRewriter.h"
245 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
246 #include "llvm/Transforms/Utils/UnifyLoopExits.h"
247 #include "llvm/Transforms/Vectorize/LoadStoreVectorizer.h"
248 #include "llvm/Transforms/Vectorize/LoopVectorize.h"
249 #include "llvm/Transforms/Vectorize/SLPVectorizer.h"
250 #include "llvm/Transforms/Vectorize/VectorCombine.h"
251
252 using namespace llvm;
253
254 static const Regex DefaultAliasRegex(
255 "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
256
257 namespace llvm {
258 cl::opt<bool> PrintPipelinePasses(
259 "print-pipeline-passes",
260 cl::desc("Print a '-passes' compatible string describing the pipeline "
261 "(best-effort only)."));
262 } // namespace llvm
263
264 namespace {
265
266 // The following passes/analyses have custom names, otherwise their name will
267 // include `(anonymous namespace)`. These are special since they are only for
268 // testing purposes and don't live in a header file.
269
270 /// No-op module pass which does nothing.
271 struct NoOpModulePass : PassInfoMixin<NoOpModulePass> {
run__anond0f669fc0111::NoOpModulePass272 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
273 return PreservedAnalyses::all();
274 }
275
name__anond0f669fc0111::NoOpModulePass276 static StringRef name() { return "NoOpModulePass"; }
277 };
278
279 /// No-op module analysis.
280 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
281 friend AnalysisInfoMixin<NoOpModuleAnalysis>;
282 static AnalysisKey Key;
283
284 public:
285 struct Result {};
run(Module &,ModuleAnalysisManager &)286 Result run(Module &, ModuleAnalysisManager &) { return Result(); }
name()287 static StringRef name() { return "NoOpModuleAnalysis"; }
288 };
289
290 /// No-op CGSCC pass which does nothing.
291 struct NoOpCGSCCPass : PassInfoMixin<NoOpCGSCCPass> {
run__anond0f669fc0111::NoOpCGSCCPass292 PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
293 LazyCallGraph &, CGSCCUpdateResult &UR) {
294 return PreservedAnalyses::all();
295 }
name__anond0f669fc0111::NoOpCGSCCPass296 static StringRef name() { return "NoOpCGSCCPass"; }
297 };
298
299 /// No-op CGSCC analysis.
300 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
301 friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
302 static AnalysisKey Key;
303
304 public:
305 struct Result {};
run(LazyCallGraph::SCC &,CGSCCAnalysisManager &,LazyCallGraph & G)306 Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
307 return Result();
308 }
name()309 static StringRef name() { return "NoOpCGSCCAnalysis"; }
310 };
311
312 /// No-op function pass which does nothing.
313 struct NoOpFunctionPass : PassInfoMixin<NoOpFunctionPass> {
run__anond0f669fc0111::NoOpFunctionPass314 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
315 return PreservedAnalyses::all();
316 }
name__anond0f669fc0111::NoOpFunctionPass317 static StringRef name() { return "NoOpFunctionPass"; }
318 };
319
320 /// No-op function analysis.
321 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
322 friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
323 static AnalysisKey Key;
324
325 public:
326 struct Result {};
run(Function &,FunctionAnalysisManager &)327 Result run(Function &, FunctionAnalysisManager &) { return Result(); }
name()328 static StringRef name() { return "NoOpFunctionAnalysis"; }
329 };
330
331 /// No-op loop nest pass which does nothing.
332 struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
run__anond0f669fc0111::NoOpLoopNestPass333 PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
334 LoopStandardAnalysisResults &, LPMUpdater &) {
335 return PreservedAnalyses::all();
336 }
name__anond0f669fc0111::NoOpLoopNestPass337 static StringRef name() { return "NoOpLoopNestPass"; }
338 };
339
340 /// No-op loop pass which does nothing.
341 struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
run__anond0f669fc0111::NoOpLoopPass342 PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
343 LoopStandardAnalysisResults &, LPMUpdater &) {
344 return PreservedAnalyses::all();
345 }
name__anond0f669fc0111::NoOpLoopPass346 static StringRef name() { return "NoOpLoopPass"; }
347 };
348
349 /// No-op loop analysis.
350 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
351 friend AnalysisInfoMixin<NoOpLoopAnalysis>;
352 static AnalysisKey Key;
353
354 public:
355 struct Result {};
run(Loop &,LoopAnalysisManager &,LoopStandardAnalysisResults &)356 Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
357 return Result();
358 }
name()359 static StringRef name() { return "NoOpLoopAnalysis"; }
360 };
361
362 AnalysisKey NoOpModuleAnalysis::Key;
363 AnalysisKey NoOpCGSCCAnalysis::Key;
364 AnalysisKey NoOpFunctionAnalysis::Key;
365 AnalysisKey NoOpLoopAnalysis::Key;
366
367 /// Whether or not we should populate a PassInstrumentationCallbacks's class to
368 /// pass name map.
369 ///
370 /// This is for optimization purposes so we don't populate it if we never use
371 /// it. This should be updated if new pass instrumentation wants to use the map.
372 /// We currently only use this for --print-before/after.
shouldPopulateClassToPassNames()373 bool shouldPopulateClassToPassNames() {
374 return PrintPipelinePasses || !printBeforePasses().empty() ||
375 !printAfterPasses().empty();
376 }
377
378 // A pass for testing -print-on-crash.
379 // DO NOT USE THIS EXCEPT FOR TESTING!
380 class TriggerCrashPass : public PassInfoMixin<TriggerCrashPass> {
381 public:
run(Module &,ModuleAnalysisManager &)382 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
383 abort();
384 return PreservedAnalyses::all();
385 }
name()386 static StringRef name() { return "TriggerCrashPass"; }
387 };
388
389 } // namespace
390
PassBuilder(TargetMachine * TM,PipelineTuningOptions PTO,Optional<PGOOptions> PGOOpt,PassInstrumentationCallbacks * PIC)391 PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
392 Optional<PGOOptions> PGOOpt,
393 PassInstrumentationCallbacks *PIC)
394 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
395 if (TM)
396 TM->registerPassBuilderCallbacks(*this);
397 if (PIC && shouldPopulateClassToPassNames()) {
398 #define MODULE_PASS(NAME, CREATE_PASS) \
399 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
400 #define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
401 PIC->addClassToPassName(CLASS, NAME);
402 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
403 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
404 #define FUNCTION_PASS(NAME, CREATE_PASS) \
405 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
406 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
407 PIC->addClassToPassName(CLASS, NAME);
408 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
409 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
410 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
411 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
412 #define LOOP_PASS(NAME, CREATE_PASS) \
413 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
414 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
415 PIC->addClassToPassName(CLASS, NAME);
416 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
417 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
418 #define CGSCC_PASS(NAME, CREATE_PASS) \
419 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
420 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
421 PIC->addClassToPassName(CLASS, NAME);
422 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
423 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
424 #include "PassRegistry.def"
425 }
426 }
427
registerModuleAnalyses(ModuleAnalysisManager & MAM)428 void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
429 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
430 MAM.registerPass([&] { return CREATE_PASS; });
431 #include "PassRegistry.def"
432
433 for (auto &C : ModuleAnalysisRegistrationCallbacks)
434 C(MAM);
435 }
436
registerCGSCCAnalyses(CGSCCAnalysisManager & CGAM)437 void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
438 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
439 CGAM.registerPass([&] { return CREATE_PASS; });
440 #include "PassRegistry.def"
441
442 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
443 C(CGAM);
444 }
445
registerFunctionAnalyses(FunctionAnalysisManager & FAM)446 void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
447 // We almost always want the default alias analysis pipeline.
448 // If a user wants a different one, they can register their own before calling
449 // registerFunctionAnalyses().
450 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
451
452 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
453 FAM.registerPass([&] { return CREATE_PASS; });
454 #include "PassRegistry.def"
455
456 for (auto &C : FunctionAnalysisRegistrationCallbacks)
457 C(FAM);
458 }
459
registerLoopAnalyses(LoopAnalysisManager & LAM)460 void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
461 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
462 LAM.registerPass([&] { return CREATE_PASS; });
463 #include "PassRegistry.def"
464
465 for (auto &C : LoopAnalysisRegistrationCallbacks)
466 C(LAM);
467 }
468
parseRepeatPassName(StringRef Name)469 static Optional<int> parseRepeatPassName(StringRef Name) {
470 if (!Name.consume_front("repeat<") || !Name.consume_back(">"))
471 return None;
472 int Count;
473 if (Name.getAsInteger(0, Count) || Count <= 0)
474 return None;
475 return Count;
476 }
477
parseDevirtPassName(StringRef Name)478 static Optional<int> parseDevirtPassName(StringRef Name) {
479 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
480 return None;
481 int Count;
482 if (Name.getAsInteger(0, Count) || Count < 0)
483 return None;
484 return Count;
485 }
486
checkParametrizedPassName(StringRef Name,StringRef PassName)487 static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
488 if (!Name.consume_front(PassName))
489 return false;
490 // normal pass name w/o parameters == default parameters
491 if (Name.empty())
492 return true;
493 return Name.startswith("<") && Name.endswith(">");
494 }
495
496 namespace {
497
498 /// This performs customized parsing of pass name with parameters.
499 ///
500 /// We do not need parametrization of passes in textual pipeline very often,
501 /// yet on a rare occasion ability to specify parameters right there can be
502 /// useful.
503 ///
504 /// \p Name - parameterized specification of a pass from a textual pipeline
505 /// is a string in a form of :
506 /// PassName '<' parameter-list '>'
507 ///
508 /// Parameter list is being parsed by the parser callable argument, \p Parser,
509 /// It takes a string-ref of parameters and returns either StringError or a
510 /// parameter list in a form of a custom parameters type, all wrapped into
511 /// Expected<> template class.
512 ///
513 template <typename ParametersParseCallableT>
parsePassParameters(ParametersParseCallableT && Parser,StringRef Name,StringRef PassName)514 auto parsePassParameters(ParametersParseCallableT &&Parser, StringRef Name,
515 StringRef PassName) -> decltype(Parser(StringRef{})) {
516 using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
517
518 StringRef Params = Name;
519 if (!Params.consume_front(PassName)) {
520 assert(false &&
521 "unable to strip pass name from parametrized pass specification");
522 }
523 if (!Params.empty() &&
524 (!Params.consume_front("<") || !Params.consume_back(">"))) {
525 assert(false && "invalid format for parametrized pass name");
526 }
527
528 Expected<ParametersT> Result = Parser(Params);
529 assert((Result || Result.template errorIsA<StringError>()) &&
530 "Pass parameter parser can only return StringErrors.");
531 return Result;
532 }
533
534 /// Parser of parameters for LoopUnroll pass.
parseLoopUnrollOptions(StringRef Params)535 Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
536 LoopUnrollOptions UnrollOpts;
537 while (!Params.empty()) {
538 StringRef ParamName;
539 std::tie(ParamName, Params) = Params.split(';');
540 int OptLevel = StringSwitch<int>(ParamName)
541 .Case("O0", 0)
542 .Case("O1", 1)
543 .Case("O2", 2)
544 .Case("O3", 3)
545 .Default(-1);
546 if (OptLevel >= 0) {
547 UnrollOpts.setOptLevel(OptLevel);
548 continue;
549 }
550 if (ParamName.consume_front("full-unroll-max=")) {
551 int Count;
552 if (ParamName.getAsInteger(0, Count))
553 return make_error<StringError>(
554 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
555 inconvertibleErrorCode());
556 UnrollOpts.setFullUnrollMaxCount(Count);
557 continue;
558 }
559
560 bool Enable = !ParamName.consume_front("no-");
561 if (ParamName == "partial") {
562 UnrollOpts.setPartial(Enable);
563 } else if (ParamName == "peeling") {
564 UnrollOpts.setPeeling(Enable);
565 } else if (ParamName == "profile-peeling") {
566 UnrollOpts.setProfileBasedPeeling(Enable);
567 } else if (ParamName == "runtime") {
568 UnrollOpts.setRuntime(Enable);
569 } else if (ParamName == "upperbound") {
570 UnrollOpts.setUpperBound(Enable);
571 } else {
572 return make_error<StringError>(
573 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
574 inconvertibleErrorCode());
575 }
576 }
577 return UnrollOpts;
578 }
579
parseSinglePassOption(StringRef Params,StringRef OptionName,StringRef PassName)580 Expected<bool> parseSinglePassOption(StringRef Params, StringRef OptionName,
581 StringRef PassName) {
582 bool Result = false;
583 while (!Params.empty()) {
584 StringRef ParamName;
585 std::tie(ParamName, Params) = Params.split(';');
586
587 if (ParamName == OptionName) {
588 Result = true;
589 } else {
590 return make_error<StringError>(
591 formatv("invalid {1} pass parameter '{0}' ", ParamName, PassName)
592 .str(),
593 inconvertibleErrorCode());
594 }
595 }
596 return Result;
597 }
598
parseInlinerPassOptions(StringRef Params)599 Expected<bool> parseInlinerPassOptions(StringRef Params) {
600 return parseSinglePassOption(Params, "only-mandatory", "InlinerPass");
601 }
602
parseCoroSplitPassOptions(StringRef Params)603 Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
604 return parseSinglePassOption(Params, "reuse-storage", "CoroSplitPass");
605 }
606
parseEarlyCSEPassOptions(StringRef Params)607 Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
608 return parseSinglePassOption(Params, "memssa", "EarlyCSE");
609 }
610
parseEntryExitInstrumenterPassOptions(StringRef Params)611 Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
612 return parseSinglePassOption(Params, "post-inline", "EntryExitInstrumenter");
613 }
614
parseLoopExtractorPassOptions(StringRef Params)615 Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
616 return parseSinglePassOption(Params, "single", "LoopExtractor");
617 }
618
parseLowerMatrixIntrinsicsPassOptions(StringRef Params)619 Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
620 return parseSinglePassOption(Params, "minimal", "LowerMatrixIntrinsics");
621 }
622
parseASanPassOptions(StringRef Params)623 Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
624 AddressSanitizerOptions Result;
625 while (!Params.empty()) {
626 StringRef ParamName;
627 std::tie(ParamName, Params) = Params.split(';');
628
629 if (ParamName == "kernel") {
630 Result.CompileKernel = true;
631 } else {
632 return make_error<StringError>(
633 formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName)
634 .str(),
635 inconvertibleErrorCode());
636 }
637 }
638 return Result;
639 }
640
parseHWASanPassOptions(StringRef Params)641 Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
642 HWAddressSanitizerOptions Result;
643 while (!Params.empty()) {
644 StringRef ParamName;
645 std::tie(ParamName, Params) = Params.split(';');
646
647 if (ParamName == "recover") {
648 Result.Recover = true;
649 } else if (ParamName == "kernel") {
650 Result.CompileKernel = true;
651 } else {
652 return make_error<StringError>(
653 formatv("invalid HWAddressSanitizer pass parameter '{0}' ", ParamName)
654 .str(),
655 inconvertibleErrorCode());
656 }
657 }
658 return Result;
659 }
660
parseMSanPassOptions(StringRef Params)661 Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
662 MemorySanitizerOptions Result;
663 while (!Params.empty()) {
664 StringRef ParamName;
665 std::tie(ParamName, Params) = Params.split(';');
666
667 if (ParamName == "recover") {
668 Result.Recover = true;
669 } else if (ParamName == "kernel") {
670 Result.Kernel = true;
671 } else if (ParamName.consume_front("track-origins=")) {
672 if (ParamName.getAsInteger(0, Result.TrackOrigins))
673 return make_error<StringError>(
674 formatv("invalid argument to MemorySanitizer pass track-origins "
675 "parameter: '{0}' ",
676 ParamName)
677 .str(),
678 inconvertibleErrorCode());
679 } else if (ParamName == "eager-checks") {
680 Result.EagerChecks = true;
681 } else {
682 return make_error<StringError>(
683 formatv("invalid MemorySanitizer pass parameter '{0}' ", ParamName)
684 .str(),
685 inconvertibleErrorCode());
686 }
687 }
688 return Result;
689 }
690
691 /// Parser of parameters for SimplifyCFG pass.
parseSimplifyCFGOptions(StringRef Params)692 Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
693 SimplifyCFGOptions Result;
694 while (!Params.empty()) {
695 StringRef ParamName;
696 std::tie(ParamName, Params) = Params.split(';');
697
698 bool Enable = !ParamName.consume_front("no-");
699 if (ParamName == "forward-switch-cond") {
700 Result.forwardSwitchCondToPhi(Enable);
701 } else if (ParamName == "switch-range-to-icmp") {
702 Result.convertSwitchRangeToICmp(Enable);
703 } else if (ParamName == "switch-to-lookup") {
704 Result.convertSwitchToLookupTable(Enable);
705 } else if (ParamName == "keep-loops") {
706 Result.needCanonicalLoops(Enable);
707 } else if (ParamName == "hoist-common-insts") {
708 Result.hoistCommonInsts(Enable);
709 } else if (ParamName == "sink-common-insts") {
710 Result.sinkCommonInsts(Enable);
711 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
712 APInt BonusInstThreshold;
713 if (ParamName.getAsInteger(0, BonusInstThreshold))
714 return make_error<StringError>(
715 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
716 "parameter: '{0}' ",
717 ParamName).str(),
718 inconvertibleErrorCode());
719 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
720 } else {
721 return make_error<StringError>(
722 formatv("invalid SimplifyCFG pass parameter '{0}' ", ParamName).str(),
723 inconvertibleErrorCode());
724 }
725 }
726 return Result;
727 }
728
729 /// Parser of parameters for LoopVectorize pass.
parseLoopVectorizeOptions(StringRef Params)730 Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
731 LoopVectorizeOptions Opts;
732 while (!Params.empty()) {
733 StringRef ParamName;
734 std::tie(ParamName, Params) = Params.split(';');
735
736 bool Enable = !ParamName.consume_front("no-");
737 if (ParamName == "interleave-forced-only") {
738 Opts.setInterleaveOnlyWhenForced(Enable);
739 } else if (ParamName == "vectorize-forced-only") {
740 Opts.setVectorizeOnlyWhenForced(Enable);
741 } else {
742 return make_error<StringError>(
743 formatv("invalid LoopVectorize parameter '{0}' ", ParamName).str(),
744 inconvertibleErrorCode());
745 }
746 }
747 return Opts;
748 }
749
parseLoopUnswitchOptions(StringRef Params)750 Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
751 std::pair<bool, bool> Result = {false, true};
752 while (!Params.empty()) {
753 StringRef ParamName;
754 std::tie(ParamName, Params) = Params.split(';');
755
756 bool Enable = !ParamName.consume_front("no-");
757 if (ParamName == "nontrivial") {
758 Result.first = Enable;
759 } else if (ParamName == "trivial") {
760 Result.second = Enable;
761 } else {
762 return make_error<StringError>(
763 formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
764 .str(),
765 inconvertibleErrorCode());
766 }
767 }
768 return Result;
769 }
770
parseLICMOptions(StringRef Params)771 Expected<LICMOptions> parseLICMOptions(StringRef Params) {
772 LICMOptions Result;
773 while (!Params.empty()) {
774 StringRef ParamName;
775 std::tie(ParamName, Params) = Params.split(';');
776
777 bool Enable = !ParamName.consume_front("no-");
778 if (ParamName == "allowspeculation") {
779 Result.AllowSpeculation = Enable;
780 } else {
781 return make_error<StringError>(
782 formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
783 inconvertibleErrorCode());
784 }
785 }
786 return Result;
787 }
788
parseMergedLoadStoreMotionOptions(StringRef Params)789 Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
790 bool Result = false;
791 while (!Params.empty()) {
792 StringRef ParamName;
793 std::tie(ParamName, Params) = Params.split(';');
794
795 bool Enable = !ParamName.consume_front("no-");
796 if (ParamName == "split-footer-bb") {
797 Result = Enable;
798 } else {
799 return make_error<StringError>(
800 formatv("invalid MergedLoadStoreMotion pass parameter '{0}' ",
801 ParamName)
802 .str(),
803 inconvertibleErrorCode());
804 }
805 }
806 return Result;
807 }
808
parseGVNOptions(StringRef Params)809 Expected<GVNOptions> parseGVNOptions(StringRef Params) {
810 GVNOptions Result;
811 while (!Params.empty()) {
812 StringRef ParamName;
813 std::tie(ParamName, Params) = Params.split(';');
814
815 bool Enable = !ParamName.consume_front("no-");
816 if (ParamName == "pre") {
817 Result.setPRE(Enable);
818 } else if (ParamName == "load-pre") {
819 Result.setLoadPRE(Enable);
820 } else if (ParamName == "split-backedge-load-pre") {
821 Result.setLoadPRESplitBackedge(Enable);
822 } else if (ParamName == "memdep") {
823 Result.setMemDep(Enable);
824 } else {
825 return make_error<StringError>(
826 formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
827 inconvertibleErrorCode());
828 }
829 }
830 return Result;
831 }
832
833 Expected<StackLifetime::LivenessType>
parseStackLifetimeOptions(StringRef Params)834 parseStackLifetimeOptions(StringRef Params) {
835 StackLifetime::LivenessType Result = StackLifetime::LivenessType::May;
836 while (!Params.empty()) {
837 StringRef ParamName;
838 std::tie(ParamName, Params) = Params.split(';');
839
840 if (ParamName == "may") {
841 Result = StackLifetime::LivenessType::May;
842 } else if (ParamName == "must") {
843 Result = StackLifetime::LivenessType::Must;
844 } else {
845 return make_error<StringError>(
846 formatv("invalid StackLifetime parameter '{0}' ", ParamName).str(),
847 inconvertibleErrorCode());
848 }
849 }
850 return Result;
851 }
852
853 } // namespace
854
855 /// Tests whether a pass name starts with a valid prefix for a default pipeline
856 /// alias.
startsWithDefaultPipelineAliasPrefix(StringRef Name)857 static bool startsWithDefaultPipelineAliasPrefix(StringRef Name) {
858 return Name.startswith("default") || Name.startswith("thinlto") ||
859 Name.startswith("lto");
860 }
861
862 /// Tests whether registered callbacks will accept a given pass name.
863 ///
864 /// When parsing a pipeline text, the type of the outermost pipeline may be
865 /// omitted, in which case the type is automatically determined from the first
866 /// pass name in the text. This may be a name that is handled through one of the
867 /// callbacks. We check this through the oridinary parsing callbacks by setting
868 /// up a dummy PassManager in order to not force the client to also handle this
869 /// type of query.
870 template <typename PassManagerT, typename CallbacksT>
callbacksAcceptPassName(StringRef Name,CallbacksT & Callbacks)871 static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
872 if (!Callbacks.empty()) {
873 PassManagerT DummyPM;
874 for (auto &CB : Callbacks)
875 if (CB(Name, DummyPM, {}))
876 return true;
877 }
878 return false;
879 }
880
881 template <typename CallbacksT>
isModulePassName(StringRef Name,CallbacksT & Callbacks)882 static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
883 // Manually handle aliases for pre-configured pipeline fragments.
884 if (startsWithDefaultPipelineAliasPrefix(Name))
885 return DefaultAliasRegex.match(Name);
886
887 // Explicitly handle pass manager names.
888 if (Name == "module")
889 return true;
890 if (Name == "cgscc")
891 return true;
892 if (Name == "function" || Name == "function<eager-inv>")
893 return true;
894
895 // Explicitly handle custom-parsed pass names.
896 if (parseRepeatPassName(Name))
897 return true;
898
899 #define MODULE_PASS(NAME, CREATE_PASS) \
900 if (Name == NAME) \
901 return true;
902 #define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
903 if (checkParametrizedPassName(Name, NAME)) \
904 return true;
905 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
906 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
907 return true;
908 #include "PassRegistry.def"
909
910 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
911 }
912
913 template <typename CallbacksT>
isCGSCCPassName(StringRef Name,CallbacksT & Callbacks)914 static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
915 // Explicitly handle pass manager names.
916 if (Name == "cgscc")
917 return true;
918 if (Name == "function" || Name == "function<eager-inv>")
919 return true;
920
921 // Explicitly handle custom-parsed pass names.
922 if (parseRepeatPassName(Name))
923 return true;
924 if (parseDevirtPassName(Name))
925 return true;
926
927 #define CGSCC_PASS(NAME, CREATE_PASS) \
928 if (Name == NAME) \
929 return true;
930 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
931 if (checkParametrizedPassName(Name, NAME)) \
932 return true;
933 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
934 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
935 return true;
936 #include "PassRegistry.def"
937
938 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
939 }
940
941 template <typename CallbacksT>
isFunctionPassName(StringRef Name,CallbacksT & Callbacks)942 static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
943 // Explicitly handle pass manager names.
944 if (Name == "function" || Name == "function<eager-inv>")
945 return true;
946 if (Name == "loop" || Name == "loop-mssa")
947 return true;
948
949 // Explicitly handle custom-parsed pass names.
950 if (parseRepeatPassName(Name))
951 return true;
952
953 #define FUNCTION_PASS(NAME, CREATE_PASS) \
954 if (Name == NAME) \
955 return true;
956 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
957 if (checkParametrizedPassName(Name, NAME)) \
958 return true;
959 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
960 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
961 return true;
962 #include "PassRegistry.def"
963
964 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
965 }
966
967 template <typename CallbacksT>
isLoopNestPassName(StringRef Name,CallbacksT & Callbacks,bool & UseMemorySSA)968 static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
969 bool &UseMemorySSA) {
970 UseMemorySSA = false;
971
972 // Explicitly handle custom-parsed pass names.
973 if (parseRepeatPassName(Name))
974 return true;
975
976 if (Name == "lnicm") {
977 UseMemorySSA = true;
978 return true;
979 }
980
981 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
982 if (Name == NAME) \
983 return true;
984 #include "PassRegistry.def"
985
986 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
987 }
988
989 template <typename CallbacksT>
isLoopPassName(StringRef Name,CallbacksT & Callbacks,bool & UseMemorySSA)990 static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
991 bool &UseMemorySSA) {
992 UseMemorySSA = false;
993
994 // Explicitly handle custom-parsed pass names.
995 if (parseRepeatPassName(Name))
996 return true;
997
998 if (Name == "licm") {
999 UseMemorySSA = true;
1000 return true;
1001 }
1002
1003 #define LOOP_PASS(NAME, CREATE_PASS) \
1004 if (Name == NAME) \
1005 return true;
1006 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1007 if (checkParametrizedPassName(Name, NAME)) \
1008 return true;
1009 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1010 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1011 return true;
1012 #include "PassRegistry.def"
1013
1014 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1015 }
1016
1017 Optional<std::vector<PassBuilder::PipelineElement>>
parsePipelineText(StringRef Text)1018 PassBuilder::parsePipelineText(StringRef Text) {
1019 std::vector<PipelineElement> ResultPipeline;
1020
1021 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1022 &ResultPipeline};
1023 for (;;) {
1024 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1025 size_t Pos = Text.find_first_of(",()");
1026 Pipeline.push_back({Text.substr(0, Pos), {}});
1027
1028 // If we have a single terminating name, we're done.
1029 if (Pos == Text.npos)
1030 break;
1031
1032 char Sep = Text[Pos];
1033 Text = Text.substr(Pos + 1);
1034 if (Sep == ',')
1035 // Just a name ending in a comma, continue.
1036 continue;
1037
1038 if (Sep == '(') {
1039 // Push the inner pipeline onto the stack to continue processing.
1040 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1041 continue;
1042 }
1043
1044 assert(Sep == ')' && "Bogus separator!");
1045 // When handling the close parenthesis, we greedily consume them to avoid
1046 // empty strings in the pipeline.
1047 do {
1048 // If we try to pop the outer pipeline we have unbalanced parentheses.
1049 if (PipelineStack.size() == 1)
1050 return None;
1051
1052 PipelineStack.pop_back();
1053 } while (Text.consume_front(")"));
1054
1055 // Check if we've finished parsing.
1056 if (Text.empty())
1057 break;
1058
1059 // Otherwise, the end of an inner pipeline always has to be followed by
1060 // a comma, and then we can continue.
1061 if (!Text.consume_front(","))
1062 return None;
1063 }
1064
1065 if (PipelineStack.size() > 1)
1066 // Unbalanced paretheses.
1067 return None;
1068
1069 assert(PipelineStack.back() == &ResultPipeline &&
1070 "Wrong pipeline at the bottom of the stack!");
1071 return {std::move(ResultPipeline)};
1072 }
1073
parseModulePass(ModulePassManager & MPM,const PipelineElement & E)1074 Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1075 const PipelineElement &E) {
1076 auto &Name = E.Name;
1077 auto &InnerPipeline = E.InnerPipeline;
1078
1079 // First handle complex passes like the pass managers which carry pipelines.
1080 if (!InnerPipeline.empty()) {
1081 if (Name == "module") {
1082 ModulePassManager NestedMPM;
1083 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1084 return Err;
1085 MPM.addPass(std::move(NestedMPM));
1086 return Error::success();
1087 }
1088 if (Name == "cgscc") {
1089 CGSCCPassManager CGPM;
1090 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1091 return Err;
1092 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1093 return Error::success();
1094 }
1095 if (Name == "function" || Name == "function<eager-inv>") {
1096 FunctionPassManager FPM;
1097 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1098 return Err;
1099 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM),
1100 Name != "function"));
1101 return Error::success();
1102 }
1103 if (auto Count = parseRepeatPassName(Name)) {
1104 ModulePassManager NestedMPM;
1105 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1106 return Err;
1107 MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
1108 return Error::success();
1109 }
1110
1111 for (auto &C : ModulePipelineParsingCallbacks)
1112 if (C(Name, MPM, InnerPipeline))
1113 return Error::success();
1114
1115 // Normal passes can't have pipelines.
1116 return make_error<StringError>(
1117 formatv("invalid use of '{0}' pass as module pipeline", Name).str(),
1118 inconvertibleErrorCode());
1119 ;
1120 }
1121
1122 // Manually handle aliases for pre-configured pipeline fragments.
1123 if (startsWithDefaultPipelineAliasPrefix(Name)) {
1124 SmallVector<StringRef, 3> Matches;
1125 if (!DefaultAliasRegex.match(Name, &Matches))
1126 return make_error<StringError>(
1127 formatv("unknown default pipeline alias '{0}'", Name).str(),
1128 inconvertibleErrorCode());
1129
1130 assert(Matches.size() == 3 && "Must capture two matched strings!");
1131
1132 OptimizationLevel L = StringSwitch<OptimizationLevel>(Matches[2])
1133 .Case("O0", OptimizationLevel::O0)
1134 .Case("O1", OptimizationLevel::O1)
1135 .Case("O2", OptimizationLevel::O2)
1136 .Case("O3", OptimizationLevel::O3)
1137 .Case("Os", OptimizationLevel::Os)
1138 .Case("Oz", OptimizationLevel::Oz);
1139 if (L == OptimizationLevel::O0 && Matches[1] != "thinlto" &&
1140 Matches[1] != "lto") {
1141 MPM.addPass(buildO0DefaultPipeline(L, Matches[1] == "thinlto-pre-link" ||
1142 Matches[1] == "lto-pre-link"));
1143 return Error::success();
1144 }
1145
1146 // This is consistent with old pass manager invoked via opt, but
1147 // inconsistent with clang. Clang doesn't enable loop vectorization
1148 // but does enable slp vectorization at Oz.
1149 PTO.LoopVectorization =
1150 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1151 PTO.SLPVectorization =
1152 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1153
1154 if (Matches[1] == "default") {
1155 MPM.addPass(buildPerModuleDefaultPipeline(L));
1156 } else if (Matches[1] == "thinlto-pre-link") {
1157 MPM.addPass(buildThinLTOPreLinkDefaultPipeline(L));
1158 } else if (Matches[1] == "thinlto") {
1159 MPM.addPass(buildThinLTODefaultPipeline(L, nullptr));
1160 } else if (Matches[1] == "lto-pre-link") {
1161 MPM.addPass(buildLTOPreLinkDefaultPipeline(L));
1162 } else {
1163 assert(Matches[1] == "lto" && "Not one of the matched options!");
1164 MPM.addPass(buildLTODefaultPipeline(L, nullptr));
1165 }
1166 return Error::success();
1167 }
1168
1169 // Finally expand the basic registered passes from the .inc file.
1170 #define MODULE_PASS(NAME, CREATE_PASS) \
1171 if (Name == NAME) { \
1172 MPM.addPass(CREATE_PASS); \
1173 return Error::success(); \
1174 }
1175 #define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1176 if (checkParametrizedPassName(Name, NAME)) { \
1177 auto Params = parsePassParameters(PARSER, Name, NAME); \
1178 if (!Params) \
1179 return Params.takeError(); \
1180 MPM.addPass(CREATE_PASS(Params.get())); \
1181 return Error::success(); \
1182 }
1183 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1184 if (Name == "require<" NAME ">") { \
1185 MPM.addPass( \
1186 RequireAnalysisPass< \
1187 std::remove_reference<decltype(CREATE_PASS)>::type, Module>()); \
1188 return Error::success(); \
1189 } \
1190 if (Name == "invalidate<" NAME ">") { \
1191 MPM.addPass(InvalidateAnalysisPass< \
1192 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
1193 return Error::success(); \
1194 }
1195 #define CGSCC_PASS(NAME, CREATE_PASS) \
1196 if (Name == NAME) { \
1197 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
1198 return Error::success(); \
1199 }
1200 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1201 if (checkParametrizedPassName(Name, NAME)) { \
1202 auto Params = parsePassParameters(PARSER, Name, NAME); \
1203 if (!Params) \
1204 return Params.takeError(); \
1205 MPM.addPass( \
1206 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
1207 return Error::success(); \
1208 }
1209 #define FUNCTION_PASS(NAME, CREATE_PASS) \
1210 if (Name == NAME) { \
1211 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
1212 return Error::success(); \
1213 }
1214 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1215 if (checkParametrizedPassName(Name, NAME)) { \
1216 auto Params = parsePassParameters(PARSER, Name, NAME); \
1217 if (!Params) \
1218 return Params.takeError(); \
1219 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1220 return Error::success(); \
1221 }
1222 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
1223 if (Name == NAME) { \
1224 MPM.addPass(createModuleToFunctionPassAdaptor( \
1225 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1226 return Error::success(); \
1227 }
1228 #define LOOP_PASS(NAME, CREATE_PASS) \
1229 if (Name == NAME) { \
1230 MPM.addPass(createModuleToFunctionPassAdaptor( \
1231 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1232 return Error::success(); \
1233 }
1234 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1235 if (checkParametrizedPassName(Name, NAME)) { \
1236 auto Params = parsePassParameters(PARSER, Name, NAME); \
1237 if (!Params) \
1238 return Params.takeError(); \
1239 MPM.addPass( \
1240 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1241 CREATE_PASS(Params.get()), false, false))); \
1242 return Error::success(); \
1243 }
1244 #include "PassRegistry.def"
1245
1246 for (auto &C : ModulePipelineParsingCallbacks)
1247 if (C(Name, MPM, InnerPipeline))
1248 return Error::success();
1249 return make_error<StringError>(
1250 formatv("unknown module pass '{0}'", Name).str(),
1251 inconvertibleErrorCode());
1252 }
1253
parseCGSCCPass(CGSCCPassManager & CGPM,const PipelineElement & E)1254 Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
1255 const PipelineElement &E) {
1256 auto &Name = E.Name;
1257 auto &InnerPipeline = E.InnerPipeline;
1258
1259 // First handle complex passes like the pass managers which carry pipelines.
1260 if (!InnerPipeline.empty()) {
1261 if (Name == "cgscc") {
1262 CGSCCPassManager NestedCGPM;
1263 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1264 return Err;
1265 // Add the nested pass manager with the appropriate adaptor.
1266 CGPM.addPass(std::move(NestedCGPM));
1267 return Error::success();
1268 }
1269 if (Name == "function" || Name == "function<eager-inv>") {
1270 FunctionPassManager FPM;
1271 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1272 return Err;
1273 // Add the nested pass manager with the appropriate adaptor.
1274 CGPM.addPass(
1275 createCGSCCToFunctionPassAdaptor(std::move(FPM), Name != "function"));
1276 return Error::success();
1277 }
1278 if (auto Count = parseRepeatPassName(Name)) {
1279 CGSCCPassManager NestedCGPM;
1280 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1281 return Err;
1282 CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM)));
1283 return Error::success();
1284 }
1285 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
1286 CGSCCPassManager NestedCGPM;
1287 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1288 return Err;
1289 CGPM.addPass(
1290 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
1291 return Error::success();
1292 }
1293
1294 for (auto &C : CGSCCPipelineParsingCallbacks)
1295 if (C(Name, CGPM, InnerPipeline))
1296 return Error::success();
1297
1298 // Normal passes can't have pipelines.
1299 return make_error<StringError>(
1300 formatv("invalid use of '{0}' pass as cgscc pipeline", Name).str(),
1301 inconvertibleErrorCode());
1302 }
1303
1304 // Now expand the basic registered passes from the .inc file.
1305 #define CGSCC_PASS(NAME, CREATE_PASS) \
1306 if (Name == NAME) { \
1307 CGPM.addPass(CREATE_PASS); \
1308 return Error::success(); \
1309 }
1310 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1311 if (checkParametrizedPassName(Name, NAME)) { \
1312 auto Params = parsePassParameters(PARSER, Name, NAME); \
1313 if (!Params) \
1314 return Params.takeError(); \
1315 CGPM.addPass(CREATE_PASS(Params.get())); \
1316 return Error::success(); \
1317 }
1318 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1319 if (Name == "require<" NAME ">") { \
1320 CGPM.addPass(RequireAnalysisPass< \
1321 std::remove_reference<decltype(CREATE_PASS)>::type, \
1322 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
1323 CGSCCUpdateResult &>()); \
1324 return Error::success(); \
1325 } \
1326 if (Name == "invalidate<" NAME ">") { \
1327 CGPM.addPass(InvalidateAnalysisPass< \
1328 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
1329 return Error::success(); \
1330 }
1331 #define FUNCTION_PASS(NAME, CREATE_PASS) \
1332 if (Name == NAME) { \
1333 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
1334 return Error::success(); \
1335 }
1336 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1337 if (checkParametrizedPassName(Name, NAME)) { \
1338 auto Params = parsePassParameters(PARSER, Name, NAME); \
1339 if (!Params) \
1340 return Params.takeError(); \
1341 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1342 return Error::success(); \
1343 }
1344 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
1345 if (Name == NAME) { \
1346 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1347 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1348 return Error::success(); \
1349 }
1350 #define LOOP_PASS(NAME, CREATE_PASS) \
1351 if (Name == NAME) { \
1352 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1353 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1354 return Error::success(); \
1355 }
1356 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1357 if (checkParametrizedPassName(Name, NAME)) { \
1358 auto Params = parsePassParameters(PARSER, Name, NAME); \
1359 if (!Params) \
1360 return Params.takeError(); \
1361 CGPM.addPass( \
1362 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1363 CREATE_PASS(Params.get()), false, false))); \
1364 return Error::success(); \
1365 }
1366 #include "PassRegistry.def"
1367
1368 for (auto &C : CGSCCPipelineParsingCallbacks)
1369 if (C(Name, CGPM, InnerPipeline))
1370 return Error::success();
1371 return make_error<StringError>(
1372 formatv("unknown cgscc pass '{0}'", Name).str(),
1373 inconvertibleErrorCode());
1374 }
1375
parseFunctionPass(FunctionPassManager & FPM,const PipelineElement & E)1376 Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
1377 const PipelineElement &E) {
1378 auto &Name = E.Name;
1379 auto &InnerPipeline = E.InnerPipeline;
1380
1381 // First handle complex passes like the pass managers which carry pipelines.
1382 if (!InnerPipeline.empty()) {
1383 if (Name == "function") {
1384 FunctionPassManager NestedFPM;
1385 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1386 return Err;
1387 // Add the nested pass manager with the appropriate adaptor.
1388 FPM.addPass(std::move(NestedFPM));
1389 return Error::success();
1390 }
1391 if (Name == "loop" || Name == "loop-mssa") {
1392 LoopPassManager LPM;
1393 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
1394 return Err;
1395 // Add the nested pass manager with the appropriate adaptor.
1396 bool UseMemorySSA = (Name == "loop-mssa");
1397 bool UseBFI = llvm::any_of(
1398 InnerPipeline, [](auto Pipeline) { return Pipeline.Name == "licm"; });
1399 bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1400 return Pipeline.Name == "loop-predication";
1401 });
1402 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1403 UseBFI, UseBPI));
1404 return Error::success();
1405 }
1406 if (auto Count = parseRepeatPassName(Name)) {
1407 FunctionPassManager NestedFPM;
1408 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1409 return Err;
1410 FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM)));
1411 return Error::success();
1412 }
1413
1414 for (auto &C : FunctionPipelineParsingCallbacks)
1415 if (C(Name, FPM, InnerPipeline))
1416 return Error::success();
1417
1418 // Normal passes can't have pipelines.
1419 return make_error<StringError>(
1420 formatv("invalid use of '{0}' pass as function pipeline", Name).str(),
1421 inconvertibleErrorCode());
1422 }
1423
1424 // Now expand the basic registered passes from the .inc file.
1425 #define FUNCTION_PASS(NAME, CREATE_PASS) \
1426 if (Name == NAME) { \
1427 FPM.addPass(CREATE_PASS); \
1428 return Error::success(); \
1429 }
1430 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1431 if (checkParametrizedPassName(Name, NAME)) { \
1432 auto Params = parsePassParameters(PARSER, Name, NAME); \
1433 if (!Params) \
1434 return Params.takeError(); \
1435 FPM.addPass(CREATE_PASS(Params.get())); \
1436 return Error::success(); \
1437 }
1438 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1439 if (Name == "require<" NAME ">") { \
1440 FPM.addPass( \
1441 RequireAnalysisPass< \
1442 std::remove_reference<decltype(CREATE_PASS)>::type, Function>()); \
1443 return Error::success(); \
1444 } \
1445 if (Name == "invalidate<" NAME ">") { \
1446 FPM.addPass(InvalidateAnalysisPass< \
1447 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
1448 return Error::success(); \
1449 }
1450 // FIXME: UseMemorySSA is set to false. Maybe we could do things like:
1451 // bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
1452 // "guard-widening");
1453 // The risk is that it may become obsolete if we're not careful.
1454 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
1455 if (Name == NAME) { \
1456 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1457 return Error::success(); \
1458 }
1459 #define LOOP_PASS(NAME, CREATE_PASS) \
1460 if (Name == NAME) { \
1461 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1462 return Error::success(); \
1463 }
1464 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1465 if (checkParametrizedPassName(Name, NAME)) { \
1466 auto Params = parsePassParameters(PARSER, Name, NAME); \
1467 if (!Params) \
1468 return Params.takeError(); \
1469 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
1470 false, false)); \
1471 return Error::success(); \
1472 }
1473 #include "PassRegistry.def"
1474
1475 for (auto &C : FunctionPipelineParsingCallbacks)
1476 if (C(Name, FPM, InnerPipeline))
1477 return Error::success();
1478 return make_error<StringError>(
1479 formatv("unknown function pass '{0}'", Name).str(),
1480 inconvertibleErrorCode());
1481 }
1482
parseLoopPass(LoopPassManager & LPM,const PipelineElement & E)1483 Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
1484 const PipelineElement &E) {
1485 StringRef Name = E.Name;
1486 auto &InnerPipeline = E.InnerPipeline;
1487
1488 // First handle complex passes like the pass managers which carry pipelines.
1489 if (!InnerPipeline.empty()) {
1490 if (Name == "loop") {
1491 LoopPassManager NestedLPM;
1492 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1493 return Err;
1494 // Add the nested pass manager with the appropriate adaptor.
1495 LPM.addPass(std::move(NestedLPM));
1496 return Error::success();
1497 }
1498 if (auto Count = parseRepeatPassName(Name)) {
1499 LoopPassManager NestedLPM;
1500 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1501 return Err;
1502 LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM)));
1503 return Error::success();
1504 }
1505
1506 for (auto &C : LoopPipelineParsingCallbacks)
1507 if (C(Name, LPM, InnerPipeline))
1508 return Error::success();
1509
1510 // Normal passes can't have pipelines.
1511 return make_error<StringError>(
1512 formatv("invalid use of '{0}' pass as loop pipeline", Name).str(),
1513 inconvertibleErrorCode());
1514 }
1515
1516 // Now expand the basic registered passes from the .inc file.
1517 #define LOOPNEST_PASS(NAME, CREATE_PASS) \
1518 if (Name == NAME) { \
1519 LPM.addPass(CREATE_PASS); \
1520 return Error::success(); \
1521 }
1522 #define LOOP_PASS(NAME, CREATE_PASS) \
1523 if (Name == NAME) { \
1524 LPM.addPass(CREATE_PASS); \
1525 return Error::success(); \
1526 }
1527 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1528 if (checkParametrizedPassName(Name, NAME)) { \
1529 auto Params = parsePassParameters(PARSER, Name, NAME); \
1530 if (!Params) \
1531 return Params.takeError(); \
1532 LPM.addPass(CREATE_PASS(Params.get())); \
1533 return Error::success(); \
1534 }
1535 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1536 if (Name == "require<" NAME ">") { \
1537 LPM.addPass(RequireAnalysisPass< \
1538 std::remove_reference<decltype(CREATE_PASS)>::type, Loop, \
1539 LoopAnalysisManager, LoopStandardAnalysisResults &, \
1540 LPMUpdater &>()); \
1541 return Error::success(); \
1542 } \
1543 if (Name == "invalidate<" NAME ">") { \
1544 LPM.addPass(InvalidateAnalysisPass< \
1545 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
1546 return Error::success(); \
1547 }
1548 #include "PassRegistry.def"
1549
1550 for (auto &C : LoopPipelineParsingCallbacks)
1551 if (C(Name, LPM, InnerPipeline))
1552 return Error::success();
1553 return make_error<StringError>(formatv("unknown loop pass '{0}'", Name).str(),
1554 inconvertibleErrorCode());
1555 }
1556
parseAAPassName(AAManager & AA,StringRef Name)1557 bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
1558 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1559 if (Name == NAME) { \
1560 AA.registerModuleAnalysis< \
1561 std::remove_reference<decltype(CREATE_PASS)>::type>(); \
1562 return true; \
1563 }
1564 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1565 if (Name == NAME) { \
1566 AA.registerFunctionAnalysis< \
1567 std::remove_reference<decltype(CREATE_PASS)>::type>(); \
1568 return true; \
1569 }
1570 #include "PassRegistry.def"
1571
1572 for (auto &C : AAParsingCallbacks)
1573 if (C(Name, AA))
1574 return true;
1575 return false;
1576 }
1577
parseLoopPassPipeline(LoopPassManager & LPM,ArrayRef<PipelineElement> Pipeline)1578 Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
1579 ArrayRef<PipelineElement> Pipeline) {
1580 for (const auto &Element : Pipeline) {
1581 if (auto Err = parseLoopPass(LPM, Element))
1582 return Err;
1583 }
1584 return Error::success();
1585 }
1586
parseFunctionPassPipeline(FunctionPassManager & FPM,ArrayRef<PipelineElement> Pipeline)1587 Error PassBuilder::parseFunctionPassPipeline(
1588 FunctionPassManager &FPM, ArrayRef<PipelineElement> Pipeline) {
1589 for (const auto &Element : Pipeline) {
1590 if (auto Err = parseFunctionPass(FPM, Element))
1591 return Err;
1592 }
1593 return Error::success();
1594 }
1595
parseCGSCCPassPipeline(CGSCCPassManager & CGPM,ArrayRef<PipelineElement> Pipeline)1596 Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
1597 ArrayRef<PipelineElement> Pipeline) {
1598 for (const auto &Element : Pipeline) {
1599 if (auto Err = parseCGSCCPass(CGPM, Element))
1600 return Err;
1601 }
1602 return Error::success();
1603 }
1604
crossRegisterProxies(LoopAnalysisManager & LAM,FunctionAnalysisManager & FAM,CGSCCAnalysisManager & CGAM,ModuleAnalysisManager & MAM)1605 void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM,
1606 FunctionAnalysisManager &FAM,
1607 CGSCCAnalysisManager &CGAM,
1608 ModuleAnalysisManager &MAM) {
1609 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
1610 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
1611 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
1612 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
1613 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
1614 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
1615 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
1616 }
1617
parseModulePassPipeline(ModulePassManager & MPM,ArrayRef<PipelineElement> Pipeline)1618 Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
1619 ArrayRef<PipelineElement> Pipeline) {
1620 for (const auto &Element : Pipeline) {
1621 if (auto Err = parseModulePass(MPM, Element))
1622 return Err;
1623 }
1624 return Error::success();
1625 }
1626
1627 // Primary pass pipeline description parsing routine for a \c ModulePassManager
1628 // FIXME: Should this routine accept a TargetMachine or require the caller to
1629 // pre-populate the analysis managers with target-specific stuff?
parsePassPipeline(ModulePassManager & MPM,StringRef PipelineText)1630 Error PassBuilder::parsePassPipeline(ModulePassManager &MPM,
1631 StringRef PipelineText) {
1632 auto Pipeline = parsePipelineText(PipelineText);
1633 if (!Pipeline || Pipeline->empty())
1634 return make_error<StringError>(
1635 formatv("invalid pipeline '{0}'", PipelineText).str(),
1636 inconvertibleErrorCode());
1637
1638 // If the first name isn't at the module layer, wrap the pipeline up
1639 // automatically.
1640 StringRef FirstName = Pipeline->front().Name;
1641
1642 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
1643 bool UseMemorySSA;
1644 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
1645 Pipeline = {{"cgscc", std::move(*Pipeline)}};
1646 } else if (isFunctionPassName(FirstName,
1647 FunctionPipelineParsingCallbacks)) {
1648 Pipeline = {{"function", std::move(*Pipeline)}};
1649 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
1650 UseMemorySSA)) {
1651 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
1652 std::move(*Pipeline)}}}};
1653 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
1654 UseMemorySSA)) {
1655 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
1656 std::move(*Pipeline)}}}};
1657 } else {
1658 for (auto &C : TopLevelPipelineParsingCallbacks)
1659 if (C(MPM, *Pipeline))
1660 return Error::success();
1661
1662 // Unknown pass or pipeline name!
1663 auto &InnerPipeline = Pipeline->front().InnerPipeline;
1664 return make_error<StringError>(
1665 formatv("unknown {0} name '{1}'",
1666 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
1667 .str(),
1668 inconvertibleErrorCode());
1669 }
1670 }
1671
1672 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
1673 return Err;
1674 return Error::success();
1675 }
1676
1677 // Primary pass pipeline description parsing routine for a \c CGSCCPassManager
parsePassPipeline(CGSCCPassManager & CGPM,StringRef PipelineText)1678 Error PassBuilder::parsePassPipeline(CGSCCPassManager &CGPM,
1679 StringRef PipelineText) {
1680 auto Pipeline = parsePipelineText(PipelineText);
1681 if (!Pipeline || Pipeline->empty())
1682 return make_error<StringError>(
1683 formatv("invalid pipeline '{0}'", PipelineText).str(),
1684 inconvertibleErrorCode());
1685
1686 StringRef FirstName = Pipeline->front().Name;
1687 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
1688 return make_error<StringError>(
1689 formatv("unknown cgscc pass '{0}' in pipeline '{1}'", FirstName,
1690 PipelineText)
1691 .str(),
1692 inconvertibleErrorCode());
1693
1694 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
1695 return Err;
1696 return Error::success();
1697 }
1698
1699 // Primary pass pipeline description parsing routine for a \c
1700 // FunctionPassManager
parsePassPipeline(FunctionPassManager & FPM,StringRef PipelineText)1701 Error PassBuilder::parsePassPipeline(FunctionPassManager &FPM,
1702 StringRef PipelineText) {
1703 auto Pipeline = parsePipelineText(PipelineText);
1704 if (!Pipeline || Pipeline->empty())
1705 return make_error<StringError>(
1706 formatv("invalid pipeline '{0}'", PipelineText).str(),
1707 inconvertibleErrorCode());
1708
1709 StringRef FirstName = Pipeline->front().Name;
1710 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
1711 return make_error<StringError>(
1712 formatv("unknown function pass '{0}' in pipeline '{1}'", FirstName,
1713 PipelineText)
1714 .str(),
1715 inconvertibleErrorCode());
1716
1717 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
1718 return Err;
1719 return Error::success();
1720 }
1721
1722 // Primary pass pipeline description parsing routine for a \c LoopPassManager
parsePassPipeline(LoopPassManager & CGPM,StringRef PipelineText)1723 Error PassBuilder::parsePassPipeline(LoopPassManager &CGPM,
1724 StringRef PipelineText) {
1725 auto Pipeline = parsePipelineText(PipelineText);
1726 if (!Pipeline || Pipeline->empty())
1727 return make_error<StringError>(
1728 formatv("invalid pipeline '{0}'", PipelineText).str(),
1729 inconvertibleErrorCode());
1730
1731 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
1732 return Err;
1733
1734 return Error::success();
1735 }
1736
parseAAPipeline(AAManager & AA,StringRef PipelineText)1737 Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
1738 // If the pipeline just consists of the word 'default' just replace the AA
1739 // manager with our default one.
1740 if (PipelineText == "default") {
1741 AA = buildDefaultAAPipeline();
1742 return Error::success();
1743 }
1744
1745 while (!PipelineText.empty()) {
1746 StringRef Name;
1747 std::tie(Name, PipelineText) = PipelineText.split(',');
1748 if (!parseAAPassName(AA, Name))
1749 return make_error<StringError>(
1750 formatv("unknown alias analysis name '{0}'", Name).str(),
1751 inconvertibleErrorCode());
1752 }
1753
1754 return Error::success();
1755 }
1756
isAAPassName(StringRef PassName)1757 bool PassBuilder::isAAPassName(StringRef PassName) {
1758 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1759 if (PassName == NAME) \
1760 return true;
1761 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1762 if (PassName == NAME) \
1763 return true;
1764 #include "PassRegistry.def"
1765 return false;
1766 }
1767
isAnalysisPassName(StringRef PassName)1768 bool PassBuilder::isAnalysisPassName(StringRef PassName) {
1769 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1770 if (PassName == NAME) \
1771 return true;
1772 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1773 if (PassName == NAME) \
1774 return true;
1775 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1776 if (PassName == NAME) \
1777 return true;
1778 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1779 if (PassName == NAME) \
1780 return true;
1781 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1782 if (PassName == NAME) \
1783 return true;
1784 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1785 if (PassName == NAME) \
1786 return true;
1787 #include "PassRegistry.def"
1788 return false;
1789 }
1790
printPassName(StringRef PassName,raw_ostream & OS)1791 static void printPassName(StringRef PassName, raw_ostream &OS) {
1792 OS << " " << PassName << "\n";
1793 }
printPassName(StringRef PassName,StringRef Params,raw_ostream & OS)1794 static void printPassName(StringRef PassName, StringRef Params,
1795 raw_ostream &OS) {
1796 OS << " " << PassName << "<" << Params << ">\n";
1797 }
1798
printPassNames(raw_ostream & OS)1799 void PassBuilder::printPassNames(raw_ostream &OS) {
1800 // TODO: print pass descriptions when they are available
1801
1802 OS << "Module passes:\n";
1803 #define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
1804 #include "PassRegistry.def"
1805
1806 OS << "Module passes with params:\n";
1807 #define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1808 printPassName(NAME, PARAMS, OS);
1809 #include "PassRegistry.def"
1810
1811 OS << "Module analyses:\n";
1812 #define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1813 #include "PassRegistry.def"
1814
1815 OS << "Module alias analyses:\n";
1816 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1817 #include "PassRegistry.def"
1818
1819 OS << "CGSCC passes:\n";
1820 #define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
1821 #include "PassRegistry.def"
1822
1823 OS << "CGSCC passes with params:\n";
1824 #define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1825 printPassName(NAME, PARAMS, OS);
1826 #include "PassRegistry.def"
1827
1828 OS << "CGSCC analyses:\n";
1829 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1830 #include "PassRegistry.def"
1831
1832 OS << "Function passes:\n";
1833 #define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
1834 #include "PassRegistry.def"
1835
1836 OS << "Function passes with params:\n";
1837 #define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1838 printPassName(NAME, PARAMS, OS);
1839 #include "PassRegistry.def"
1840
1841 OS << "Function analyses:\n";
1842 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1843 #include "PassRegistry.def"
1844
1845 OS << "Function alias analyses:\n";
1846 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1847 #include "PassRegistry.def"
1848
1849 OS << "LoopNest passes:\n";
1850 #define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
1851 #include "PassRegistry.def"
1852
1853 OS << "Loop passes:\n";
1854 #define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
1855 #include "PassRegistry.def"
1856
1857 OS << "Loop passes with params:\n";
1858 #define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1859 printPassName(NAME, PARAMS, OS);
1860 #include "PassRegistry.def"
1861
1862 OS << "Loop analyses:\n";
1863 #define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
1864 #include "PassRegistry.def"
1865 }
1866
registerParseTopLevelPipelineCallback(const std::function<bool (ModulePassManager &,ArrayRef<PipelineElement>)> & C)1867 void PassBuilder::registerParseTopLevelPipelineCallback(
1868 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
1869 &C) {
1870 TopLevelPipelineParsingCallbacks.push_back(C);
1871 }
1872