1 //===- Parsing, selection, and construction of pass pipelines -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// 11 /// This file provides the implementation of the PassBuilder based on our 12 /// static pass registry as well as related functionality. It also provides 13 /// helpers to aid in analyzing, debugging, and testing passes and pass 14 /// pipelines. 15 /// 16 //===----------------------------------------------------------------------===// 17 18 #include "llvm/Passes/PassBuilder.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/Analysis/AliasAnalysis.h" 21 #include "llvm/Analysis/AliasAnalysisEvaluator.h" 22 #include "llvm/Analysis/AssumptionCache.h" 23 #include "llvm/Analysis/BasicAliasAnalysis.h" 24 #include "llvm/Analysis/BlockFrequencyInfo.h" 25 #include "llvm/Analysis/BlockFrequencyInfoImpl.h" 26 #include "llvm/Analysis/BranchProbabilityInfo.h" 27 #include "llvm/Analysis/CFLAndersAliasAnalysis.h" 28 #include "llvm/Analysis/CFLSteensAliasAnalysis.h" 29 #include "llvm/Analysis/CGSCCPassManager.h" 30 #include "llvm/Analysis/CallGraph.h" 31 #include "llvm/Analysis/DemandedBits.h" 32 #include "llvm/Analysis/DependenceAnalysis.h" 33 #include "llvm/Analysis/DominanceFrontier.h" 34 #include "llvm/Analysis/GlobalsModRef.h" 35 #include "llvm/Analysis/LazyCallGraph.h" 36 #include "llvm/Analysis/LazyValueInfo.h" 37 #include "llvm/Analysis/LoopAccessAnalysis.h" 38 #include "llvm/Analysis/LoopInfo.h" 39 #include "llvm/Analysis/MemoryDependenceAnalysis.h" 40 #include "llvm/Analysis/PostDominators.h" 41 #include "llvm/Analysis/ProfileSummaryInfo.h" 42 #include "llvm/Analysis/RegionInfo.h" 43 #include "llvm/Analysis/ScalarEvolution.h" 44 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 45 #include "llvm/Analysis/ScopedNoAliasAA.h" 46 #include "llvm/Analysis/TargetLibraryInfo.h" 47 #include "llvm/Analysis/TargetTransformInfo.h" 48 #include "llvm/Analysis/TypeBasedAliasAnalysis.h" 49 #include "llvm/CodeGen/PreISelIntrinsicLowering.h" 50 #include "llvm/CodeGen/UnreachableBlockElim.h" 51 #include "llvm/IR/Dominators.h" 52 #include "llvm/IR/IRPrintingPasses.h" 53 #include "llvm/IR/PassManager.h" 54 #include "llvm/IR/Verifier.h" 55 #include "llvm/Support/Debug.h" 56 #include "llvm/Support/Regex.h" 57 #include "llvm/Target/TargetMachine.h" 58 #include "llvm/Transforms/GCOVProfiler.h" 59 #include "llvm/Transforms/IPO/ConstantMerge.h" 60 #include "llvm/Transforms/IPO/CrossDSOCFI.h" 61 #include "llvm/Transforms/IPO/DeadArgumentElimination.h" 62 #include "llvm/Transforms/IPO/ElimAvailExtern.h" 63 #include "llvm/Transforms/IPO/ForceFunctionAttrs.h" 64 #include "llvm/Transforms/IPO/FunctionAttrs.h" 65 #include "llvm/Transforms/IPO/GlobalDCE.h" 66 #include "llvm/Transforms/IPO/GlobalOpt.h" 67 #include "llvm/Transforms/IPO/InferFunctionAttrs.h" 68 #include "llvm/Transforms/IPO/Internalize.h" 69 #include "llvm/Transforms/IPO/LowerTypeTests.h" 70 #include "llvm/Transforms/IPO/PartialInlining.h" 71 #include "llvm/Transforms/IPO/SCCP.h" 72 #include "llvm/Transforms/IPO/StripDeadPrototypes.h" 73 #include "llvm/Transforms/IPO/WholeProgramDevirt.h" 74 #include "llvm/Transforms/InstCombine/InstCombine.h" 75 #include "llvm/Transforms/InstrProfiling.h" 76 #include "llvm/Transforms/PGOInstrumentation.h" 77 #include "llvm/Transforms/SampleProfile.h" 78 #include "llvm/Transforms/Scalar/ADCE.h" 79 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" 80 #include "llvm/Transforms/Scalar/BDCE.h" 81 #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" 82 #include "llvm/Transforms/Scalar/DCE.h" 83 #include "llvm/Transforms/Scalar/ConstantHoisting.h" 84 #include "llvm/Transforms/Scalar/DeadStoreElimination.h" 85 #include "llvm/Transforms/Scalar/EarlyCSE.h" 86 #include "llvm/Transforms/Scalar/Float2Int.h" 87 #include "llvm/Transforms/Scalar/GVN.h" 88 #include "llvm/Transforms/Scalar/GuardWidening.h" 89 #include "llvm/Transforms/Scalar/IndVarSimplify.h" 90 #include "llvm/Transforms/Scalar/JumpThreading.h" 91 #include "llvm/Transforms/Scalar/LICM.h" 92 #include "llvm/Transforms/Scalar/LoopDeletion.h" 93 #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h" 94 #include "llvm/Transforms/Scalar/LoopRotation.h" 95 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" 96 #include "llvm/Transforms/Scalar/LowerAtomic.h" 97 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" 98 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h" 99 #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h" 100 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h" 101 #include "llvm/Transforms/Scalar/Reassociate.h" 102 #include "llvm/Transforms/Scalar/SCCP.h" 103 #include "llvm/Transforms/Scalar/SROA.h" 104 #include "llvm/Transforms/Scalar/SimplifyCFG.h" 105 #include "llvm/Transforms/Scalar/Sink.h" 106 #include "llvm/Transforms/Scalar/TailRecursionElimination.h" 107 #include "llvm/Transforms/Utils/AddDiscriminators.h" 108 #include "llvm/Transforms/Utils/LCSSA.h" 109 #include "llvm/Transforms/Utils/LoopSimplify.h" 110 #include "llvm/Transforms/Utils/Mem2Reg.h" 111 #include "llvm/Transforms/Utils/MemorySSA.h" 112 #include "llvm/Transforms/Utils/SimplifyInstructions.h" 113 #include "llvm/Transforms/Vectorize/LoopVectorize.h" 114 #include "llvm/Transforms/Vectorize/SLPVectorizer.h" 115 116 #include <type_traits> 117 118 using namespace llvm; 119 120 static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$"); 121 122 namespace { 123 124 /// \brief No-op module pass which does nothing. 125 struct NoOpModulePass { 126 PreservedAnalyses run(Module &M, AnalysisManager<Module> &) { 127 return PreservedAnalyses::all(); 128 } 129 static StringRef name() { return "NoOpModulePass"; } 130 }; 131 132 /// \brief No-op module analysis. 133 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> { 134 friend AnalysisInfoMixin<NoOpModuleAnalysis>; 135 static char PassID; 136 137 public: 138 struct Result {}; 139 Result run(Module &, AnalysisManager<Module> &) { return Result(); } 140 static StringRef name() { return "NoOpModuleAnalysis"; } 141 }; 142 143 /// \brief No-op CGSCC pass which does nothing. 144 struct NoOpCGSCCPass { 145 PreservedAnalyses run(LazyCallGraph::SCC &C, 146 AnalysisManager<LazyCallGraph::SCC> &) { 147 return PreservedAnalyses::all(); 148 } 149 static StringRef name() { return "NoOpCGSCCPass"; } 150 }; 151 152 /// \brief No-op CGSCC analysis. 153 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> { 154 friend AnalysisInfoMixin<NoOpCGSCCAnalysis>; 155 static char PassID; 156 157 public: 158 struct Result {}; 159 Result run(LazyCallGraph::SCC &, AnalysisManager<LazyCallGraph::SCC> &) { 160 return Result(); 161 } 162 static StringRef name() { return "NoOpCGSCCAnalysis"; } 163 }; 164 165 /// \brief No-op function pass which does nothing. 166 struct NoOpFunctionPass { 167 PreservedAnalyses run(Function &F, AnalysisManager<Function> &) { 168 return PreservedAnalyses::all(); 169 } 170 static StringRef name() { return "NoOpFunctionPass"; } 171 }; 172 173 /// \brief No-op function analysis. 174 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> { 175 friend AnalysisInfoMixin<NoOpFunctionAnalysis>; 176 static char PassID; 177 178 public: 179 struct Result {}; 180 Result run(Function &, AnalysisManager<Function> &) { return Result(); } 181 static StringRef name() { return "NoOpFunctionAnalysis"; } 182 }; 183 184 /// \brief No-op loop pass which does nothing. 185 struct NoOpLoopPass { 186 PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &) { 187 return PreservedAnalyses::all(); 188 } 189 static StringRef name() { return "NoOpLoopPass"; } 190 }; 191 192 /// \brief No-op loop analysis. 193 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> { 194 friend AnalysisInfoMixin<NoOpLoopAnalysis>; 195 static char PassID; 196 197 public: 198 struct Result {}; 199 Result run(Loop &, AnalysisManager<Loop> &) { return Result(); } 200 static StringRef name() { return "NoOpLoopAnalysis"; } 201 }; 202 203 char NoOpModuleAnalysis::PassID; 204 char NoOpCGSCCAnalysis::PassID; 205 char NoOpFunctionAnalysis::PassID; 206 char NoOpLoopAnalysis::PassID; 207 208 } // End anonymous namespace. 209 210 void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) { 211 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \ 212 MAM.registerPass([&] { return CREATE_PASS; }); 213 #include "PassRegistry.def" 214 } 215 216 void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) { 217 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ 218 CGAM.registerPass([&] { return CREATE_PASS; }); 219 #include "PassRegistry.def" 220 } 221 222 void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) { 223 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ 224 FAM.registerPass([&] { return CREATE_PASS; }); 225 #include "PassRegistry.def" 226 } 227 228 void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) { 229 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ 230 LAM.registerPass([&] { return CREATE_PASS; }); 231 #include "PassRegistry.def" 232 } 233 234 void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM, 235 OptimizationLevel Level, 236 bool DebugLogging) { 237 // FIXME: Finish fleshing this out to match the legacy pipelines. 238 FunctionPassManager EarlyFPM(DebugLogging); 239 EarlyFPM.addPass(SimplifyCFGPass()); 240 EarlyFPM.addPass(SROA()); 241 EarlyFPM.addPass(EarlyCSEPass()); 242 EarlyFPM.addPass(LowerExpectIntrinsicPass()); 243 244 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM))); 245 } 246 247 void PassBuilder::addLTOPreLinkDefaultPipeline(ModulePassManager &MPM, 248 OptimizationLevel Level, 249 bool DebugLogging) { 250 // FIXME: We should use a customized pre-link pipeline! 251 addPerModuleDefaultPipeline(MPM, Level, DebugLogging); 252 } 253 254 void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM, 255 OptimizationLevel Level, 256 bool DebugLogging) { 257 // FIXME: Finish fleshing this out to match the legacy LTO pipelines. 258 FunctionPassManager LateFPM(DebugLogging); 259 LateFPM.addPass(InstCombinePass()); 260 LateFPM.addPass(SimplifyCFGPass()); 261 262 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM))); 263 } 264 265 #ifndef NDEBUG 266 static bool isModulePassName(StringRef Name) { 267 // Manually handle aliases for pre-configured pipeline fragments. 268 if (Name.startswith("default") || Name.startswith("lto")) 269 return DefaultAliasRegex.match(Name); 270 271 #define MODULE_PASS(NAME, CREATE_PASS) \ 272 if (Name == NAME) \ 273 return true; 274 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \ 275 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ 276 return true; 277 #include "PassRegistry.def" 278 279 return false; 280 } 281 #endif 282 283 static bool isCGSCCPassName(StringRef Name) { 284 #define CGSCC_PASS(NAME, CREATE_PASS) \ 285 if (Name == NAME) \ 286 return true; 287 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ 288 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ 289 return true; 290 #include "PassRegistry.def" 291 292 return false; 293 } 294 295 static bool isFunctionPassName(StringRef Name) { 296 #define FUNCTION_PASS(NAME, CREATE_PASS) \ 297 if (Name == NAME) \ 298 return true; 299 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ 300 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ 301 return true; 302 #include "PassRegistry.def" 303 304 return false; 305 } 306 307 static bool isLoopPassName(StringRef Name) { 308 #define LOOP_PASS(NAME, CREATE_PASS) \ 309 if (Name == NAME) \ 310 return true; 311 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ 312 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ 313 return true; 314 #include "PassRegistry.def" 315 316 return false; 317 } 318 319 bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name, 320 bool DebugLogging) { 321 // Manually handle aliases for pre-configured pipeline fragments. 322 if (Name.startswith("default") || Name.startswith("lto")) { 323 SmallVector<StringRef, 3> Matches; 324 if (!DefaultAliasRegex.match(Name, &Matches)) 325 return false; 326 assert(Matches.size() == 3 && "Must capture two matched strings!"); 327 328 auto L = StringSwitch<OptimizationLevel>(Matches[2]) 329 .Case("O0", O0) 330 .Case("O1", O1) 331 .Case("O2", O2) 332 .Case("O3", O3) 333 .Case("Os", Os) 334 .Case("Oz", Oz); 335 336 if (Matches[1] == "default") { 337 addPerModuleDefaultPipeline(MPM, L, DebugLogging); 338 } else if (Matches[1] == "lto-pre-link") { 339 addLTOPreLinkDefaultPipeline(MPM, L, DebugLogging); 340 } else { 341 assert(Matches[1] == "lto" && "Not one of the matched options!"); 342 addLTODefaultPipeline(MPM, L, DebugLogging); 343 } 344 return true; 345 } 346 347 #define MODULE_PASS(NAME, CREATE_PASS) \ 348 if (Name == NAME) { \ 349 MPM.addPass(CREATE_PASS); \ 350 return true; \ 351 } 352 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \ 353 if (Name == "require<" NAME ">") { \ 354 MPM.addPass(RequireAnalysisPass< \ 355 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 356 return true; \ 357 } \ 358 if (Name == "invalidate<" NAME ">") { \ 359 MPM.addPass(InvalidateAnalysisPass< \ 360 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 361 return true; \ 362 } 363 #include "PassRegistry.def" 364 365 return false; 366 } 367 368 bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { 369 #define CGSCC_PASS(NAME, CREATE_PASS) \ 370 if (Name == NAME) { \ 371 CGPM.addPass(CREATE_PASS); \ 372 return true; \ 373 } 374 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ 375 if (Name == "require<" NAME ">") { \ 376 CGPM.addPass(RequireAnalysisPass< \ 377 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 378 return true; \ 379 } \ 380 if (Name == "invalidate<" NAME ">") { \ 381 CGPM.addPass(InvalidateAnalysisPass< \ 382 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 383 return true; \ 384 } 385 #include "PassRegistry.def" 386 387 return false; 388 } 389 390 bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM, 391 StringRef Name) { 392 #define FUNCTION_PASS(NAME, CREATE_PASS) \ 393 if (Name == NAME) { \ 394 FPM.addPass(CREATE_PASS); \ 395 return true; \ 396 } 397 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ 398 if (Name == "require<" NAME ">") { \ 399 FPM.addPass(RequireAnalysisPass< \ 400 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 401 return true; \ 402 } \ 403 if (Name == "invalidate<" NAME ">") { \ 404 FPM.addPass(InvalidateAnalysisPass< \ 405 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 406 return true; \ 407 } 408 #include "PassRegistry.def" 409 410 return false; 411 } 412 413 bool PassBuilder::parseLoopPassName(LoopPassManager &FPM, StringRef Name) { 414 #define LOOP_PASS(NAME, CREATE_PASS) \ 415 if (Name == NAME) { \ 416 FPM.addPass(CREATE_PASS); \ 417 return true; \ 418 } 419 #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ 420 if (Name == "require<" NAME ">") { \ 421 FPM.addPass(RequireAnalysisPass< \ 422 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 423 return true; \ 424 } \ 425 if (Name == "invalidate<" NAME ">") { \ 426 FPM.addPass(InvalidateAnalysisPass< \ 427 std::remove_reference<decltype(CREATE_PASS)>::type>()); \ 428 return true; \ 429 } 430 #include "PassRegistry.def" 431 432 return false; 433 } 434 435 bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) { 436 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ 437 if (Name == NAME) { \ 438 AA.registerModuleAnalysis< \ 439 std::remove_reference<decltype(CREATE_PASS)>::type>(); \ 440 return true; \ 441 } 442 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \ 443 if (Name == NAME) { \ 444 AA.registerFunctionAnalysis< \ 445 std::remove_reference<decltype(CREATE_PASS)>::type>(); \ 446 return true; \ 447 } 448 #include "PassRegistry.def" 449 450 return false; 451 } 452 453 bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM, 454 StringRef &PipelineText, 455 bool VerifyEachPass, 456 bool DebugLogging) { 457 for (;;) { 458 // Parse nested pass managers by recursing. 459 if (PipelineText.startswith("loop(")) { 460 LoopPassManager NestedLPM(DebugLogging); 461 462 // Parse the inner pipeline inte the nested manager. 463 PipelineText = PipelineText.substr(strlen("loop(")); 464 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, 465 DebugLogging) || 466 PipelineText.empty()) 467 return false; 468 assert(PipelineText[0] == ')'); 469 PipelineText = PipelineText.substr(1); 470 471 // Add the nested pass manager with the appropriate adaptor. 472 LPM.addPass(std::move(NestedLPM)); 473 } else { 474 // Otherwise try to parse a pass name. 475 size_t End = PipelineText.find_first_of(",)"); 476 if (!parseLoopPassName(LPM, PipelineText.substr(0, End))) 477 return false; 478 // TODO: Ideally, we would run a LoopVerifierPass() here in the 479 // VerifyEachPass case, but we don't have such a verifier yet. 480 481 PipelineText = PipelineText.substr(End); 482 } 483 484 if (PipelineText.empty() || PipelineText[0] == ')') 485 return true; 486 487 assert(PipelineText[0] == ','); 488 PipelineText = PipelineText.substr(1); 489 } 490 } 491 492 bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, 493 StringRef &PipelineText, 494 bool VerifyEachPass, 495 bool DebugLogging) { 496 for (;;) { 497 // Parse nested pass managers by recursing. 498 if (PipelineText.startswith("function(")) { 499 FunctionPassManager NestedFPM(DebugLogging); 500 501 // Parse the inner pipeline inte the nested manager. 502 PipelineText = PipelineText.substr(strlen("function(")); 503 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, 504 DebugLogging) || 505 PipelineText.empty()) 506 return false; 507 assert(PipelineText[0] == ')'); 508 PipelineText = PipelineText.substr(1); 509 510 // Add the nested pass manager with the appropriate adaptor. 511 FPM.addPass(std::move(NestedFPM)); 512 } else if (PipelineText.startswith("loop(")) { 513 LoopPassManager NestedLPM(DebugLogging); 514 515 // Parse the inner pipeline inte the nested manager. 516 PipelineText = PipelineText.substr(strlen("loop(")); 517 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, 518 DebugLogging) || 519 PipelineText.empty()) 520 return false; 521 assert(PipelineText[0] == ')'); 522 PipelineText = PipelineText.substr(1); 523 524 // Add the nested pass manager with the appropriate adaptor. 525 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM))); 526 } else { 527 // Otherwise try to parse a pass name. 528 size_t End = PipelineText.find_first_of(",)"); 529 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End))) 530 return false; 531 if (VerifyEachPass) 532 FPM.addPass(VerifierPass()); 533 534 PipelineText = PipelineText.substr(End); 535 } 536 537 if (PipelineText.empty() || PipelineText[0] == ')') 538 return true; 539 540 assert(PipelineText[0] == ','); 541 PipelineText = PipelineText.substr(1); 542 } 543 } 544 545 bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, 546 StringRef &PipelineText, 547 bool VerifyEachPass, 548 bool DebugLogging) { 549 for (;;) { 550 // Parse nested pass managers by recursing. 551 if (PipelineText.startswith("cgscc(")) { 552 CGSCCPassManager NestedCGPM(DebugLogging); 553 554 // Parse the inner pipeline into the nested manager. 555 PipelineText = PipelineText.substr(strlen("cgscc(")); 556 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass, 557 DebugLogging) || 558 PipelineText.empty()) 559 return false; 560 assert(PipelineText[0] == ')'); 561 PipelineText = PipelineText.substr(1); 562 563 // Add the nested pass manager with the appropriate adaptor. 564 CGPM.addPass(std::move(NestedCGPM)); 565 } else if (PipelineText.startswith("function(")) { 566 FunctionPassManager NestedFPM(DebugLogging); 567 568 // Parse the inner pipeline inte the nested manager. 569 PipelineText = PipelineText.substr(strlen("function(")); 570 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, 571 DebugLogging) || 572 PipelineText.empty()) 573 return false; 574 assert(PipelineText[0] == ')'); 575 PipelineText = PipelineText.substr(1); 576 577 // Add the nested pass manager with the appropriate adaptor. 578 CGPM.addPass( 579 createCGSCCToFunctionPassAdaptor(std::move(NestedFPM), DebugLogging)); 580 } else { 581 // Otherwise try to parse a pass name. 582 size_t End = PipelineText.find_first_of(",)"); 583 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End))) 584 return false; 585 // FIXME: No verifier support for CGSCC passes! 586 587 PipelineText = PipelineText.substr(End); 588 } 589 590 if (PipelineText.empty() || PipelineText[0] == ')') 591 return true; 592 593 assert(PipelineText[0] == ','); 594 PipelineText = PipelineText.substr(1); 595 } 596 } 597 598 void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM, 599 FunctionAnalysisManager &FAM, 600 CGSCCAnalysisManager &CGAM, 601 ModuleAnalysisManager &MAM) { 602 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); 603 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); }); 604 CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(FAM); }); 605 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); }); 606 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); }); 607 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); 608 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); }); 609 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); }); 610 } 611 612 bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM, 613 StringRef &PipelineText, 614 bool VerifyEachPass, 615 bool DebugLogging) { 616 for (;;) { 617 // Parse nested pass managers by recursing. 618 if (PipelineText.startswith("module(")) { 619 ModulePassManager NestedMPM(DebugLogging); 620 621 // Parse the inner pipeline into the nested manager. 622 PipelineText = PipelineText.substr(strlen("module(")); 623 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass, 624 DebugLogging) || 625 PipelineText.empty()) 626 return false; 627 assert(PipelineText[0] == ')'); 628 PipelineText = PipelineText.substr(1); 629 630 // Now add the nested manager as a module pass. 631 MPM.addPass(std::move(NestedMPM)); 632 } else if (PipelineText.startswith("cgscc(")) { 633 CGSCCPassManager NestedCGPM(DebugLogging); 634 635 // Parse the inner pipeline inte the nested manager. 636 PipelineText = PipelineText.substr(strlen("cgscc(")); 637 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass, 638 DebugLogging) || 639 PipelineText.empty()) 640 return false; 641 assert(PipelineText[0] == ')'); 642 PipelineText = PipelineText.substr(1); 643 644 // Add the nested pass manager with the appropriate adaptor. 645 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM), 646 DebugLogging)); 647 } else if (PipelineText.startswith("function(")) { 648 FunctionPassManager NestedFPM(DebugLogging); 649 650 // Parse the inner pipeline inte the nested manager. 651 PipelineText = PipelineText.substr(strlen("function(")); 652 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, 653 DebugLogging) || 654 PipelineText.empty()) 655 return false; 656 assert(PipelineText[0] == ')'); 657 PipelineText = PipelineText.substr(1); 658 659 // Add the nested pass manager with the appropriate adaptor. 660 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM))); 661 } else { 662 // Otherwise try to parse a pass name. 663 size_t End = PipelineText.find_first_of(",)"); 664 if (!parseModulePassName(MPM, PipelineText.substr(0, End), DebugLogging)) 665 return false; 666 if (VerifyEachPass) 667 MPM.addPass(VerifierPass()); 668 669 PipelineText = PipelineText.substr(End); 670 } 671 672 if (PipelineText.empty() || PipelineText[0] == ')') 673 return true; 674 675 assert(PipelineText[0] == ','); 676 PipelineText = PipelineText.substr(1); 677 } 678 } 679 680 // Primary pass pipeline description parsing routine. 681 // FIXME: Should this routine accept a TargetMachine or require the caller to 682 // pre-populate the analysis managers with target-specific stuff? 683 bool PassBuilder::parsePassPipeline(ModulePassManager &MPM, 684 StringRef PipelineText, bool VerifyEachPass, 685 bool DebugLogging) { 686 // By default, try to parse the pipeline as-if it were within an implicit 687 // 'module(...)' pass pipeline. If this will parse at all, it needs to 688 // consume the entire string. 689 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging)) 690 return PipelineText.empty(); 691 692 // This isn't parsable as a module pipeline, look for the end of a pass name 693 // and directly drop down to that layer. 694 StringRef FirstName = 695 PipelineText.substr(0, PipelineText.find_first_of(",)")); 696 assert(!isModulePassName(FirstName) && 697 "Already handled all module pipeline options."); 698 699 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC 700 // pipeline. 701 if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) { 702 CGSCCPassManager CGPM(DebugLogging); 703 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass, 704 DebugLogging) || 705 !PipelineText.empty()) 706 return false; 707 MPM.addPass( 708 createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM), DebugLogging)); 709 return true; 710 } 711 712 // Similarly, if this looks like a Function pass, parse the whole thing as 713 // a Function pipelien. 714 if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) { 715 FunctionPassManager FPM(DebugLogging); 716 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass, 717 DebugLogging) || 718 !PipelineText.empty()) 719 return false; 720 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 721 return true; 722 } 723 724 // If this looks like a Loop pass, parse the whole thing as a Loop pipeline. 725 if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) { 726 LoopPassManager LPM(DebugLogging); 727 if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass, 728 DebugLogging) || 729 !PipelineText.empty()) 730 return false; 731 FunctionPassManager FPM(DebugLogging); 732 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM))); 733 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 734 return true; 735 } 736 737 return false; 738 } 739 740 bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) { 741 while (!PipelineText.empty()) { 742 StringRef Name; 743 std::tie(Name, PipelineText) = PipelineText.split(','); 744 if (!parseAAPassName(AA, Name)) 745 return false; 746 } 747 748 return true; 749 } 750