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