Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:23

0001 //===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// Interfaces for registering analysis passes, producing common pass manager
0011 /// configurations, and parsing of pass pipelines.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_PASSES_PASSBUILDER_H
0016 #define LLVM_PASSES_PASSBUILDER_H
0017 
0018 #include "llvm/Analysis/CGSCCPassManager.h"
0019 #include "llvm/CodeGen/MachinePassManager.h"
0020 #include "llvm/CodeGen/RegAllocCommon.h"
0021 #include "llvm/IR/PassManager.h"
0022 #include "llvm/Passes/OptimizationLevel.h"
0023 #include "llvm/Support/Error.h"
0024 #include "llvm/Support/PGOOptions.h"
0025 #include "llvm/Support/raw_ostream.h"
0026 #include "llvm/Transforms/IPO/Inliner.h"
0027 #include "llvm/Transforms/IPO/ModuleInliner.h"
0028 #include "llvm/Transforms/Scalar/LoopPassManager.h"
0029 #include <optional>
0030 #include <vector>
0031 
0032 namespace llvm {
0033 class StringRef;
0034 class AAManager;
0035 class TargetMachine;
0036 class ModuleSummaryIndex;
0037 template <typename T> class IntrusiveRefCntPtr;
0038 namespace vfs {
0039 class FileSystem;
0040 } // namespace vfs
0041 
0042 /// Tunable parameters for passes in the default pipelines.
0043 class PipelineTuningOptions {
0044 public:
0045   /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
0046   /// can be set in the PassBuilder when using a LLVM as a library.
0047   PipelineTuningOptions();
0048 
0049   /// Tuning option to set loop interleaving on/off, set based on opt level.
0050   bool LoopInterleaving;
0051 
0052   /// Tuning option to enable/disable loop vectorization, set based on opt
0053   /// level.
0054   bool LoopVectorization;
0055 
0056   /// Tuning option to enable/disable slp loop vectorization, set based on opt
0057   /// level.
0058   bool SLPVectorization;
0059 
0060   /// Tuning option to enable/disable loop unrolling. Its default value is true.
0061   bool LoopUnrolling;
0062 
0063   /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
0064   /// is that of the flag: `-forget-scev-loop-unroll`.
0065   bool ForgetAllSCEVInLoopUnroll;
0066 
0067   /// Tuning option to cap the number of calls to retrive clobbering accesses in
0068   /// MemorySSA, in LICM.
0069   unsigned LicmMssaOptCap;
0070 
0071   /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
0072   /// the number of access is too large.
0073   unsigned LicmMssaNoAccForPromotionCap;
0074 
0075   /// Tuning option to enable/disable call graph profile. Its default value is
0076   /// that of the flag: `-enable-npm-call-graph-profile`.
0077   bool CallGraphProfile;
0078 
0079   // Add LTO pipeline tuning option to enable the unified LTO pipeline.
0080   bool UnifiedLTO;
0081 
0082   /// Tuning option to enable/disable function merging. Its default value is
0083   /// false.
0084   bool MergeFunctions;
0085 
0086   /// Tuning option to override the default inliner threshold.
0087   int InlinerThreshold;
0088 
0089   // Experimental option to eagerly invalidate more analyses. This has the
0090   // potential to decrease max memory usage in exchange for more compile time.
0091   // This may affect codegen due to either passes using analyses only when
0092   // cached, or invalidating and recalculating an analysis that was
0093   // stale/imprecise but still valid. Currently this invalidates all function
0094   // analyses after various module->function or cgscc->function adaptors in the
0095   // default pipelines.
0096   bool EagerlyInvalidateAnalyses;
0097 };
0098 
0099 /// This class provides access to building LLVM's passes.
0100 ///
0101 /// Its members provide the baseline state available to passes during their
0102 /// construction. The \c PassRegistry.def file specifies how to construct all
0103 /// of the built-in passes, and those may reference these members during
0104 /// construction.
0105 class PassBuilder {
0106   TargetMachine *TM;
0107   PipelineTuningOptions PTO;
0108   std::optional<PGOOptions> PGOOpt;
0109   PassInstrumentationCallbacks *PIC;
0110 
0111 public:
0112   /// A struct to capture parsed pass pipeline names.
0113   ///
0114   /// A pipeline is defined as a series of names, each of which may in itself
0115   /// recursively contain a nested pipeline. A name is either the name of a pass
0116   /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
0117   /// name is the name of a pass, the InnerPipeline is empty, since passes
0118   /// cannot contain inner pipelines. See parsePassPipeline() for a more
0119   /// detailed description of the textual pipeline format.
0120   struct PipelineElement {
0121     StringRef Name;
0122     std::vector<PipelineElement> InnerPipeline;
0123   };
0124 
0125   explicit PassBuilder(TargetMachine *TM = nullptr,
0126                        PipelineTuningOptions PTO = PipelineTuningOptions(),
0127                        std::optional<PGOOptions> PGOOpt = std::nullopt,
0128                        PassInstrumentationCallbacks *PIC = nullptr);
0129 
0130   /// Cross register the analysis managers through their proxies.
0131   ///
0132   /// This is an interface that can be used to cross register each
0133   /// AnalysisManager with all the others analysis managers.
0134   void crossRegisterProxies(LoopAnalysisManager &LAM,
0135                             FunctionAnalysisManager &FAM,
0136                             CGSCCAnalysisManager &CGAM,
0137                             ModuleAnalysisManager &MAM,
0138                             MachineFunctionAnalysisManager *MFAM = nullptr);
0139 
0140   /// Registers all available module analysis passes.
0141   ///
0142   /// This is an interface that can be used to populate a \c
0143   /// ModuleAnalysisManager with all registered module analyses. Callers can
0144   /// still manually register any additional analyses. Callers can also
0145   /// pre-register analyses and this will not override those.
0146   void registerModuleAnalyses(ModuleAnalysisManager &MAM);
0147 
0148   /// Registers all available CGSCC analysis passes.
0149   ///
0150   /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
0151   /// with all registered CGSCC analyses. Callers can still manually register any
0152   /// additional analyses. Callers can also pre-register analyses and this will
0153   /// not override those.
0154   void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
0155 
0156   /// Registers all available function analysis passes.
0157   ///
0158   /// This is an interface that can be used to populate a \c
0159   /// FunctionAnalysisManager with all registered function analyses. Callers can
0160   /// still manually register any additional analyses. Callers can also
0161   /// pre-register analyses and this will not override those.
0162   void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
0163 
0164   /// Registers all available loop analysis passes.
0165   ///
0166   /// This is an interface that can be used to populate a \c LoopAnalysisManager
0167   /// with all registered loop analyses. Callers can still manually register any
0168   /// additional analyses.
0169   void registerLoopAnalyses(LoopAnalysisManager &LAM);
0170 
0171   /// Registers all available machine function analysis passes.
0172   ///
0173   /// This is an interface that can be used to populate a \c
0174   /// MachineFunctionAnalysisManager with all registered function analyses.
0175   /// Callers can still manually register any additional analyses. Callers can
0176   /// also pre-register analyses and this will not override those.
0177   void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM);
0178 
0179   /// Construct the core LLVM function canonicalization and simplification
0180   /// pipeline.
0181   ///
0182   /// This is a long pipeline and uses most of the per-function optimization
0183   /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
0184   /// repeatedly over the IR and is not expected to destroy important
0185   /// information about the semantics of the IR.
0186   ///
0187   /// Note that \p Level cannot be `O0` here. The pipelines produced are
0188   /// only intended for use when attempting to optimize code. If frontends
0189   /// require some transformations for semantic reasons, they should explicitly
0190   /// build them.
0191   ///
0192   /// \p Phase indicates the current ThinLTO phase.
0193   FunctionPassManager
0194   buildFunctionSimplificationPipeline(OptimizationLevel Level,
0195                                       ThinOrFullLTOPhase Phase);
0196 
0197   /// Construct the core LLVM module canonicalization and simplification
0198   /// pipeline.
0199   ///
0200   /// This pipeline focuses on canonicalizing and simplifying the entire module
0201   /// of IR. Much like the function simplification pipeline above, it is
0202   /// suitable to run repeatedly over the IR and is not expected to destroy
0203   /// important information. It does, however, perform inlining and other
0204   /// heuristic based simplifications that are not strictly reversible.
0205   ///
0206   /// Note that \p Level cannot be `O0` here. The pipelines produced are
0207   /// only intended for use when attempting to optimize code. If frontends
0208   /// require some transformations for semantic reasons, they should explicitly
0209   /// build them.
0210   ///
0211   /// \p Phase indicates the current ThinLTO phase.
0212   ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
0213                                                       ThinOrFullLTOPhase Phase);
0214 
0215   /// Construct the module pipeline that performs inlining as well as
0216   /// the inlining-driven cleanups.
0217   ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
0218                                                 ThinOrFullLTOPhase Phase);
0219 
0220   /// Construct the module pipeline that performs inlining with
0221   /// module inliner pass.
0222   ModulePassManager buildModuleInlinerPipeline(OptimizationLevel Level,
0223                                                ThinOrFullLTOPhase Phase);
0224 
0225   /// Construct the core LLVM module optimization pipeline.
0226   ///
0227   /// This pipeline focuses on optimizing the execution speed of the IR. It
0228   /// uses cost modeling and thresholds to balance code growth against runtime
0229   /// improvements. It includes vectorization and other information destroying
0230   /// transformations. It also cannot generally be run repeatedly on a module
0231   /// without potentially seriously regressing either runtime performance of
0232   /// the code or serious code size growth.
0233   ///
0234   /// Note that \p Level cannot be `O0` here. The pipelines produced are
0235   /// only intended for use when attempting to optimize code. If frontends
0236   /// require some transformations for semantic reasons, they should explicitly
0237   /// build them.
0238   ModulePassManager
0239   buildModuleOptimizationPipeline(OptimizationLevel Level,
0240                                   ThinOrFullLTOPhase LTOPhase);
0241 
0242   /// Build a per-module default optimization pipeline.
0243   ///
0244   /// This provides a good default optimization pipeline for per-module
0245   /// optimization and code generation without any link-time optimization. It
0246   /// typically correspond to frontend "-O[123]" options for optimization
0247   /// levels \c O1, \c O2 and \c O3 resp.
0248   ModulePassManager buildPerModuleDefaultPipeline(
0249       OptimizationLevel Level,
0250       ThinOrFullLTOPhase Phase = ThinOrFullLTOPhase::None);
0251 
0252   /// Build a fat object default optimization pipeline.
0253   ///
0254   /// This builds a pipeline that runs the LTO/ThinLTO  pre-link pipeline, and
0255   /// emits a section containing the pre-link bitcode along side the object code
0256   /// generated in non-LTO compilation.
0257   ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
0258                                                bool ThinLTO, bool EmitSummary);
0259 
0260   /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
0261   /// a pass manager.
0262   ///
0263   /// This adds the pre-link optimizations tuned to prepare a module for
0264   /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
0265   /// without making irreversible decisions which could be made better during
0266   /// the LTO run.
0267   ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
0268 
0269   /// Build a ThinLTO default optimization pipeline to a pass manager.
0270   ///
0271   /// This provides a good default optimization pipeline for link-time
0272   /// optimization and code generation. It is particularly tuned to fit well
0273   /// when IR coming into the LTO phase was first run through \c
0274   /// buildThinLTOPreLinkDefaultPipeline, and the two coordinate closely.
0275   ModulePassManager
0276   buildThinLTODefaultPipeline(OptimizationLevel Level,
0277                               const ModuleSummaryIndex *ImportSummary);
0278 
0279   /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
0280   /// manager.
0281   ///
0282   /// This adds the pre-link optimizations tuned to work well with a later LTO
0283   /// run. It works to minimize the IR which needs to be analyzed without
0284   /// making irreversible decisions which could be made better during the LTO
0285   /// run.
0286   ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
0287 
0288   /// Build an LTO default optimization pipeline to a pass manager.
0289   ///
0290   /// This provides a good default optimization pipeline for link-time
0291   /// optimization and code generation. It is particularly tuned to fit well
0292   /// when IR coming into the LTO phase was first run through \c
0293   /// buildLTOPreLinkDefaultPipeline, and the two coordinate closely.
0294   ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
0295                                             ModuleSummaryIndex *ExportSummary);
0296 
0297   /// Build an O0 pipeline with the minimal semantically required passes.
0298   ///
0299   /// This should only be used for non-LTO and LTO pre-link pipelines.
0300   ModulePassManager
0301   buildO0DefaultPipeline(OptimizationLevel Level,
0302                          ThinOrFullLTOPhase Phase = ThinOrFullLTOPhase::None);
0303 
0304   /// Build the default `AAManager` with the default alias analysis pipeline
0305   /// registered.
0306   ///
0307   /// This also adds target-specific alias analyses registered via
0308   /// TargetMachine::registerDefaultAliasAnalyses().
0309   AAManager buildDefaultAAPipeline();
0310 
0311   /// Parse a textual pass pipeline description into a \c
0312   /// ModulePassManager.
0313   ///
0314   /// The format of the textual pass pipeline description looks something like:
0315   ///
0316   ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
0317   ///
0318   /// Pass managers have ()s describing the nest structure of passes. All passes
0319   /// are comma separated. As a special shortcut, if the very first pass is not
0320   /// a module pass (as a module pass manager is), this will automatically form
0321   /// the shortest stack of pass managers that allow inserting that first pass.
0322   /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
0323   /// passes 'lpassN', all of these are valid:
0324   ///
0325   ///   fpass1,fpass2,fpass3
0326   ///   cgpass1,cgpass2,cgpass3
0327   ///   lpass1,lpass2,lpass3
0328   ///
0329   /// And they are equivalent to the following (resp.):
0330   ///
0331   ///   module(function(fpass1,fpass2,fpass3))
0332   ///   module(cgscc(cgpass1,cgpass2,cgpass3))
0333   ///   module(function(loop(lpass1,lpass2,lpass3)))
0334   ///
0335   /// This shortcut is especially useful for debugging and testing small pass
0336   /// combinations.
0337   ///
0338   /// The sequence of passes aren't necessarily the exact same kind of pass.
0339   /// You can mix different levels implicitly if adaptor passes are defined to
0340   /// make them work. For example,
0341   ///
0342   ///   mpass1,fpass1,fpass2,mpass2,lpass1
0343   ///
0344   /// This pipeline uses only one pass manager: the top-level module manager.
0345   /// fpass1,fpass2 and lpass1 are added into the top-level module manager
0346   /// using only adaptor passes. No nested function/loop pass managers are
0347   /// added. The purpose is to allow easy pass testing when the user
0348   /// specifically want the pass to run under a adaptor directly. This is
0349   /// preferred when a pipeline is largely of one type, but one or just a few
0350   /// passes are of different types(See PassBuilder.cpp for examples).
0351   Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
0352 
0353   /// {{@ Parse a textual pass pipeline description into a specific PassManager
0354   ///
0355   /// Automatic deduction of an appropriate pass manager stack is not supported.
0356   /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
0357   /// this is the valid pipeline text:
0358   ///
0359   ///   function(lpass)
0360   Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
0361   Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
0362   Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
0363   /// @}}
0364 
0365   /// Parse a textual MIR pipeline into the provided \c MachineFunctionPass
0366   /// manager.
0367   /// The format of the textual machine pipeline is a comma separated list of
0368   /// machine pass names:
0369   ///
0370   ///   machine-funciton-pass,machine-module-pass,...
0371   ///
0372   /// There is no need to specify the pass nesting, and this function
0373   /// currently cannot handle the pass nesting.
0374   Error parsePassPipeline(MachineFunctionPassManager &MFPM,
0375                           StringRef PipelineText);
0376 
0377   /// Parse a textual alias analysis pipeline into the provided AA manager.
0378   ///
0379   /// The format of the textual AA pipeline is a comma separated list of AA
0380   /// pass names:
0381   ///
0382   ///   basic-aa,globals-aa,...
0383   ///
0384   /// The AA manager is set up such that the provided alias analyses are tried
0385   /// in the order specified. See the \c AAManaager documentation for details
0386   /// about the logic used. This routine just provides the textual mapping
0387   /// between AA names and the analyses to register with the manager.
0388   ///
0389   /// Returns false if the text cannot be parsed cleanly. The specific state of
0390   /// the \p AA manager is unspecified if such an error is encountered and this
0391   /// returns false.
0392   Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
0393 
0394   /// Parse RegAllocFilterName to get RegAllocFilterFunc.
0395   std::optional<RegAllocFilterFunc>
0396   parseRegAllocFilter(StringRef RegAllocFilterName);
0397 
0398   /// Print pass names.
0399   void printPassNames(raw_ostream &OS);
0400 
0401   /// Register a callback for a default optimizer pipeline extension
0402   /// point
0403   ///
0404   /// This extension point allows adding passes that perform peephole
0405   /// optimizations similar to the instruction combiner. These passes will be
0406   /// inserted after each instance of the instruction combiner pass.
0407   void registerPeepholeEPCallback(
0408       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
0409     PeepholeEPCallbacks.push_back(C);
0410   }
0411 
0412   /// Register a callback for a default optimizer pipeline extension
0413   /// point
0414   ///
0415   /// This extension point allows adding late loop canonicalization and
0416   /// simplification passes. This is the last point in the loop optimization
0417   /// pipeline before loop deletion. Each pass added
0418   /// here must be an instance of LoopPass.
0419   /// This is the place to add passes that can remove loops, such as target-
0420   /// specific loop idiom recognition.
0421   void registerLateLoopOptimizationsEPCallback(
0422       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
0423     LateLoopOptimizationsEPCallbacks.push_back(C);
0424   }
0425 
0426   /// Register a callback for a default optimizer pipeline extension
0427   /// point
0428   ///
0429   /// This extension point allows adding loop passes to the end of the loop
0430   /// optimizer.
0431   void registerLoopOptimizerEndEPCallback(
0432       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
0433     LoopOptimizerEndEPCallbacks.push_back(C);
0434   }
0435 
0436   /// Register a callback for a default optimizer pipeline extension
0437   /// point
0438   ///
0439   /// This extension point allows adding optimization passes after most of the
0440   /// main optimizations, but before the last cleanup-ish optimizations.
0441   void registerScalarOptimizerLateEPCallback(
0442       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
0443     ScalarOptimizerLateEPCallbacks.push_back(C);
0444   }
0445 
0446   /// Register a callback for a default optimizer pipeline extension
0447   /// point
0448   ///
0449   /// This extension point allows adding CallGraphSCC passes at the end of the
0450   /// main CallGraphSCC passes and before any function simplification passes run
0451   /// by CGPassManager.
0452   void registerCGSCCOptimizerLateEPCallback(
0453       const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
0454     CGSCCOptimizerLateEPCallbacks.push_back(C);
0455   }
0456 
0457   /// Register a callback for a default optimizer pipeline extension
0458   /// point
0459   ///
0460   /// This extension point allows adding optimization passes before the
0461   /// vectorizer and other highly target specific optimization passes are
0462   /// executed.
0463   void registerVectorizerStartEPCallback(
0464       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
0465     VectorizerStartEPCallbacks.push_back(C);
0466   }
0467 
0468   /// Register a callback for a default optimizer pipeline extension point.
0469   ///
0470   /// This extension point allows adding optimization once at the start of the
0471   /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
0472   /// link-time pipelines).
0473   void registerPipelineStartEPCallback(
0474       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
0475     PipelineStartEPCallbacks.push_back(C);
0476   }
0477 
0478   /// Register a callback for a default optimizer pipeline extension point.
0479   ///
0480   /// This extension point allows adding optimization right after passes that do
0481   /// basic simplification of the input IR.
0482   void registerPipelineEarlySimplificationEPCallback(
0483       const std::function<void(ModulePassManager &, OptimizationLevel,
0484                                ThinOrFullLTOPhase)> &C) {
0485     PipelineEarlySimplificationEPCallbacks.push_back(C);
0486   }
0487 
0488   /// Register a callback for a default optimizer pipeline extension point
0489   ///
0490   /// This extension point allows adding optimizations before the function
0491   /// optimization pipeline.
0492   void registerOptimizerEarlyEPCallback(
0493       const std::function<void(ModulePassManager &, OptimizationLevel,
0494                                ThinOrFullLTOPhase Phase)> &C) {
0495     OptimizerEarlyEPCallbacks.push_back(C);
0496   }
0497 
0498   /// Register a callback for a default optimizer pipeline extension point
0499   ///
0500   /// This extension point allows adding optimizations at the very end of the
0501   /// function optimization pipeline.
0502   void registerOptimizerLastEPCallback(
0503       const std::function<void(ModulePassManager &, OptimizationLevel,
0504                                ThinOrFullLTOPhase)> &C) {
0505     OptimizerLastEPCallbacks.push_back(C);
0506   }
0507 
0508   /// Register a callback for a default optimizer pipeline extension point
0509   ///
0510   /// This extension point allows adding optimizations at the start of the full
0511   /// LTO pipeline.
0512   void registerFullLinkTimeOptimizationEarlyEPCallback(
0513       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
0514     FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C);
0515   }
0516 
0517   /// Register a callback for a default optimizer pipeline extension point
0518   ///
0519   /// This extension point allows adding optimizations at the end of the full
0520   /// LTO pipeline.
0521   void registerFullLinkTimeOptimizationLastEPCallback(
0522       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
0523     FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
0524   }
0525 
0526   /// Register a callback for parsing an AliasAnalysis Name to populate
0527   /// the given AAManager \p AA
0528   void registerParseAACallback(
0529       const std::function<bool(StringRef Name, AAManager &AA)> &C) {
0530     AAParsingCallbacks.push_back(C);
0531   }
0532 
0533   /// {{@ Register callbacks for analysis registration with this PassBuilder
0534   /// instance.
0535   /// Callees register their analyses with the given AnalysisManager objects.
0536   void registerAnalysisRegistrationCallback(
0537       const std::function<void(CGSCCAnalysisManager &)> &C) {
0538     CGSCCAnalysisRegistrationCallbacks.push_back(C);
0539   }
0540   void registerAnalysisRegistrationCallback(
0541       const std::function<void(FunctionAnalysisManager &)> &C) {
0542     FunctionAnalysisRegistrationCallbacks.push_back(C);
0543   }
0544   void registerAnalysisRegistrationCallback(
0545       const std::function<void(LoopAnalysisManager &)> &C) {
0546     LoopAnalysisRegistrationCallbacks.push_back(C);
0547   }
0548   void registerAnalysisRegistrationCallback(
0549       const std::function<void(ModuleAnalysisManager &)> &C) {
0550     ModuleAnalysisRegistrationCallbacks.push_back(C);
0551   }
0552   void registerAnalysisRegistrationCallback(
0553       const std::function<void(MachineFunctionAnalysisManager &)> &C) {
0554     MachineFunctionAnalysisRegistrationCallbacks.push_back(C);
0555   }
0556   /// @}}
0557 
0558   /// {{@ Register pipeline parsing callbacks with this pass builder instance.
0559   /// Using these callbacks, callers can parse both a single pass name, as well
0560   /// as entire sub-pipelines, and populate the PassManager instance
0561   /// accordingly.
0562   void registerPipelineParsingCallback(
0563       const std::function<bool(StringRef Name, CGSCCPassManager &,
0564                                ArrayRef<PipelineElement>)> &C) {
0565     CGSCCPipelineParsingCallbacks.push_back(C);
0566   }
0567   void registerPipelineParsingCallback(
0568       const std::function<bool(StringRef Name, FunctionPassManager &,
0569                                ArrayRef<PipelineElement>)> &C) {
0570     FunctionPipelineParsingCallbacks.push_back(C);
0571   }
0572   void registerPipelineParsingCallback(
0573       const std::function<bool(StringRef Name, LoopPassManager &,
0574                                ArrayRef<PipelineElement>)> &C) {
0575     LoopPipelineParsingCallbacks.push_back(C);
0576   }
0577   void registerPipelineParsingCallback(
0578       const std::function<bool(StringRef Name, ModulePassManager &,
0579                                ArrayRef<PipelineElement>)> &C) {
0580     ModulePipelineParsingCallbacks.push_back(C);
0581   }
0582   void registerPipelineParsingCallback(
0583       const std::function<bool(StringRef Name, MachineFunctionPassManager &,
0584                                ArrayRef<PipelineElement>)> &C) {
0585     MachineFunctionPipelineParsingCallbacks.push_back(C);
0586   }
0587   /// @}}
0588 
0589   /// Register callbacks to parse target specific filter field if regalloc pass
0590   /// needs it. E.g. AMDGPU requires regalloc passes can handle sgpr and vgpr
0591   /// separately.
0592   void registerRegClassFilterParsingCallback(
0593       const std::function<RegAllocFilterFunc(StringRef)> &C) {
0594     RegClassFilterParsingCallbacks.push_back(C);
0595   }
0596 
0597   /// Register a callback for a top-level pipeline entry.
0598   ///
0599   /// If the PassManager type is not given at the top level of the pipeline
0600   /// text, this Callback should be used to determine the appropriate stack of
0601   /// PassManagers and populate the passed ModulePassManager.
0602   void registerParseTopLevelPipelineCallback(
0603       const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
0604           &C);
0605 
0606   /// Add PGOInstrumenation passes for O0 only.
0607   void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
0608                               bool IsCS, bool AtomicCounterUpdate,
0609                               std::string ProfileFile,
0610                               std::string ProfileRemappingFile,
0611                               IntrusiveRefCntPtr<vfs::FileSystem> FS);
0612 
0613   /// Returns PIC. External libraries can use this to register pass
0614   /// instrumentation callbacks.
0615   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
0616     return PIC;
0617   }
0618 
0619   // Invoke the callbacks registered for the various extension points.
0620   // Custom pipelines should use these to invoke the callbacks registered
0621   // by TargetMachines and other clients.
0622   void invokePeepholeEPCallbacks(FunctionPassManager &FPM,
0623                                  OptimizationLevel Level);
0624   void invokeLateLoopOptimizationsEPCallbacks(LoopPassManager &LPM,
0625                                               OptimizationLevel Level);
0626   void invokeLoopOptimizerEndEPCallbacks(LoopPassManager &LPM,
0627                                          OptimizationLevel Level);
0628   void invokeScalarOptimizerLateEPCallbacks(FunctionPassManager &FPM,
0629                                             OptimizationLevel Level);
0630   void invokeCGSCCOptimizerLateEPCallbacks(CGSCCPassManager &CGPM,
0631                                            OptimizationLevel Level);
0632   void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
0633                                         OptimizationLevel Level);
0634   void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
0635                                        OptimizationLevel Level,
0636                                        ThinOrFullLTOPhase Phase);
0637   void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
0638                                       OptimizationLevel Level,
0639                                       ThinOrFullLTOPhase Phase);
0640   void invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
0641                                                       OptimizationLevel Level);
0642   void invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
0643                                                      OptimizationLevel Level);
0644   void invokePipelineStartEPCallbacks(ModulePassManager &MPM,
0645                                       OptimizationLevel Level);
0646   void invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM,
0647                                                     OptimizationLevel Level,
0648                                                     ThinOrFullLTOPhase Phase);
0649 
0650   static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
0651     if (!Name.consume_front(PassName))
0652       return false;
0653     // normal pass name w/o parameters == default parameters
0654     if (Name.empty())
0655       return true;
0656     return Name.starts_with("<") && Name.ends_with(">");
0657   }
0658 
0659   /// This performs customized parsing of pass name with parameters.
0660   ///
0661   /// We do not need parametrization of passes in textual pipeline very often,
0662   /// yet on a rare occasion ability to specify parameters right there can be
0663   /// useful.
0664   ///
0665   /// \p Name - parameterized specification of a pass from a textual pipeline
0666   /// is a string in a form of :
0667   ///      PassName '<' parameter-list '>'
0668   ///
0669   /// Parameter list is being parsed by the parser callable argument, \p Parser,
0670   /// It takes a string-ref of parameters and returns either StringError or a
0671   /// parameter list in a form of a custom parameters type, all wrapped into
0672   /// Expected<> template class.
0673   ///
0674   template <typename ParametersParseCallableT>
0675   static auto parsePassParameters(ParametersParseCallableT &&Parser,
0676                                   StringRef Name, StringRef PassName)
0677       -> decltype(Parser(StringRef{})) {
0678     using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
0679 
0680     StringRef Params = Name;
0681     if (!Params.consume_front(PassName)) {
0682       llvm_unreachable(
0683           "unable to strip pass name from parametrized pass specification");
0684     }
0685     if (!Params.empty() &&
0686         (!Params.consume_front("<") || !Params.consume_back(">"))) {
0687       llvm_unreachable("invalid format for parametrized pass name");
0688     }
0689 
0690     Expected<ParametersT> Result = Parser(Params);
0691     assert((Result || Result.template errorIsA<StringError>()) &&
0692            "Pass parameter parser can only return StringErrors.");
0693     return Result;
0694   }
0695 
0696   /// Handle passes only accept one bool-valued parameter.
0697   ///
0698   /// \return false when Params is empty.
0699   static Expected<bool> parseSinglePassOption(StringRef Params,
0700                                               StringRef OptionName,
0701                                               StringRef PassName);
0702 
0703 private:
0704   // O1 pass pipeline
0705   FunctionPassManager
0706   buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
0707                                         ThinOrFullLTOPhase Phase);
0708 
0709   void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
0710 
0711   void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
0712                        bool IsFullLTO);
0713 
0714   static std::optional<std::vector<PipelineElement>>
0715   parsePipelineText(StringRef Text);
0716 
0717   Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
0718   Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
0719   Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
0720   Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
0721   Error parseMachinePass(MachineFunctionPassManager &MFPM,
0722                          const PipelineElement &E);
0723   bool parseAAPassName(AAManager &AA, StringRef Name);
0724 
0725   Error parseMachinePassPipeline(MachineFunctionPassManager &MFPM,
0726                                  ArrayRef<PipelineElement> Pipeline);
0727   Error parseLoopPassPipeline(LoopPassManager &LPM,
0728                               ArrayRef<PipelineElement> Pipeline);
0729   Error parseFunctionPassPipeline(FunctionPassManager &FPM,
0730                                   ArrayRef<PipelineElement> Pipeline);
0731   Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
0732                                ArrayRef<PipelineElement> Pipeline);
0733   Error parseModulePassPipeline(ModulePassManager &MPM,
0734                                 ArrayRef<PipelineElement> Pipeline);
0735 
0736   // Adds passes to do pre-inlining and related cleanup passes before
0737   // profile instrumentation/matching (to enable better context sensitivity),
0738   // and for memprof to enable better matching with missing debug frames.
0739   void addPreInlinerPasses(ModulePassManager &MPM, OptimizationLevel Level,
0740                            ThinOrFullLTOPhase LTOPhase);
0741 
0742   void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
0743                          bool RunProfileGen, bool IsCS,
0744                          bool AtomicCounterUpdate, std::string ProfileFile,
0745                          std::string ProfileRemappingFile,
0746                          IntrusiveRefCntPtr<vfs::FileSystem> FS);
0747   void addPostPGOLoopRotation(ModulePassManager &MPM, OptimizationLevel Level);
0748 
0749   // Extension Point callbacks
0750   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
0751       PeepholeEPCallbacks;
0752   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
0753       LateLoopOptimizationsEPCallbacks;
0754   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
0755       LoopOptimizerEndEPCallbacks;
0756   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
0757       ScalarOptimizerLateEPCallbacks;
0758   SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
0759       CGSCCOptimizerLateEPCallbacks;
0760   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
0761       VectorizerStartEPCallbacks;
0762   // Module callbacks
0763   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
0764                                  ThinOrFullLTOPhase)>,
0765               2>
0766       OptimizerEarlyEPCallbacks;
0767   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
0768                                  ThinOrFullLTOPhase)>,
0769               2>
0770       OptimizerLastEPCallbacks;
0771   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
0772       FullLinkTimeOptimizationEarlyEPCallbacks;
0773   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
0774       FullLinkTimeOptimizationLastEPCallbacks;
0775   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
0776       PipelineStartEPCallbacks;
0777   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
0778                                  ThinOrFullLTOPhase)>,
0779               2>
0780       PipelineEarlySimplificationEPCallbacks;
0781 
0782   SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
0783       ModuleAnalysisRegistrationCallbacks;
0784   SmallVector<std::function<bool(StringRef, ModulePassManager &,
0785                                  ArrayRef<PipelineElement>)>,
0786               2>
0787       ModulePipelineParsingCallbacks;
0788   SmallVector<
0789       std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
0790       TopLevelPipelineParsingCallbacks;
0791   // CGSCC callbacks
0792   SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
0793       CGSCCAnalysisRegistrationCallbacks;
0794   SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
0795                                  ArrayRef<PipelineElement>)>,
0796               2>
0797       CGSCCPipelineParsingCallbacks;
0798   // Function callbacks
0799   SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
0800       FunctionAnalysisRegistrationCallbacks;
0801   SmallVector<std::function<bool(StringRef, FunctionPassManager &,
0802                                  ArrayRef<PipelineElement>)>,
0803               2>
0804       FunctionPipelineParsingCallbacks;
0805   // Loop callbacks
0806   SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
0807       LoopAnalysisRegistrationCallbacks;
0808   SmallVector<std::function<bool(StringRef, LoopPassManager &,
0809                                  ArrayRef<PipelineElement>)>,
0810               2>
0811       LoopPipelineParsingCallbacks;
0812   // AA callbacks
0813   SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
0814       AAParsingCallbacks;
0815   // Machine pass callbackcs
0816   SmallVector<std::function<void(MachineFunctionAnalysisManager &)>, 2>
0817       MachineFunctionAnalysisRegistrationCallbacks;
0818   SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &,
0819                                  ArrayRef<PipelineElement>)>,
0820               2>
0821       MachineFunctionPipelineParsingCallbacks;
0822   // Callbacks to parse `filter` parameter in register allocation passes
0823   SmallVector<std::function<RegAllocFilterFunc(StringRef)>, 2>
0824       RegClassFilterParsingCallbacks;
0825 };
0826 
0827 /// This utility template takes care of adding require<> and invalidate<>
0828 /// passes for an analysis to a given \c PassManager. It is intended to be used
0829 /// during parsing of a pass pipeline when parsing a single PipelineName.
0830 /// When registering a new function analysis FancyAnalysis with the pass
0831 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
0832 /// like this:
0833 ///
0834 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
0835 ///                                   ArrayRef<PipelineElement> P) {
0836 ///   if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
0837 ///                                                 FPM))
0838 ///     return true;
0839 ///   return false;
0840 /// }
0841 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
0842           typename... ExtraArgTs>
0843 bool parseAnalysisUtilityPasses(
0844     StringRef AnalysisName, StringRef PipelineName,
0845     PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
0846   if (!PipelineName.ends_with(">"))
0847     return false;
0848   // See if this is an invalidate<> pass name
0849   if (PipelineName.starts_with("invalidate<")) {
0850     PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
0851     if (PipelineName != AnalysisName)
0852       return false;
0853     PM.addPass(InvalidateAnalysisPass<AnalysisT>());
0854     return true;
0855   }
0856 
0857   // See if this is a require<> pass name
0858   if (PipelineName.starts_with("require<")) {
0859     PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
0860     if (PipelineName != AnalysisName)
0861       return false;
0862     PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
0863                                    ExtraArgTs...>());
0864     return true;
0865   }
0866 
0867   return false;
0868 }
0869 
0870 // These are special since they are only for testing purposes.
0871 
0872 /// No-op module pass which does nothing.
0873 struct NoOpModulePass : PassInfoMixin<NoOpModulePass> {
0874   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
0875     return PreservedAnalyses::all();
0876   }
0877 };
0878 
0879 /// No-op module analysis.
0880 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
0881   friend AnalysisInfoMixin<NoOpModuleAnalysis>;
0882   static AnalysisKey Key;
0883 
0884 public:
0885   struct Result {};
0886   Result run(Module &, ModuleAnalysisManager &) { return Result(); }
0887 };
0888 
0889 /// No-op CGSCC pass which does nothing.
0890 struct NoOpCGSCCPass : PassInfoMixin<NoOpCGSCCPass> {
0891   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
0892                         LazyCallGraph &, CGSCCUpdateResult &UR) {
0893     return PreservedAnalyses::all();
0894   }
0895 };
0896 
0897 /// No-op CGSCC analysis.
0898 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
0899   friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
0900   static AnalysisKey Key;
0901 
0902 public:
0903   struct Result {};
0904   Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
0905     return Result();
0906   }
0907 };
0908 
0909 /// No-op function pass which does nothing.
0910 struct NoOpFunctionPass : PassInfoMixin<NoOpFunctionPass> {
0911   PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
0912     return PreservedAnalyses::all();
0913   }
0914 };
0915 
0916 /// No-op function analysis.
0917 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
0918   friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
0919   static AnalysisKey Key;
0920 
0921 public:
0922   struct Result {};
0923   Result run(Function &, FunctionAnalysisManager &) { return Result(); }
0924 };
0925 
0926 /// No-op loop nest pass which does nothing.
0927 struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
0928   PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
0929                         LoopStandardAnalysisResults &, LPMUpdater &) {
0930     return PreservedAnalyses::all();
0931   }
0932 };
0933 
0934 /// No-op loop pass which does nothing.
0935 struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
0936   PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
0937                         LoopStandardAnalysisResults &, LPMUpdater &) {
0938     return PreservedAnalyses::all();
0939   }
0940 };
0941 
0942 /// No-op machine function pass which does nothing.
0943 struct NoOpMachineFunctionPass : public PassInfoMixin<NoOpMachineFunctionPass> {
0944   PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
0945     return PreservedAnalyses::all();
0946   }
0947 };
0948 
0949 /// No-op loop analysis.
0950 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
0951   friend AnalysisInfoMixin<NoOpLoopAnalysis>;
0952   static AnalysisKey Key;
0953 
0954 public:
0955   struct Result {};
0956   Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
0957     return Result();
0958   }
0959 };
0960 
0961 /// Common option used by multiple tools to print pipeline passes
0962 extern cl::opt<bool> PrintPipelinePasses;
0963 
0964 }
0965 
0966 #endif