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