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