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: 344 PreservedAnalyses run(Module &, ModuleAnalysisManager &) { 345 abort(); 346 return PreservedAnalyses::all(); 347 } 348 static StringRef name() { return "TriggerCrashModulePass"; } 349 }; 350 351 class TriggerCrashFunctionPass 352 : public PassInfoMixin<TriggerCrashFunctionPass> { 353 public: 354 PreservedAnalyses run(Function &, FunctionAnalysisManager &) { 355 abort(); 356 return PreservedAnalyses::all(); 357 } 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: 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 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 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 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: 400 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) { 401 MFPropsModifier _(*this, MF); 402 return PreservedAnalyses::none(); 403 } 404 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 } 420 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; } 421 }; 422 423 } // namespace 424 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 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 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 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 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 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>> 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 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 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 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. 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. 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 673 Expected<bool> parseGlobalDCEPassOptions(StringRef Params) { 674 return PassBuilder::parseSinglePassOption( 675 Params, "vfe-linkage-unit-visibility", "GlobalDCE"); 676 } 677 678 Expected<bool> parseCGProfilePassOptions(StringRef Params) { 679 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link", 680 "CGProfile"); 681 } 682 683 Expected<bool> parseInlinerPassOptions(StringRef Params) { 684 return PassBuilder::parseSinglePassOption(Params, "only-mandatory", 685 "InlinerPass"); 686 } 687 688 Expected<bool> parseCoroSplitPassOptions(StringRef Params) { 689 return PassBuilder::parseSinglePassOption(Params, "reuse-storage", 690 "CoroSplitPass"); 691 } 692 693 Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) { 694 return PassBuilder::parseSinglePassOption( 695 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs"); 696 } 697 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 718 Expected<bool> parseEarlyCSEPassOptions(StringRef Params) { 719 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE"); 720 } 721 722 Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) { 723 return PassBuilder::parseSinglePassOption(Params, "post-inline", 724 "EntryExitInstrumenter"); 725 } 726 727 Expected<bool> parseLoopExtractorPassOptions(StringRef Params) { 728 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor"); 729 } 730 731 Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) { 732 return PassBuilder::parseSinglePassOption(Params, "minimal", 733 "LowerMatrixIntrinsics"); 734 } 735 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 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 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 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. 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 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. 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 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 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 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 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 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 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 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> 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 1074 Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) { 1075 return PassBuilder::parseSinglePassOption(Params, "normalized-results", 1076 "DependenceAnalysisPrinter"); 1077 } 1078 1079 Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) { 1080 return PassBuilder::parseSinglePassOption(Params, "lower-gep", 1081 "SeparateConstOffsetFromGEP"); 1082 } 1083 1084 Expected<OptimizationLevel> 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 1096 Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) { 1097 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses", 1098 "MemorySSAPrinterPass"); 1099 } 1100 1101 Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) { 1102 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target", 1103 "SpeculativeExecutionPass"); 1104 } 1105 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 1123 Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) { 1124 return PassBuilder::parseSinglePassOption(Params, "detailed", 1125 "StructuralHashPrinterPass"); 1126 } 1127 1128 Expected<bool> parseWinEHPrepareOptions(StringRef Params) { 1129 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only", 1130 "WinEHPreparePass"); 1131 } 1132 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 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> 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. 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> 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> 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> 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> 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> 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> 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> 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>> 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 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 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 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 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 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 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 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 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 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 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 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 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? 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 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 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 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 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 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> 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 2205 static void printPassName(StringRef PassName, raw_ostream &OS) { 2206 OS << " " << PassName << "\n"; 2207 } 2208 static void printPassName(StringRef PassName, StringRef Params, 2209 raw_ostream &OS) { 2210 OS << " " << PassName << "<" << Params << ">\n"; 2211 } 2212 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 2293 void PassBuilder::registerParseTopLevelPipelineCallback( 2294 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)> 2295 &C) { 2296 TopLevelPipelineParsingCallbacks.push_back(C); 2297 } 2298