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