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