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