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