1 //===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// Interfaces for registering analysis passes, producing common pass manager 11 /// configurations, and parsing of pass pipelines. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_PASSES_PASSBUILDER_H 16 #define LLVM_PASSES_PASSBUILDER_H 17 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/Analysis/CGSCCPassManager.h" 20 #include "llvm/IR/PassManager.h" 21 #include "llvm/Support/Error.h" 22 #include "llvm/Transforms/IPO/Inliner.h" 23 #include "llvm/Transforms/Instrumentation.h" 24 #include "llvm/Transforms/Scalar/LoopPassManager.h" 25 #include <vector> 26 27 namespace llvm { 28 class StringRef; 29 class AAManager; 30 class TargetMachine; 31 class ModuleSummaryIndex; 32 33 /// A struct capturing PGO tunables. 34 struct PGOOptions { 35 enum PGOAction { NoAction, IRInstr, IRUse, SampleUse }; 36 enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse }; 37 PGOOptions(std::string ProfileFile = "", std::string CSProfileGenFile = "", 38 std::string ProfileRemappingFile = "", PGOAction Action = NoAction, 39 CSPGOAction CSAction = NoCSAction, bool SamplePGOSupport = false) 40 : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile), 41 ProfileRemappingFile(ProfileRemappingFile), Action(Action), 42 CSAction(CSAction), 43 SamplePGOSupport(SamplePGOSupport || Action == SampleUse) { 44 // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can 45 // callback with IRUse action without ProfileFile. 46 47 // If there is a CSAction, PGOAction cannot be IRInstr or SampleUse. 48 assert(this->CSAction == NoCSAction || 49 (this->Action != IRInstr && this->Action != SampleUse)); 50 51 // For CSIRInstr, CSProfileGenFile also needs to be nonempty. 52 assert(this->CSAction != CSIRInstr || !this->CSProfileGenFile.empty()); 53 54 // If CSAction is CSIRUse, PGOAction needs to be IRUse as they share 55 // a profile. 56 assert(this->CSAction != CSIRUse || this->Action == IRUse); 57 58 // If neither Action nor CSAction, SamplePGOSupport needs to be true. 59 assert(this->Action != NoAction || this->CSAction != NoCSAction || 60 this->SamplePGOSupport); 61 } 62 std::string ProfileFile; 63 std::string CSProfileGenFile; 64 std::string ProfileRemappingFile; 65 PGOAction Action; 66 CSPGOAction CSAction; 67 bool SamplePGOSupport; 68 }; 69 70 /// Tunable parameters for passes in the default pipelines. 71 class PipelineTuningOptions { 72 public: 73 /// Constructor sets pipeline tuning defaults based on cl::opts. Each option 74 /// can be set in the PassBuilder when using a LLVM as a library. 75 PipelineTuningOptions(); 76 77 /// Tuning option to set loop interleaving on/off, set based on opt level. 78 bool LoopInterleaving; 79 80 /// Tuning option to enable/disable loop vectorization, set based on opt 81 /// level. 82 bool LoopVectorization; 83 84 /// Tuning option to enable/disable slp loop vectorization, set based on opt 85 /// level. 86 bool SLPVectorization; 87 88 /// Tuning option to enable/disable loop unrolling. Its default value is true. 89 bool LoopUnrolling; 90 91 /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value 92 /// is that of the flag: `-forget-scev-loop-unroll`. 93 bool ForgetAllSCEVInLoopUnroll; 94 95 /// Tuning option to enable/disable coroutine intrinsic lowering. Its default 96 /// value is false. Frontends such as Clang may enable this conditionally. For 97 /// example, Clang enables this option if the flags `-std=c++2a` or above, or 98 /// `-fcoroutines-ts`, have been specified. 99 bool Coroutines; 100 101 /// Tuning option to cap the number of calls to retrive clobbering accesses in 102 /// MemorySSA, in LICM. 103 unsigned LicmMssaOptCap; 104 105 /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if 106 /// the number of access is too large. 107 unsigned LicmMssaNoAccForPromotionCap; 108 109 /// Tuning option to enable/disable call graph profile. Its default value is 110 /// that of the flag: `-enable-npm-call-graph-profile`. 111 bool CallGraphProfile; 112 }; 113 114 /// This class provides access to building LLVM's passes. 115 /// 116 /// Its members provide the baseline state available to passes during their 117 /// construction. The \c PassRegistry.def file specifies how to construct all 118 /// of the built-in passes, and those may reference these members during 119 /// construction. 120 class PassBuilder { 121 TargetMachine *TM; 122 PipelineTuningOptions PTO; 123 Optional<PGOOptions> PGOOpt; 124 PassInstrumentationCallbacks *PIC; 125 126 public: 127 /// A struct to capture parsed pass pipeline names. 128 /// 129 /// A pipeline is defined as a series of names, each of which may in itself 130 /// recursively contain a nested pipeline. A name is either the name of a pass 131 /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the 132 /// name is the name of a pass, the InnerPipeline is empty, since passes 133 /// cannot contain inner pipelines. See parsePassPipeline() for a more 134 /// detailed description of the textual pipeline format. 135 struct PipelineElement { 136 StringRef Name; 137 std::vector<PipelineElement> InnerPipeline; 138 }; 139 140 /// ThinLTO phase. 141 /// 142 /// This enumerates the LLVM ThinLTO optimization phases. 143 enum class ThinLTOPhase { 144 /// No ThinLTO behavior needed. 145 None, 146 /// ThinLTO prelink (summary) phase. 147 PreLink, 148 /// ThinLTO postlink (backend compile) phase. 149 PostLink 150 }; 151 152 /// LLVM-provided high-level optimization levels. 153 /// 154 /// This enumerates the LLVM-provided high-level optimization levels. Each 155 /// level has a specific goal and rationale. 156 class OptimizationLevel final { 157 unsigned SpeedLevel = 2; 158 unsigned SizeLevel = 0; 159 OptimizationLevel(unsigned SpeedLevel, unsigned SizeLevel) 160 : SpeedLevel(SpeedLevel), SizeLevel(SizeLevel) { 161 // Check that only valid combinations are passed. 162 assert(SpeedLevel <= 3 && 163 "Optimization level for speed should be 0, 1, 2, or 3"); 164 assert(SizeLevel <= 2 && 165 "Optimization level for size should be 0, 1, or 2"); 166 assert((SizeLevel == 0 || SpeedLevel == 2) && 167 "Optimize for size should be encoded with speedup level == 2"); 168 } 169 170 public: 171 OptimizationLevel() = default; 172 /// Disable as many optimizations as possible. This doesn't completely 173 /// disable the optimizer in all cases, for example always_inline functions 174 /// can be required to be inlined for correctness. 175 static const OptimizationLevel O0; 176 177 /// Optimize quickly without destroying debuggability. 178 /// 179 /// This level is tuned to produce a result from the optimizer as quickly 180 /// as possible and to avoid destroying debuggability. This tends to result 181 /// in a very good development mode where the compiled code will be 182 /// immediately executed as part of testing. As a consequence, where 183 /// possible, we would like to produce efficient-to-execute code, but not 184 /// if it significantly slows down compilation or would prevent even basic 185 /// debugging of the resulting binary. 186 /// 187 /// As an example, complex loop transformations such as versioning, 188 /// vectorization, or fusion don't make sense here due to the degree to 189 /// which the executed code differs from the source code, and the compile 190 /// time cost. 191 static const OptimizationLevel O1; 192 /// Optimize for fast execution as much as possible without triggering 193 /// significant incremental compile time or code size growth. 194 /// 195 /// The key idea is that optimizations at this level should "pay for 196 /// themselves". So if an optimization increases compile time by 5% or 197 /// increases code size by 5% for a particular benchmark, that benchmark 198 /// should also be one which sees a 5% runtime improvement. If the compile 199 /// time or code size penalties happen on average across a diverse range of 200 /// LLVM users' benchmarks, then the improvements should as well. 201 /// 202 /// And no matter what, the compile time needs to not grow superlinearly 203 /// with the size of input to LLVM so that users can control the runtime of 204 /// the optimizer in this mode. 205 /// 206 /// This is expected to be a good default optimization level for the vast 207 /// majority of users. 208 static const OptimizationLevel O2; 209 /// Optimize for fast execution as much as possible. 210 /// 211 /// This mode is significantly more aggressive in trading off compile time 212 /// and code size to get execution time improvements. The core idea is that 213 /// this mode should include any optimization that helps execution time on 214 /// balance across a diverse collection of benchmarks, even if it increases 215 /// code size or compile time for some benchmarks without corresponding 216 /// improvements to execution time. 217 /// 218 /// Despite being willing to trade more compile time off to get improved 219 /// execution time, this mode still tries to avoid superlinear growth in 220 /// order to make even significantly slower compile times at least scale 221 /// reasonably. This does not preclude very substantial constant factor 222 /// costs though. 223 static const OptimizationLevel O3; 224 /// Similar to \c O2 but tries to optimize for small code size instead of 225 /// fast execution without triggering significant incremental execution 226 /// time slowdowns. 227 /// 228 /// The logic here is exactly the same as \c O2, but with code size and 229 /// execution time metrics swapped. 230 /// 231 /// A consequence of the different core goal is that this should in general 232 /// produce substantially smaller executables that still run in 233 /// a reasonable amount of time. 234 static const OptimizationLevel Os; 235 /// A very specialized mode that will optimize for code size at any and all 236 /// costs. 237 /// 238 /// This is useful primarily when there are absolute size limitations and 239 /// any effort taken to reduce the size is worth it regardless of the 240 /// execution time impact. You should expect this level to produce rather 241 /// slow, but very small, code. 242 static const OptimizationLevel Oz; 243 244 bool isOptimizingForSpeed() const { 245 return SizeLevel == 0 && SpeedLevel > 0; 246 } 247 248 bool isOptimizingForSize() const { return SizeLevel > 0; } 249 250 bool operator==(const OptimizationLevel &Other) const { 251 return SizeLevel == Other.SizeLevel && SpeedLevel == Other.SpeedLevel; 252 } 253 bool operator!=(const OptimizationLevel &Other) const { 254 return SizeLevel != Other.SizeLevel || SpeedLevel != Other.SpeedLevel; 255 } 256 257 unsigned getSpeedupLevel() const { return SpeedLevel; } 258 259 unsigned getSizeLevel() const { return SizeLevel; } 260 }; 261 262 explicit PassBuilder(TargetMachine *TM = nullptr, 263 PipelineTuningOptions PTO = PipelineTuningOptions(), 264 Optional<PGOOptions> PGOOpt = None, 265 PassInstrumentationCallbacks *PIC = nullptr) 266 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {} 267 268 /// Cross register the analysis managers through their proxies. 269 /// 270 /// This is an interface that can be used to cross register each 271 /// AnalysisManager with all the others analysis managers. 272 void crossRegisterProxies(LoopAnalysisManager &LAM, 273 FunctionAnalysisManager &FAM, 274 CGSCCAnalysisManager &CGAM, 275 ModuleAnalysisManager &MAM); 276 277 /// Registers all available module analysis passes. 278 /// 279 /// This is an interface that can be used to populate a \c 280 /// ModuleAnalysisManager with all registered module analyses. Callers can 281 /// still manually register any additional analyses. Callers can also 282 /// pre-register analyses and this will not override those. 283 void registerModuleAnalyses(ModuleAnalysisManager &MAM); 284 285 /// Registers all available CGSCC analysis passes. 286 /// 287 /// This is an interface that can be used to populate a \c CGSCCAnalysisManager 288 /// with all registered CGSCC analyses. Callers can still manually register any 289 /// additional analyses. Callers can also pre-register analyses and this will 290 /// not override those. 291 void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM); 292 293 /// Registers all available function analysis passes. 294 /// 295 /// This is an interface that can be used to populate a \c 296 /// FunctionAnalysisManager with all registered function analyses. Callers can 297 /// still manually register any additional analyses. Callers can also 298 /// pre-register analyses and this will not override those. 299 void registerFunctionAnalyses(FunctionAnalysisManager &FAM); 300 301 /// Registers all available loop analysis passes. 302 /// 303 /// This is an interface that can be used to populate a \c LoopAnalysisManager 304 /// with all registered loop analyses. Callers can still manually register any 305 /// additional analyses. 306 void registerLoopAnalyses(LoopAnalysisManager &LAM); 307 308 /// Construct the core LLVM function canonicalization and simplification 309 /// pipeline. 310 /// 311 /// This is a long pipeline and uses most of the per-function optimization 312 /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run 313 /// repeatedly over the IR and is not expected to destroy important 314 /// information about the semantics of the IR. 315 /// 316 /// Note that \p Level cannot be `O0` here. The pipelines produced are 317 /// only intended for use when attempting to optimize code. If frontends 318 /// require some transformations for semantic reasons, they should explicitly 319 /// build them. 320 /// 321 /// \p Phase indicates the current ThinLTO phase. 322 FunctionPassManager 323 buildFunctionSimplificationPipeline(OptimizationLevel Level, 324 ThinLTOPhase Phase, 325 bool DebugLogging = false); 326 327 /// Construct the core LLVM module canonicalization and simplification 328 /// pipeline. 329 /// 330 /// This pipeline focuses on canonicalizing and simplifying the entire module 331 /// of IR. Much like the function simplification pipeline above, it is 332 /// suitable to run repeatedly over the IR and is not expected to destroy 333 /// important information. It does, however, perform inlining and other 334 /// heuristic based simplifications that are not strictly reversible. 335 /// 336 /// Note that \p Level cannot be `O0` here. The pipelines produced are 337 /// only intended for use when attempting to optimize code. If frontends 338 /// require some transformations for semantic reasons, they should explicitly 339 /// build them. 340 /// 341 /// \p Phase indicates the current ThinLTO phase. 342 ModulePassManager 343 buildModuleSimplificationPipeline(OptimizationLevel Level, 344 ThinLTOPhase Phase, 345 bool DebugLogging = false); 346 347 /// Construct the module pipeline that performs inlining as well as 348 /// the inlining-driven cleanups. 349 ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level, 350 ThinLTOPhase Phase, 351 bool DebugLogging = false); 352 353 /// Construct the core LLVM module optimization pipeline. 354 /// 355 /// This pipeline focuses on optimizing the execution speed of the IR. It 356 /// uses cost modeling and thresholds to balance code growth against runtime 357 /// improvements. It includes vectorization and other information destroying 358 /// transformations. It also cannot generally be run repeatedly on a module 359 /// without potentially seriously regressing either runtime performance of 360 /// the code or serious code size growth. 361 /// 362 /// Note that \p Level cannot be `O0` here. The pipelines produced are 363 /// only intended for use when attempting to optimize code. If frontends 364 /// require some transformations for semantic reasons, they should explicitly 365 /// build them. 366 ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level, 367 bool DebugLogging = false, 368 bool LTOPreLink = false); 369 370 /// Build a per-module default optimization pipeline. 371 /// 372 /// This provides a good default optimization pipeline for per-module 373 /// optimization and code generation without any link-time optimization. It 374 /// typically correspond to frontend "-O[123]" options for optimization 375 /// levels \c O1, \c O2 and \c O3 resp. 376 /// 377 /// Note that \p Level cannot be `O0` here. The pipelines produced are 378 /// only intended for use when attempting to optimize code. If frontends 379 /// require some transformations for semantic reasons, they should explicitly 380 /// build them. 381 ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level, 382 bool DebugLogging = false, 383 bool LTOPreLink = false); 384 385 /// Build a pre-link, ThinLTO-targeting default optimization pipeline to 386 /// a pass manager. 387 /// 388 /// This adds the pre-link optimizations tuned to prepare a module for 389 /// a ThinLTO run. It works to minimize the IR which needs to be analyzed 390 /// without making irreversible decisions which could be made better during 391 /// the LTO run. 392 /// 393 /// Note that \p Level cannot be `O0` here. The pipelines produced are 394 /// only intended for use when attempting to optimize code. If frontends 395 /// require some transformations for semantic reasons, they should explicitly 396 /// build them. 397 ModulePassManager 398 buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level, 399 bool DebugLogging = false); 400 401 /// Build an ThinLTO default optimization pipeline to a pass manager. 402 /// 403 /// This provides a good default optimization pipeline for link-time 404 /// optimization and code generation. It is particularly tuned to fit well 405 /// when IR coming into the LTO phase was first run through \c 406 /// addPreLinkLTODefaultPipeline, and the two coordinate closely. 407 /// 408 /// Note that \p Level cannot be `O0` here. The pipelines produced are 409 /// only intended for use when attempting to optimize code. If frontends 410 /// require some transformations for semantic reasons, they should explicitly 411 /// build them. 412 ModulePassManager 413 buildThinLTODefaultPipeline(OptimizationLevel Level, bool DebugLogging, 414 const ModuleSummaryIndex *ImportSummary); 415 416 /// Build a pre-link, LTO-targeting default optimization pipeline to a pass 417 /// manager. 418 /// 419 /// This adds the pre-link optimizations tuned to work well with a later LTO 420 /// run. It works to minimize the IR which needs to be analyzed without 421 /// making irreversible decisions which could be made better during the LTO 422 /// run. 423 /// 424 /// Note that \p Level cannot be `O0` here. The pipelines produced are 425 /// only intended for use when attempting to optimize code. If frontends 426 /// require some transformations for semantic reasons, they should explicitly 427 /// build them. 428 ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level, 429 bool DebugLogging = false); 430 431 /// Build an LTO default optimization pipeline to a pass manager. 432 /// 433 /// This provides a good default optimization pipeline for link-time 434 /// optimization and code generation. It is particularly tuned to fit well 435 /// when IR coming into the LTO phase was first run through \c 436 /// addPreLinkLTODefaultPipeline, and the two coordinate closely. 437 /// 438 /// Note that \p Level cannot be `O0` here. The pipelines produced are 439 /// only intended for use when attempting to optimize code. If frontends 440 /// require some transformations for semantic reasons, they should explicitly 441 /// build them. 442 ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level, 443 bool DebugLogging, 444 ModuleSummaryIndex *ExportSummary); 445 446 /// Build the default `AAManager` with the default alias analysis pipeline 447 /// registered. 448 AAManager buildDefaultAAPipeline(); 449 450 /// Parse a textual pass pipeline description into a \c 451 /// ModulePassManager. 452 /// 453 /// The format of the textual pass pipeline description looks something like: 454 /// 455 /// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...) 456 /// 457 /// Pass managers have ()s describing the nest structure of passes. All passes 458 /// are comma separated. As a special shortcut, if the very first pass is not 459 /// a module pass (as a module pass manager is), this will automatically form 460 /// the shortest stack of pass managers that allow inserting that first pass. 461 /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop 462 /// passes 'lpassN', all of these are valid: 463 /// 464 /// fpass1,fpass2,fpass3 465 /// cgpass1,cgpass2,cgpass3 466 /// lpass1,lpass2,lpass3 467 /// 468 /// And they are equivalent to the following (resp.): 469 /// 470 /// module(function(fpass1,fpass2,fpass3)) 471 /// module(cgscc(cgpass1,cgpass2,cgpass3)) 472 /// module(function(loop(lpass1,lpass2,lpass3))) 473 /// 474 /// This shortcut is especially useful for debugging and testing small pass 475 /// combinations. Note that these shortcuts don't introduce any other magic. 476 /// If the sequence of passes aren't all the exact same kind of pass, it will 477 /// be an error. You cannot mix different levels implicitly, you must 478 /// explicitly form a pass manager in which to nest passes. 479 Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, 480 bool VerifyEachPass = true, 481 bool DebugLogging = false); 482 483 /// {{@ Parse a textual pass pipeline description into a specific PassManager 484 /// 485 /// Automatic deduction of an appropriate pass manager stack is not supported. 486 /// For example, to insert a loop pass 'lpass' into a FunctionPassManager, 487 /// this is the valid pipeline text: 488 /// 489 /// function(lpass) 490 Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText, 491 bool VerifyEachPass = true, 492 bool DebugLogging = false); 493 Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText, 494 bool VerifyEachPass = true, 495 bool DebugLogging = false); 496 Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText, 497 bool VerifyEachPass = true, 498 bool DebugLogging = false); 499 /// @}} 500 501 /// Parse a textual alias analysis pipeline into the provided AA manager. 502 /// 503 /// The format of the textual AA pipeline is a comma separated list of AA 504 /// pass names: 505 /// 506 /// basic-aa,globals-aa,... 507 /// 508 /// The AA manager is set up such that the provided alias analyses are tried 509 /// in the order specified. See the \c AAManaager documentation for details 510 /// about the logic used. This routine just provides the textual mapping 511 /// between AA names and the analyses to register with the manager. 512 /// 513 /// Returns false if the text cannot be parsed cleanly. The specific state of 514 /// the \p AA manager is unspecified if such an error is encountered and this 515 /// returns false. 516 Error parseAAPipeline(AAManager &AA, StringRef PipelineText); 517 518 /// Returns true if the pass name is the name of an alias analysis pass. 519 bool isAAPassName(StringRef PassName); 520 521 /// Returns true if the pass name is the name of a (non-alias) analysis pass. 522 bool isAnalysisPassName(StringRef PassName); 523 524 /// Register a callback for a default optimizer pipeline extension 525 /// point 526 /// 527 /// This extension point allows adding passes that perform peephole 528 /// optimizations similar to the instruction combiner. These passes will be 529 /// inserted after each instance of the instruction combiner pass. 530 void registerPeepholeEPCallback( 531 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) { 532 PeepholeEPCallbacks.push_back(C); 533 } 534 535 /// Register a callback for a default optimizer pipeline extension 536 /// point 537 /// 538 /// This extension point allows adding late loop canonicalization and 539 /// simplification passes. This is the last point in the loop optimization 540 /// pipeline before loop deletion. Each pass added 541 /// here must be an instance of LoopPass. 542 /// This is the place to add passes that can remove loops, such as target- 543 /// specific loop idiom recognition. 544 void registerLateLoopOptimizationsEPCallback( 545 const std::function<void(LoopPassManager &, OptimizationLevel)> &C) { 546 LateLoopOptimizationsEPCallbacks.push_back(C); 547 } 548 549 /// Register a callback for a default optimizer pipeline extension 550 /// point 551 /// 552 /// This extension point allows adding loop passes to the end of the loop 553 /// optimizer. 554 void registerLoopOptimizerEndEPCallback( 555 const std::function<void(LoopPassManager &, OptimizationLevel)> &C) { 556 LoopOptimizerEndEPCallbacks.push_back(C); 557 } 558 559 /// Register a callback for a default optimizer pipeline extension 560 /// point 561 /// 562 /// This extension point allows adding optimization passes after most of the 563 /// main optimizations, but before the last cleanup-ish optimizations. 564 void registerScalarOptimizerLateEPCallback( 565 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) { 566 ScalarOptimizerLateEPCallbacks.push_back(C); 567 } 568 569 /// Register a callback for a default optimizer pipeline extension 570 /// point 571 /// 572 /// This extension point allows adding CallGraphSCC passes at the end of the 573 /// main CallGraphSCC passes and before any function simplification passes run 574 /// by CGPassManager. 575 void registerCGSCCOptimizerLateEPCallback( 576 const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) { 577 CGSCCOptimizerLateEPCallbacks.push_back(C); 578 } 579 580 /// Register a callback for a default optimizer pipeline extension 581 /// point 582 /// 583 /// This extension point allows adding optimization passes before the 584 /// vectorizer and other highly target specific optimization passes are 585 /// executed. 586 void registerVectorizerStartEPCallback( 587 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) { 588 VectorizerStartEPCallbacks.push_back(C); 589 } 590 591 /// Register a callback for a default optimizer pipeline extension point. 592 /// 593 /// This extension point allows adding optimization once at the start of the 594 /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO 595 /// link-time pipelines). 596 void registerPipelineStartEPCallback( 597 const std::function<void(ModulePassManager &)> &C) { 598 PipelineStartEPCallbacks.push_back(C); 599 } 600 601 /// Register a callback for a default optimizer pipeline extension point 602 /// 603 /// This extension point allows adding optimizations at the very end of the 604 /// function optimization pipeline. A key difference between this and the 605 /// legacy PassManager's OptimizerLast callback is that this extension point 606 /// is not triggered at O0. Extensions to the O0 pipeline should append their 607 /// passes to the end of the overall pipeline. 608 void registerOptimizerLastEPCallback( 609 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { 610 OptimizerLastEPCallbacks.push_back(C); 611 } 612 613 /// Register a callback for parsing an AliasAnalysis Name to populate 614 /// the given AAManager \p AA 615 void registerParseAACallback( 616 const std::function<bool(StringRef Name, AAManager &AA)> &C) { 617 AAParsingCallbacks.push_back(C); 618 } 619 620 /// {{@ Register callbacks for analysis registration with this PassBuilder 621 /// instance. 622 /// Callees register their analyses with the given AnalysisManager objects. 623 void registerAnalysisRegistrationCallback( 624 const std::function<void(CGSCCAnalysisManager &)> &C) { 625 CGSCCAnalysisRegistrationCallbacks.push_back(C); 626 } 627 void registerAnalysisRegistrationCallback( 628 const std::function<void(FunctionAnalysisManager &)> &C) { 629 FunctionAnalysisRegistrationCallbacks.push_back(C); 630 } 631 void registerAnalysisRegistrationCallback( 632 const std::function<void(LoopAnalysisManager &)> &C) { 633 LoopAnalysisRegistrationCallbacks.push_back(C); 634 } 635 void registerAnalysisRegistrationCallback( 636 const std::function<void(ModuleAnalysisManager &)> &C) { 637 ModuleAnalysisRegistrationCallbacks.push_back(C); 638 } 639 /// @}} 640 641 /// {{@ Register pipeline parsing callbacks with this pass builder instance. 642 /// Using these callbacks, callers can parse both a single pass name, as well 643 /// as entire sub-pipelines, and populate the PassManager instance 644 /// accordingly. 645 void registerPipelineParsingCallback( 646 const std::function<bool(StringRef Name, CGSCCPassManager &, 647 ArrayRef<PipelineElement>)> &C) { 648 CGSCCPipelineParsingCallbacks.push_back(C); 649 } 650 void registerPipelineParsingCallback( 651 const std::function<bool(StringRef Name, FunctionPassManager &, 652 ArrayRef<PipelineElement>)> &C) { 653 FunctionPipelineParsingCallbacks.push_back(C); 654 } 655 void registerPipelineParsingCallback( 656 const std::function<bool(StringRef Name, LoopPassManager &, 657 ArrayRef<PipelineElement>)> &C) { 658 LoopPipelineParsingCallbacks.push_back(C); 659 } 660 void registerPipelineParsingCallback( 661 const std::function<bool(StringRef Name, ModulePassManager &, 662 ArrayRef<PipelineElement>)> &C) { 663 ModulePipelineParsingCallbacks.push_back(C); 664 } 665 /// @}} 666 667 /// Register a callback for a top-level pipeline entry. 668 /// 669 /// If the PassManager type is not given at the top level of the pipeline 670 /// text, this Callback should be used to determine the appropriate stack of 671 /// PassManagers and populate the passed ModulePassManager. 672 void registerParseTopLevelPipelineCallback( 673 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>, 674 bool VerifyEachPass, bool DebugLogging)> &C) { 675 TopLevelPipelineParsingCallbacks.push_back(C); 676 } 677 678 /// Add PGOInstrumenation passes for O0 only. 679 void addPGOInstrPassesForO0(ModulePassManager &MPM, bool DebugLogging, 680 bool RunProfileGen, bool IsCS, 681 std::string ProfileFile, 682 std::string ProfileRemappingFile); 683 684 685 /// Returns PIC. External libraries can use this to register pass 686 /// instrumentation callbacks. 687 PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const { 688 return PIC; 689 } 690 691 private: 692 // O1 pass pipeline 693 FunctionPassManager buildO1FunctionSimplificationPipeline( 694 OptimizationLevel Level, ThinLTOPhase Phase, bool DebugLogging = false); 695 696 static Optional<std::vector<PipelineElement>> 697 parsePipelineText(StringRef Text); 698 699 Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E, 700 bool VerifyEachPass, bool DebugLogging); 701 Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E, 702 bool VerifyEachPass, bool DebugLogging); 703 Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E, 704 bool VerifyEachPass, bool DebugLogging); 705 Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E, 706 bool VerifyEachPass, bool DebugLogging); 707 bool parseAAPassName(AAManager &AA, StringRef Name); 708 709 Error parseLoopPassPipeline(LoopPassManager &LPM, 710 ArrayRef<PipelineElement> Pipeline, 711 bool VerifyEachPass, bool DebugLogging); 712 Error parseFunctionPassPipeline(FunctionPassManager &FPM, 713 ArrayRef<PipelineElement> Pipeline, 714 bool VerifyEachPass, bool DebugLogging); 715 Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM, 716 ArrayRef<PipelineElement> Pipeline, 717 bool VerifyEachPass, bool DebugLogging); 718 Error parseModulePassPipeline(ModulePassManager &MPM, 719 ArrayRef<PipelineElement> Pipeline, 720 bool VerifyEachPass, bool DebugLogging); 721 722 void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, 723 OptimizationLevel Level, bool RunProfileGen, bool IsCS, 724 std::string ProfileFile, 725 std::string ProfileRemappingFile); 726 void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel); 727 728 // Extension Point callbacks 729 SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2> 730 PeepholeEPCallbacks; 731 SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2> 732 LateLoopOptimizationsEPCallbacks; 733 SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2> 734 LoopOptimizerEndEPCallbacks; 735 SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2> 736 ScalarOptimizerLateEPCallbacks; 737 SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2> 738 CGSCCOptimizerLateEPCallbacks; 739 SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2> 740 VectorizerStartEPCallbacks; 741 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> 742 OptimizerLastEPCallbacks; 743 // Module callbacks 744 SmallVector<std::function<void(ModulePassManager &)>, 2> 745 PipelineStartEPCallbacks; 746 SmallVector<std::function<void(ModuleAnalysisManager &)>, 2> 747 ModuleAnalysisRegistrationCallbacks; 748 SmallVector<std::function<bool(StringRef, ModulePassManager &, 749 ArrayRef<PipelineElement>)>, 750 2> 751 ModulePipelineParsingCallbacks; 752 SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>, 753 bool VerifyEachPass, bool DebugLogging)>, 754 2> 755 TopLevelPipelineParsingCallbacks; 756 // CGSCC callbacks 757 SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2> 758 CGSCCAnalysisRegistrationCallbacks; 759 SmallVector<std::function<bool(StringRef, CGSCCPassManager &, 760 ArrayRef<PipelineElement>)>, 761 2> 762 CGSCCPipelineParsingCallbacks; 763 // Function callbacks 764 SmallVector<std::function<void(FunctionAnalysisManager &)>, 2> 765 FunctionAnalysisRegistrationCallbacks; 766 SmallVector<std::function<bool(StringRef, FunctionPassManager &, 767 ArrayRef<PipelineElement>)>, 768 2> 769 FunctionPipelineParsingCallbacks; 770 // Loop callbacks 771 SmallVector<std::function<void(LoopAnalysisManager &)>, 2> 772 LoopAnalysisRegistrationCallbacks; 773 SmallVector<std::function<bool(StringRef, LoopPassManager &, 774 ArrayRef<PipelineElement>)>, 775 2> 776 LoopPipelineParsingCallbacks; 777 // AA callbacks 778 SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2> 779 AAParsingCallbacks; 780 }; 781 782 /// This utility template takes care of adding require<> and invalidate<> 783 /// passes for an analysis to a given \c PassManager. It is intended to be used 784 /// during parsing of a pass pipeline when parsing a single PipelineName. 785 /// When registering a new function analysis FancyAnalysis with the pass 786 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look 787 /// like this: 788 /// 789 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM, 790 /// ArrayRef<PipelineElement> P) { 791 /// if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name, 792 /// FPM)) 793 /// return true; 794 /// return false; 795 /// } 796 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT, 797 typename... ExtraArgTs> 798 bool parseAnalysisUtilityPasses( 799 StringRef AnalysisName, StringRef PipelineName, 800 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) { 801 if (!PipelineName.endswith(">")) 802 return false; 803 // See if this is an invalidate<> pass name 804 if (PipelineName.startswith("invalidate<")) { 805 PipelineName = PipelineName.substr(11, PipelineName.size() - 12); 806 if (PipelineName != AnalysisName) 807 return false; 808 PM.addPass(InvalidateAnalysisPass<AnalysisT>()); 809 return true; 810 } 811 812 // See if this is a require<> pass name 813 if (PipelineName.startswith("require<")) { 814 PipelineName = PipelineName.substr(8, PipelineName.size() - 9); 815 if (PipelineName != AnalysisName) 816 return false; 817 PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT, 818 ExtraArgTs...>()); 819 return true; 820 } 821 822 return false; 823 } 824 } 825 826 #endif 827