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