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 118using namespace llvm; 119 120static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$"); 121 122namespace { 123 124/// \brief No-op module pass which does nothing. 125struct 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. 133class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> { 134 friend AnalysisInfoMixin<NoOpModuleAnalysis>; 135 static char PassID; 136 137public: 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. 144struct 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. 153class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> { 154 friend AnalysisInfoMixin<NoOpCGSCCAnalysis>; 155 static char PassID; 156 157public: 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. 166struct 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. 174class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> { 175 friend AnalysisInfoMixin<NoOpFunctionAnalysis>; 176 static char PassID; 177 178public: 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. 185struct 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. 193class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> { 194 friend AnalysisInfoMixin<NoOpLoopAnalysis>; 195 static char PassID; 196 197public: 198 struct Result {}; 199 Result run(Loop &, AnalysisManager<Loop> &) { return Result(); } 200 static StringRef name() { return "NoOpLoopAnalysis"; } 201}; 202 203char NoOpModuleAnalysis::PassID; 204char NoOpCGSCCAnalysis::PassID; 205char NoOpFunctionAnalysis::PassID; 206char NoOpLoopAnalysis::PassID; 207 208} // End anonymous namespace. 209 210void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) { 211#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ 212 MAM.registerPass([&] { return CREATE_PASS; }); 213#include "PassRegistry.def" 214} 215 216void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) { 217#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ 218 CGAM.registerPass([&] { return CREATE_PASS; }); 219#include "PassRegistry.def" 220} 221 222void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) { 223#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ 224 FAM.registerPass([&] { return CREATE_PASS; }); 225#include "PassRegistry.def" 226} 227 228void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) { 229#define LOOP_ANALYSIS(NAME, CREATE_PASS) \ 230 LAM.registerPass([&] { return CREATE_PASS; }); 231#include "PassRegistry.def" 232} 233 234void 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 247void 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 254void 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 266static 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 283static 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 295static 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 307static 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 319bool 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 368bool 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 390bool 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 413bool 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 435bool 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 453bool 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 492bool 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 545bool 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 598void 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 612bool 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? 683bool 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 740bool 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