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