xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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/Analysis/CGSCCPassManager.h"
19 #include "llvm/CodeGen/MachinePassManager.h"
20 #include "llvm/CodeGen/RegAllocCommon.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/Passes/OptimizationLevel.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/Support/PGOOptions.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Transforms/IPO/Inliner.h"
27 #include "llvm/Transforms/IPO/ModuleInliner.h"
28 #include "llvm/Transforms/Instrumentation.h"
29 #include "llvm/Transforms/Scalar/LoopPassManager.h"
30 #include <optional>
31 #include <vector>
32 
33 namespace llvm {
34 class StringRef;
35 class AAManager;
36 class TargetMachine;
37 class ModuleSummaryIndex;
38 template <typename T> class IntrusiveRefCntPtr;
39 namespace vfs {
40 class FileSystem;
41 } // namespace vfs
42 
43 /// Tunable parameters for passes in the default pipelines.
44 class PipelineTuningOptions {
45 public:
46   /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
47   /// can be set in the PassBuilder when using a LLVM as a library.
48   PipelineTuningOptions();
49 
50   /// Tuning option to set loop interleaving on/off, set based on opt level.
51   bool LoopInterleaving;
52 
53   /// Tuning option to enable/disable loop vectorization, set based on opt
54   /// level.
55   bool LoopVectorization;
56 
57   /// Tuning option to enable/disable slp loop vectorization, set based on opt
58   /// level.
59   bool SLPVectorization;
60 
61   /// Tuning option to enable/disable loop unrolling. Its default value is true.
62   bool LoopUnrolling;
63 
64   /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
65   /// is that of the flag: `-forget-scev-loop-unroll`.
66   bool ForgetAllSCEVInLoopUnroll;
67 
68   /// Tuning option to cap the number of calls to retrive clobbering accesses in
69   /// MemorySSA, in LICM.
70   unsigned LicmMssaOptCap;
71 
72   /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
73   /// the number of access is too large.
74   unsigned LicmMssaNoAccForPromotionCap;
75 
76   /// Tuning option to enable/disable call graph profile. Its default value is
77   /// that of the flag: `-enable-npm-call-graph-profile`.
78   bool CallGraphProfile;
79 
80   // Add LTO pipeline tuning option to enable the unified LTO pipeline.
81   bool UnifiedLTO;
82 
83   /// Tuning option to enable/disable function merging. Its default value is
84   /// false.
85   bool MergeFunctions;
86 
87   /// Tuning option to override the default inliner threshold.
88   int InlinerThreshold;
89 
90   // Experimental option to eagerly invalidate more analyses. This has the
91   // potential to decrease max memory usage in exchange for more compile time.
92   // This may affect codegen due to either passes using analyses only when
93   // cached, or invalidating and recalculating an analysis that was
94   // stale/imprecise but still valid. Currently this invalidates all function
95   // analyses after various module->function or cgscc->function adaptors in the
96   // default pipelines.
97   bool EagerlyInvalidateAnalyses;
98 };
99 
100 /// This class provides access to building LLVM's passes.
101 ///
102 /// Its members provide the baseline state available to passes during their
103 /// construction. The \c PassRegistry.def file specifies how to construct all
104 /// of the built-in passes, and those may reference these members during
105 /// construction.
106 class PassBuilder {
107   TargetMachine *TM;
108   PipelineTuningOptions PTO;
109   std::optional<PGOOptions> PGOOpt;
110   PassInstrumentationCallbacks *PIC;
111 
112 public:
113   /// A struct to capture parsed pass pipeline names.
114   ///
115   /// A pipeline is defined as a series of names, each of which may in itself
116   /// recursively contain a nested pipeline. A name is either the name of a pass
117   /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
118   /// name is the name of a pass, the InnerPipeline is empty, since passes
119   /// cannot contain inner pipelines. See parsePassPipeline() for a more
120   /// detailed description of the textual pipeline format.
121   struct PipelineElement {
122     StringRef Name;
123     std::vector<PipelineElement> InnerPipeline;
124   };
125 
126   explicit PassBuilder(TargetMachine *TM = nullptr,
127                        PipelineTuningOptions PTO = PipelineTuningOptions(),
128                        std::optional<PGOOptions> PGOOpt = std::nullopt,
129                        PassInstrumentationCallbacks *PIC = nullptr);
130 
131   /// Cross register the analysis managers through their proxies.
132   ///
133   /// This is an interface that can be used to cross register each
134   /// AnalysisManager with all the others analysis managers.
135   void crossRegisterProxies(LoopAnalysisManager &LAM,
136                             FunctionAnalysisManager &FAM,
137                             CGSCCAnalysisManager &CGAM,
138                             ModuleAnalysisManager &MAM,
139                             MachineFunctionAnalysisManager *MFAM = nullptr);
140 
141   /// Registers all available module analysis passes.
142   ///
143   /// This is an interface that can be used to populate a \c
144   /// ModuleAnalysisManager with all registered module analyses. Callers can
145   /// still manually register any additional analyses. Callers can also
146   /// pre-register analyses and this will not override those.
147   void registerModuleAnalyses(ModuleAnalysisManager &MAM);
148 
149   /// Registers all available CGSCC analysis passes.
150   ///
151   /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
152   /// with all registered CGSCC analyses. Callers can still manually register any
153   /// additional analyses. Callers can also pre-register analyses and this will
154   /// not override those.
155   void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
156 
157   /// Registers all available function analysis passes.
158   ///
159   /// This is an interface that can be used to populate a \c
160   /// FunctionAnalysisManager with all registered function analyses. Callers can
161   /// still manually register any additional analyses. Callers can also
162   /// pre-register analyses and this will not override those.
163   void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
164 
165   /// Registers all available loop analysis passes.
166   ///
167   /// This is an interface that can be used to populate a \c LoopAnalysisManager
168   /// with all registered loop analyses. Callers can still manually register any
169   /// additional analyses.
170   void registerLoopAnalyses(LoopAnalysisManager &LAM);
171 
172   /// Registers all available machine function analysis passes.
173   ///
174   /// This is an interface that can be used to populate a \c
175   /// MachineFunctionAnalysisManager with all registered function analyses.
176   /// Callers can still manually register any additional analyses. Callers can
177   /// also pre-register analyses and this will not override those.
178   void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM);
179 
180   /// Construct the core LLVM function canonicalization and simplification
181   /// pipeline.
182   ///
183   /// This is a long pipeline and uses most of the per-function optimization
184   /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
185   /// repeatedly over the IR and is not expected to destroy important
186   /// information about the semantics of the IR.
187   ///
188   /// Note that \p Level cannot be `O0` here. The pipelines produced are
189   /// only intended for use when attempting to optimize code. If frontends
190   /// require some transformations for semantic reasons, they should explicitly
191   /// build them.
192   ///
193   /// \p Phase indicates the current ThinLTO phase.
194   FunctionPassManager
195   buildFunctionSimplificationPipeline(OptimizationLevel Level,
196                                       ThinOrFullLTOPhase Phase);
197 
198   /// Construct the core LLVM module canonicalization and simplification
199   /// pipeline.
200   ///
201   /// This pipeline focuses on canonicalizing and simplifying the entire module
202   /// of IR. Much like the function simplification pipeline above, it is
203   /// suitable to run repeatedly over the IR and is not expected to destroy
204   /// important information. It does, however, perform inlining and other
205   /// heuristic based simplifications that are not strictly reversible.
206   ///
207   /// Note that \p Level cannot be `O0` here. The pipelines produced are
208   /// only intended for use when attempting to optimize code. If frontends
209   /// require some transformations for semantic reasons, they should explicitly
210   /// build them.
211   ///
212   /// \p Phase indicates the current ThinLTO phase.
213   ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
214                                                       ThinOrFullLTOPhase Phase);
215 
216   /// Construct the module pipeline that performs inlining as well as
217   /// the inlining-driven cleanups.
218   ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
219                                                 ThinOrFullLTOPhase Phase);
220 
221   /// Construct the module pipeline that performs inlining with
222   /// module inliner pass.
223   ModulePassManager buildModuleInlinerPipeline(OptimizationLevel Level,
224                                                ThinOrFullLTOPhase Phase);
225 
226   /// Construct the core LLVM module optimization pipeline.
227   ///
228   /// This pipeline focuses on optimizing the execution speed of the IR. It
229   /// uses cost modeling and thresholds to balance code growth against runtime
230   /// improvements. It includes vectorization and other information destroying
231   /// transformations. It also cannot generally be run repeatedly on a module
232   /// without potentially seriously regressing either runtime performance of
233   /// the code or serious code size growth.
234   ///
235   /// Note that \p Level cannot be `O0` here. The pipelines produced are
236   /// only intended for use when attempting to optimize code. If frontends
237   /// require some transformations for semantic reasons, they should explicitly
238   /// build them.
239   ModulePassManager
240   buildModuleOptimizationPipeline(OptimizationLevel Level,
241                                   ThinOrFullLTOPhase LTOPhase);
242 
243   /// Build a per-module default optimization pipeline.
244   ///
245   /// This provides a good default optimization pipeline for per-module
246   /// optimization and code generation without any link-time optimization. It
247   /// typically correspond to frontend "-O[123]" options for optimization
248   /// levels \c O1, \c O2 and \c O3 resp.
249   ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level,
250                                                   bool LTOPreLink = false);
251 
252   /// Build a fat object default optimization pipeline.
253   ///
254   /// This builds a pipeline that runs the LTO/ThinLTO  pre-link pipeline, and
255   /// emits a section containing the pre-link bitcode along side the object code
256   /// generated in non-LTO compilation.
257   ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
258                                                bool ThinLTO, bool EmitSummary);
259 
260   /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
261   /// a pass manager.
262   ///
263   /// This adds the pre-link optimizations tuned to prepare a module for
264   /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
265   /// without making irreversible decisions which could be made better during
266   /// the LTO run.
267   ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
268 
269   /// Build a ThinLTO default optimization pipeline to a pass manager.
270   ///
271   /// This provides a good default optimization pipeline for link-time
272   /// optimization and code generation. It is particularly tuned to fit well
273   /// when IR coming into the LTO phase was first run through \c
274   /// buildThinLTOPreLinkDefaultPipeline, and the two coordinate closely.
275   ModulePassManager
276   buildThinLTODefaultPipeline(OptimizationLevel Level,
277                               const ModuleSummaryIndex *ImportSummary);
278 
279   /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
280   /// manager.
281   ///
282   /// This adds the pre-link optimizations tuned to work well with a later LTO
283   /// run. It works to minimize the IR which needs to be analyzed without
284   /// making irreversible decisions which could be made better during the LTO
285   /// run.
286   ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
287 
288   /// Build an LTO default optimization pipeline to a pass manager.
289   ///
290   /// This provides a good default optimization pipeline for link-time
291   /// optimization and code generation. It is particularly tuned to fit well
292   /// when IR coming into the LTO phase was first run through \c
293   /// buildLTOPreLinkDefaultPipeline, and the two coordinate closely.
294   ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
295                                             ModuleSummaryIndex *ExportSummary);
296 
297   /// Build an O0 pipeline with the minimal semantically required passes.
298   ///
299   /// This should only be used for non-LTO and LTO pre-link pipelines.
300   ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level,
301                                            bool LTOPreLink = false);
302 
303   /// Build the default `AAManager` with the default alias analysis pipeline
304   /// registered.
305   ///
306   /// This also adds target-specific alias analyses registered via
307   /// TargetMachine::registerDefaultAliasAnalyses().
308   AAManager buildDefaultAAPipeline();
309 
310   /// Parse a textual pass pipeline description into a \c
311   /// ModulePassManager.
312   ///
313   /// The format of the textual pass pipeline description looks something like:
314   ///
315   ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
316   ///
317   /// Pass managers have ()s describing the nest structure of passes. All passes
318   /// are comma separated. As a special shortcut, if the very first pass is not
319   /// a module pass (as a module pass manager is), this will automatically form
320   /// the shortest stack of pass managers that allow inserting that first pass.
321   /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
322   /// passes 'lpassN', all of these are valid:
323   ///
324   ///   fpass1,fpass2,fpass3
325   ///   cgpass1,cgpass2,cgpass3
326   ///   lpass1,lpass2,lpass3
327   ///
328   /// And they are equivalent to the following (resp.):
329   ///
330   ///   module(function(fpass1,fpass2,fpass3))
331   ///   module(cgscc(cgpass1,cgpass2,cgpass3))
332   ///   module(function(loop(lpass1,lpass2,lpass3)))
333   ///
334   /// This shortcut is especially useful for debugging and testing small pass
335   /// combinations.
336   ///
337   /// The sequence of passes aren't necessarily the exact same kind of pass.
338   /// You can mix different levels implicitly if adaptor passes are defined to
339   /// make them work. For example,
340   ///
341   ///   mpass1,fpass1,fpass2,mpass2,lpass1
342   ///
343   /// This pipeline uses only one pass manager: the top-level module manager.
344   /// fpass1,fpass2 and lpass1 are added into the top-level module manager
345   /// using only adaptor passes. No nested function/loop pass managers are
346   /// added. The purpose is to allow easy pass testing when the user
347   /// specifically want the pass to run under a adaptor directly. This is
348   /// preferred when a pipeline is largely of one type, but one or just a few
349   /// passes are of different types(See PassBuilder.cpp for examples).
350   Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
351 
352   /// {{@ Parse a textual pass pipeline description into a specific PassManager
353   ///
354   /// Automatic deduction of an appropriate pass manager stack is not supported.
355   /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
356   /// this is the valid pipeline text:
357   ///
358   ///   function(lpass)
359   Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
360   Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
361   Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
362   /// @}}
363 
364   /// Parse a textual MIR pipeline into the provided \c MachineFunctionPass
365   /// manager.
366   /// The format of the textual machine pipeline is a comma separated list of
367   /// machine pass names:
368   ///
369   ///   machine-funciton-pass,machine-module-pass,...
370   ///
371   /// There is no need to specify the pass nesting, and this function
372   /// currently cannot handle the pass nesting.
373   Error parsePassPipeline(MachineFunctionPassManager &MFPM,
374                           StringRef PipelineText);
375 
376   /// Parse a textual alias analysis pipeline into the provided AA manager.
377   ///
378   /// The format of the textual AA pipeline is a comma separated list of AA
379   /// pass names:
380   ///
381   ///   basic-aa,globals-aa,...
382   ///
383   /// The AA manager is set up such that the provided alias analyses are tried
384   /// in the order specified. See the \c AAManaager documentation for details
385   /// about the logic used. This routine just provides the textual mapping
386   /// between AA names and the analyses to register with the manager.
387   ///
388   /// Returns false if the text cannot be parsed cleanly. The specific state of
389   /// the \p AA manager is unspecified if such an error is encountered and this
390   /// returns false.
391   Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
392 
393   /// Parse RegAllocFilterName to get RegAllocFilterFunc.
394   std::optional<RegAllocFilterFunc>
395   parseRegAllocFilter(StringRef RegAllocFilterName);
396 
397   /// Print pass names.
398   void printPassNames(raw_ostream &OS);
399 
400   /// Register a callback for a default optimizer pipeline extension
401   /// point
402   ///
403   /// This extension point allows adding passes that perform peephole
404   /// optimizations similar to the instruction combiner. These passes will be
405   /// inserted after each instance of the instruction combiner pass.
registerPeepholeEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)406   void registerPeepholeEPCallback(
407       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
408     PeepholeEPCallbacks.push_back(C);
409   }
410 
411   /// Register a callback for a default optimizer pipeline extension
412   /// point
413   ///
414   /// This extension point allows adding late loop canonicalization and
415   /// simplification passes. This is the last point in the loop optimization
416   /// pipeline before loop deletion. Each pass added
417   /// here must be an instance of LoopPass.
418   /// This is the place to add passes that can remove loops, such as target-
419   /// specific loop idiom recognition.
registerLateLoopOptimizationsEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)420   void registerLateLoopOptimizationsEPCallback(
421       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
422     LateLoopOptimizationsEPCallbacks.push_back(C);
423   }
424 
425   /// Register a callback for a default optimizer pipeline extension
426   /// point
427   ///
428   /// This extension point allows adding loop passes to the end of the loop
429   /// optimizer.
registerLoopOptimizerEndEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)430   void registerLoopOptimizerEndEPCallback(
431       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
432     LoopOptimizerEndEPCallbacks.push_back(C);
433   }
434 
435   /// Register a callback for a default optimizer pipeline extension
436   /// point
437   ///
438   /// This extension point allows adding optimization passes after most of the
439   /// main optimizations, but before the last cleanup-ish optimizations.
registerScalarOptimizerLateEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)440   void registerScalarOptimizerLateEPCallback(
441       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
442     ScalarOptimizerLateEPCallbacks.push_back(C);
443   }
444 
445   /// Register a callback for a default optimizer pipeline extension
446   /// point
447   ///
448   /// This extension point allows adding CallGraphSCC passes at the end of the
449   /// main CallGraphSCC passes and before any function simplification passes run
450   /// by CGPassManager.
registerCGSCCOptimizerLateEPCallback(const std::function<void (CGSCCPassManager &,OptimizationLevel)> & C)451   void registerCGSCCOptimizerLateEPCallback(
452       const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
453     CGSCCOptimizerLateEPCallbacks.push_back(C);
454   }
455 
456   /// Register a callback for a default optimizer pipeline extension
457   /// point
458   ///
459   /// This extension point allows adding optimization passes before the
460   /// vectorizer and other highly target specific optimization passes are
461   /// executed.
registerVectorizerStartEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)462   void registerVectorizerStartEPCallback(
463       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
464     VectorizerStartEPCallbacks.push_back(C);
465   }
466 
467   /// Register a callback for a default optimizer pipeline extension point.
468   ///
469   /// This extension point allows adding optimization once at the start of the
470   /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
471   /// link-time pipelines).
registerPipelineStartEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)472   void registerPipelineStartEPCallback(
473       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
474     PipelineStartEPCallbacks.push_back(C);
475   }
476 
477   /// Register a callback for a default optimizer pipeline extension point.
478   ///
479   /// This extension point allows adding optimization right after passes that do
480   /// basic simplification of the input IR.
registerPipelineEarlySimplificationEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)481   void registerPipelineEarlySimplificationEPCallback(
482       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
483     PipelineEarlySimplificationEPCallbacks.push_back(C);
484   }
485 
486   /// Register a callback for a default optimizer pipeline extension point
487   ///
488   /// This extension point allows adding optimizations before the function
489   /// optimization pipeline.
registerOptimizerEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)490   void registerOptimizerEarlyEPCallback(
491       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
492     OptimizerEarlyEPCallbacks.push_back(C);
493   }
494 
495   /// Register a callback for a default optimizer pipeline extension point
496   ///
497   /// This extension point allows adding optimizations at the very end of the
498   /// function optimization pipeline.
registerOptimizerLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)499   void registerOptimizerLastEPCallback(
500       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
501     OptimizerLastEPCallbacks.push_back(C);
502   }
503 
504   /// Register a callback for a default optimizer pipeline extension point
505   ///
506   /// This extension point allows adding optimizations at the start of the full
507   /// LTO pipeline.
registerFullLinkTimeOptimizationEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)508   void registerFullLinkTimeOptimizationEarlyEPCallback(
509       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
510     FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C);
511   }
512 
513   /// Register a callback for a default optimizer pipeline extension point
514   ///
515   /// This extension point allows adding optimizations at the end of the full
516   /// LTO pipeline.
registerFullLinkTimeOptimizationLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)517   void registerFullLinkTimeOptimizationLastEPCallback(
518       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
519     FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
520   }
521 
522   /// Register a callback for parsing an AliasAnalysis Name to populate
523   /// the given AAManager \p AA
registerParseAACallback(const std::function<bool (StringRef Name,AAManager & AA)> & C)524   void registerParseAACallback(
525       const std::function<bool(StringRef Name, AAManager &AA)> &C) {
526     AAParsingCallbacks.push_back(C);
527   }
528 
529   /// {{@ Register callbacks for analysis registration with this PassBuilder
530   /// instance.
531   /// Callees register their analyses with the given AnalysisManager objects.
registerAnalysisRegistrationCallback(const std::function<void (CGSCCAnalysisManager &)> & C)532   void registerAnalysisRegistrationCallback(
533       const std::function<void(CGSCCAnalysisManager &)> &C) {
534     CGSCCAnalysisRegistrationCallbacks.push_back(C);
535   }
registerAnalysisRegistrationCallback(const std::function<void (FunctionAnalysisManager &)> & C)536   void registerAnalysisRegistrationCallback(
537       const std::function<void(FunctionAnalysisManager &)> &C) {
538     FunctionAnalysisRegistrationCallbacks.push_back(C);
539   }
registerAnalysisRegistrationCallback(const std::function<void (LoopAnalysisManager &)> & C)540   void registerAnalysisRegistrationCallback(
541       const std::function<void(LoopAnalysisManager &)> &C) {
542     LoopAnalysisRegistrationCallbacks.push_back(C);
543   }
registerAnalysisRegistrationCallback(const std::function<void (ModuleAnalysisManager &)> & C)544   void registerAnalysisRegistrationCallback(
545       const std::function<void(ModuleAnalysisManager &)> &C) {
546     ModuleAnalysisRegistrationCallbacks.push_back(C);
547   }
registerAnalysisRegistrationCallback(const std::function<void (MachineFunctionAnalysisManager &)> & C)548   void registerAnalysisRegistrationCallback(
549       const std::function<void(MachineFunctionAnalysisManager &)> &C) {
550     MachineFunctionAnalysisRegistrationCallbacks.push_back(C);
551   }
552   /// @}}
553 
554   /// {{@ Register pipeline parsing callbacks with this pass builder instance.
555   /// Using these callbacks, callers can parse both a single pass name, as well
556   /// as entire sub-pipelines, and populate the PassManager instance
557   /// accordingly.
registerPipelineParsingCallback(const std::function<bool (StringRef Name,CGSCCPassManager &,ArrayRef<PipelineElement>)> & C)558   void registerPipelineParsingCallback(
559       const std::function<bool(StringRef Name, CGSCCPassManager &,
560                                ArrayRef<PipelineElement>)> &C) {
561     CGSCCPipelineParsingCallbacks.push_back(C);
562   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,FunctionPassManager &,ArrayRef<PipelineElement>)> & C)563   void registerPipelineParsingCallback(
564       const std::function<bool(StringRef Name, FunctionPassManager &,
565                                ArrayRef<PipelineElement>)> &C) {
566     FunctionPipelineParsingCallbacks.push_back(C);
567   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,LoopPassManager &,ArrayRef<PipelineElement>)> & C)568   void registerPipelineParsingCallback(
569       const std::function<bool(StringRef Name, LoopPassManager &,
570                                ArrayRef<PipelineElement>)> &C) {
571     LoopPipelineParsingCallbacks.push_back(C);
572   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,ModulePassManager &,ArrayRef<PipelineElement>)> & C)573   void registerPipelineParsingCallback(
574       const std::function<bool(StringRef Name, ModulePassManager &,
575                                ArrayRef<PipelineElement>)> &C) {
576     ModulePipelineParsingCallbacks.push_back(C);
577   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,MachineFunctionPassManager &,ArrayRef<PipelineElement>)> & C)578   void registerPipelineParsingCallback(
579       const std::function<bool(StringRef Name, MachineFunctionPassManager &,
580                                ArrayRef<PipelineElement>)> &C) {
581     MachineFunctionPipelineParsingCallbacks.push_back(C);
582   }
583   /// @}}
584 
585   /// Register callbacks to parse target specific filter field if regalloc pass
586   /// needs it. E.g. AMDGPU requires regalloc passes can handle sgpr and vgpr
587   /// separately.
registerRegClassFilterParsingCallback(const std::function<RegAllocFilterFunc (StringRef)> & C)588   void registerRegClassFilterParsingCallback(
589       const std::function<RegAllocFilterFunc(StringRef)> &C) {
590     RegClassFilterParsingCallbacks.push_back(C);
591   }
592 
593   /// Register a callback for a top-level pipeline entry.
594   ///
595   /// If the PassManager type is not given at the top level of the pipeline
596   /// text, this Callback should be used to determine the appropriate stack of
597   /// PassManagers and populate the passed ModulePassManager.
598   void registerParseTopLevelPipelineCallback(
599       const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
600           &C);
601 
602   /// Add PGOInstrumenation passes for O0 only.
603   void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
604                               bool IsCS, bool AtomicCounterUpdate,
605                               std::string ProfileFile,
606                               std::string ProfileRemappingFile,
607                               IntrusiveRefCntPtr<vfs::FileSystem> FS);
608 
609   /// Returns PIC. External libraries can use this to register pass
610   /// instrumentation callbacks.
getPassInstrumentationCallbacks()611   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
612     return PIC;
613   }
614 
615   // Invoke the callbacks registered for the various extension points.
616   // Custom pipelines should use these to invoke the callbacks registered
617   // by TargetMachines and other clients.
618   void invokePeepholeEPCallbacks(FunctionPassManager &FPM,
619                                  OptimizationLevel Level);
620   void invokeLateLoopOptimizationsEPCallbacks(LoopPassManager &LPM,
621                                               OptimizationLevel Level);
622   void invokeLoopOptimizerEndEPCallbacks(LoopPassManager &LPM,
623                                          OptimizationLevel Level);
624   void invokeScalarOptimizerLateEPCallbacks(FunctionPassManager &FPM,
625                                             OptimizationLevel Level);
626   void invokeCGSCCOptimizerLateEPCallbacks(CGSCCPassManager &CGPM,
627                                            OptimizationLevel Level);
628   void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
629                                         OptimizationLevel Level);
630   void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
631                                        OptimizationLevel Level);
632   void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
633                                       OptimizationLevel Level);
634   void invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
635                                                       OptimizationLevel Level);
636   void invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
637                                                      OptimizationLevel Level);
638   void invokePipelineStartEPCallbacks(ModulePassManager &MPM,
639                                       OptimizationLevel Level);
640   void invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM,
641                                                     OptimizationLevel Level);
642 
checkParametrizedPassName(StringRef Name,StringRef PassName)643   static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
644     if (!Name.consume_front(PassName))
645       return false;
646     // normal pass name w/o parameters == default parameters
647     if (Name.empty())
648       return true;
649     return Name.starts_with("<") && Name.ends_with(">");
650   }
651 
652   /// This performs customized parsing of pass name with parameters.
653   ///
654   /// We do not need parametrization of passes in textual pipeline very often,
655   /// yet on a rare occasion ability to specify parameters right there can be
656   /// useful.
657   ///
658   /// \p Name - parameterized specification of a pass from a textual pipeline
659   /// is a string in a form of :
660   ///      PassName '<' parameter-list '>'
661   ///
662   /// Parameter list is being parsed by the parser callable argument, \p Parser,
663   /// It takes a string-ref of parameters and returns either StringError or a
664   /// parameter list in a form of a custom parameters type, all wrapped into
665   /// Expected<> template class.
666   ///
667   template <typename ParametersParseCallableT>
668   static auto parsePassParameters(ParametersParseCallableT &&Parser,
669                                   StringRef Name, StringRef PassName)
670       -> decltype(Parser(StringRef{})) {
671     using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
672 
673     StringRef Params = Name;
674     if (!Params.consume_front(PassName)) {
675       llvm_unreachable(
676           "unable to strip pass name from parametrized pass specification");
677     }
678     if (!Params.empty() &&
679         (!Params.consume_front("<") || !Params.consume_back(">"))) {
680       llvm_unreachable("invalid format for parametrized pass name");
681     }
682 
683     Expected<ParametersT> Result = Parser(Params);
684     assert((Result || Result.template errorIsA<StringError>()) &&
685            "Pass parameter parser can only return StringErrors.");
686     return Result;
687   }
688 
689   /// Handle passes only accept one bool-valued parameter.
690   ///
691   /// \return false when Params is empty.
692   static Expected<bool> parseSinglePassOption(StringRef Params,
693                                               StringRef OptionName,
694                                               StringRef PassName);
695 
696 private:
697   // O1 pass pipeline
698   FunctionPassManager
699   buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
700                                         ThinOrFullLTOPhase Phase);
701 
702   void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
703 
704   void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
705                        bool IsFullLTO);
706 
707   static std::optional<std::vector<PipelineElement>>
708   parsePipelineText(StringRef Text);
709 
710   Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
711   Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
712   Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
713   Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
714   Error parseMachinePass(MachineFunctionPassManager &MFPM,
715                          const PipelineElement &E);
716   bool parseAAPassName(AAManager &AA, StringRef Name);
717 
718   Error parseMachinePassPipeline(MachineFunctionPassManager &MFPM,
719                                  ArrayRef<PipelineElement> Pipeline);
720   Error parseLoopPassPipeline(LoopPassManager &LPM,
721                               ArrayRef<PipelineElement> Pipeline);
722   Error parseFunctionPassPipeline(FunctionPassManager &FPM,
723                                   ArrayRef<PipelineElement> Pipeline);
724   Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
725                                ArrayRef<PipelineElement> Pipeline);
726   Error parseModulePassPipeline(ModulePassManager &MPM,
727                                 ArrayRef<PipelineElement> Pipeline);
728 
729   // Adds passes to do pre-inlining and related cleanup passes before
730   // profile instrumentation/matching (to enable better context sensitivity),
731   // and for memprof to enable better matching with missing debug frames.
732   void addPreInlinerPasses(ModulePassManager &MPM, OptimizationLevel Level,
733                            ThinOrFullLTOPhase LTOPhase);
734 
735   void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
736                          bool RunProfileGen, bool IsCS,
737                          bool AtomicCounterUpdate, std::string ProfileFile,
738                          std::string ProfileRemappingFile,
739                          IntrusiveRefCntPtr<vfs::FileSystem> FS);
740   void addPostPGOLoopRotation(ModulePassManager &MPM, OptimizationLevel Level);
741 
742   // Extension Point callbacks
743   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
744       PeepholeEPCallbacks;
745   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
746       LateLoopOptimizationsEPCallbacks;
747   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
748       LoopOptimizerEndEPCallbacks;
749   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
750       ScalarOptimizerLateEPCallbacks;
751   SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
752       CGSCCOptimizerLateEPCallbacks;
753   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
754       VectorizerStartEPCallbacks;
755   // Module callbacks
756   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
757       OptimizerEarlyEPCallbacks;
758   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
759       OptimizerLastEPCallbacks;
760   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
761       FullLinkTimeOptimizationEarlyEPCallbacks;
762   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
763       FullLinkTimeOptimizationLastEPCallbacks;
764   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
765       PipelineStartEPCallbacks;
766   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
767       PipelineEarlySimplificationEPCallbacks;
768 
769   SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
770       ModuleAnalysisRegistrationCallbacks;
771   SmallVector<std::function<bool(StringRef, ModulePassManager &,
772                                  ArrayRef<PipelineElement>)>,
773               2>
774       ModulePipelineParsingCallbacks;
775   SmallVector<
776       std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
777       TopLevelPipelineParsingCallbacks;
778   // CGSCC callbacks
779   SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
780       CGSCCAnalysisRegistrationCallbacks;
781   SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
782                                  ArrayRef<PipelineElement>)>,
783               2>
784       CGSCCPipelineParsingCallbacks;
785   // Function callbacks
786   SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
787       FunctionAnalysisRegistrationCallbacks;
788   SmallVector<std::function<bool(StringRef, FunctionPassManager &,
789                                  ArrayRef<PipelineElement>)>,
790               2>
791       FunctionPipelineParsingCallbacks;
792   // Loop callbacks
793   SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
794       LoopAnalysisRegistrationCallbacks;
795   SmallVector<std::function<bool(StringRef, LoopPassManager &,
796                                  ArrayRef<PipelineElement>)>,
797               2>
798       LoopPipelineParsingCallbacks;
799   // AA callbacks
800   SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
801       AAParsingCallbacks;
802   // Machine pass callbackcs
803   SmallVector<std::function<void(MachineFunctionAnalysisManager &)>, 2>
804       MachineFunctionAnalysisRegistrationCallbacks;
805   SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &,
806                                  ArrayRef<PipelineElement>)>,
807               2>
808       MachineFunctionPipelineParsingCallbacks;
809   // Callbacks to parse `filter` parameter in register allocation passes
810   SmallVector<std::function<RegAllocFilterFunc(StringRef)>, 2>
811       RegClassFilterParsingCallbacks;
812 };
813 
814 /// This utility template takes care of adding require<> and invalidate<>
815 /// passes for an analysis to a given \c PassManager. It is intended to be used
816 /// during parsing of a pass pipeline when parsing a single PipelineName.
817 /// When registering a new function analysis FancyAnalysis with the pass
818 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
819 /// like this:
820 ///
821 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
822 ///                                   ArrayRef<PipelineElement> P) {
823 ///   if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
824 ///                                                 FPM))
825 ///     return true;
826 ///   return false;
827 /// }
828 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
829           typename... ExtraArgTs>
parseAnalysisUtilityPasses(StringRef AnalysisName,StringRef PipelineName,PassManager<IRUnitT,AnalysisManagerT,ExtraArgTs...> & PM)830 bool parseAnalysisUtilityPasses(
831     StringRef AnalysisName, StringRef PipelineName,
832     PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
833   if (!PipelineName.ends_with(">"))
834     return false;
835   // See if this is an invalidate<> pass name
836   if (PipelineName.starts_with("invalidate<")) {
837     PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
838     if (PipelineName != AnalysisName)
839       return false;
840     PM.addPass(InvalidateAnalysisPass<AnalysisT>());
841     return true;
842   }
843 
844   // See if this is a require<> pass name
845   if (PipelineName.starts_with("require<")) {
846     PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
847     if (PipelineName != AnalysisName)
848       return false;
849     PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
850                                    ExtraArgTs...>());
851     return true;
852   }
853 
854   return false;
855 }
856 
857 // These are special since they are only for testing purposes.
858 
859 /// No-op module pass which does nothing.
860 struct NoOpModulePass : PassInfoMixin<NoOpModulePass> {
runNoOpModulePass861   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
862     return PreservedAnalyses::all();
863   }
864 };
865 
866 /// No-op module analysis.
867 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
868   friend AnalysisInfoMixin<NoOpModuleAnalysis>;
869   static AnalysisKey Key;
870 
871 public:
872   struct Result {};
run(Module &,ModuleAnalysisManager &)873   Result run(Module &, ModuleAnalysisManager &) { return Result(); }
874 };
875 
876 /// No-op CGSCC pass which does nothing.
877 struct NoOpCGSCCPass : PassInfoMixin<NoOpCGSCCPass> {
runNoOpCGSCCPass878   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
879                         LazyCallGraph &, CGSCCUpdateResult &UR) {
880     return PreservedAnalyses::all();
881   }
882 };
883 
884 /// No-op CGSCC analysis.
885 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
886   friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
887   static AnalysisKey Key;
888 
889 public:
890   struct Result {};
run(LazyCallGraph::SCC &,CGSCCAnalysisManager &,LazyCallGraph & G)891   Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
892     return Result();
893   }
894 };
895 
896 /// No-op function pass which does nothing.
897 struct NoOpFunctionPass : PassInfoMixin<NoOpFunctionPass> {
runNoOpFunctionPass898   PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
899     return PreservedAnalyses::all();
900   }
901 };
902 
903 /// No-op function analysis.
904 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
905   friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
906   static AnalysisKey Key;
907 
908 public:
909   struct Result {};
run(Function &,FunctionAnalysisManager &)910   Result run(Function &, FunctionAnalysisManager &) { return Result(); }
911 };
912 
913 /// No-op loop nest pass which does nothing.
914 struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
runNoOpLoopNestPass915   PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
916                         LoopStandardAnalysisResults &, LPMUpdater &) {
917     return PreservedAnalyses::all();
918   }
919 };
920 
921 /// No-op loop pass which does nothing.
922 struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
runNoOpLoopPass923   PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
924                         LoopStandardAnalysisResults &, LPMUpdater &) {
925     return PreservedAnalyses::all();
926   }
927 };
928 
929 /// No-op machine function pass which does nothing.
930 struct NoOpMachineFunctionPass : public PassInfoMixin<NoOpMachineFunctionPass> {
runNoOpMachineFunctionPass931   PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
932     return PreservedAnalyses::all();
933   }
934 };
935 
936 /// No-op loop analysis.
937 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
938   friend AnalysisInfoMixin<NoOpLoopAnalysis>;
939   static AnalysisKey Key;
940 
941 public:
942   struct Result {};
run(Loop &,LoopAnalysisManager &,LoopStandardAnalysisResults &)943   Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
944     return Result();
945   }
946 };
947 }
948 
949 #endif
950