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