xref: /freebsd/contrib/llvm-project/llvm/lib/Passes/PassBuilder.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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