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