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