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