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