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

source code of llvm/lib/Passes/PassBuilder.cpp