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