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                                                bool ThinLTO, bool EmitSummary);
251 
252   /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
253   /// a pass manager.
254   ///
255   /// This adds the pre-link optimizations tuned to prepare a module for
256   /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
257   /// without making irreversible decisions which could be made better during
258   /// the LTO run.
259   ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
260 
261   /// Build an ThinLTO default optimization pipeline to a pass manager.
262   ///
263   /// This provides a good default optimization pipeline for link-time
264   /// optimization and code generation. It is particularly tuned to fit well
265   /// when IR coming into the LTO phase was first run through \c
266   /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
267   ModulePassManager
268   buildThinLTODefaultPipeline(OptimizationLevel Level,
269                               const ModuleSummaryIndex *ImportSummary);
270 
271   /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
272   /// manager.
273   ///
274   /// This adds the pre-link optimizations tuned to work well with a later LTO
275   /// run. It works to minimize the IR which needs to be analyzed without
276   /// making irreversible decisions which could be made better during the LTO
277   /// run.
278   ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
279 
280   /// Build an LTO default optimization pipeline to a pass manager.
281   ///
282   /// This provides a good default optimization pipeline for link-time
283   /// optimization and code generation. It is particularly tuned to fit well
284   /// when IR coming into the LTO phase was first run through \c
285   /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
286   ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
287                                             ModuleSummaryIndex *ExportSummary);
288 
289   /// Build an O0 pipeline with the minimal semantically required passes.
290   ///
291   /// This should only be used for non-LTO and LTO pre-link pipelines.
292   ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level,
293                                            bool LTOPreLink = false);
294 
295   /// Build the default `AAManager` with the default alias analysis pipeline
296   /// registered.
297   ///
298   /// This also adds target-specific alias analyses registered via
299   /// TargetMachine::registerDefaultAliasAnalyses().
300   AAManager buildDefaultAAPipeline();
301 
302   /// Parse a textual pass pipeline description into a \c
303   /// ModulePassManager.
304   ///
305   /// The format of the textual pass pipeline description looks something like:
306   ///
307   ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
308   ///
309   /// Pass managers have ()s describing the nest structure of passes. All passes
310   /// are comma separated. As a special shortcut, if the very first pass is not
311   /// a module pass (as a module pass manager is), this will automatically form
312   /// the shortest stack of pass managers that allow inserting that first pass.
313   /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
314   /// passes 'lpassN', all of these are valid:
315   ///
316   ///   fpass1,fpass2,fpass3
317   ///   cgpass1,cgpass2,cgpass3
318   ///   lpass1,lpass2,lpass3
319   ///
320   /// And they are equivalent to the following (resp.):
321   ///
322   ///   module(function(fpass1,fpass2,fpass3))
323   ///   module(cgscc(cgpass1,cgpass2,cgpass3))
324   ///   module(function(loop(lpass1,lpass2,lpass3)))
325   ///
326   /// This shortcut is especially useful for debugging and testing small pass
327   /// combinations.
328   ///
329   /// The sequence of passes aren't necessarily the exact same kind of pass.
330   /// You can mix different levels implicitly if adaptor passes are defined to
331   /// make them work. For example,
332   ///
333   ///   mpass1,fpass1,fpass2,mpass2,lpass1
334   ///
335   /// This pipeline uses only one pass manager: the top-level module manager.
336   /// fpass1,fpass2 and lpass1 are added into the the top-level module manager
337   /// using only adaptor passes. No nested function/loop pass managers are
338   /// added. The purpose is to allow easy pass testing when the user
339   /// specifically want the pass to run under a adaptor directly. This is
340   /// preferred when a pipeline is largely of one type, but one or just a few
341   /// passes are of different types(See PassBuilder.cpp for examples).
342   Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
343 
344   /// {{@ Parse a textual pass pipeline description into a specific PassManager
345   ///
346   /// Automatic deduction of an appropriate pass manager stack is not supported.
347   /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
348   /// this is the valid pipeline text:
349   ///
350   ///   function(lpass)
351   Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
352   Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
353   Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
354   /// @}}
355 
356   /// Parse a textual alias analysis pipeline into the provided AA manager.
357   ///
358   /// The format of the textual AA pipeline is a comma separated list of AA
359   /// pass names:
360   ///
361   ///   basic-aa,globals-aa,...
362   ///
363   /// The AA manager is set up such that the provided alias analyses are tried
364   /// in the order specified. See the \c AAManaager documentation for details
365   /// about the logic used. This routine just provides the textual mapping
366   /// between AA names and the analyses to register with the manager.
367   ///
368   /// Returns false if the text cannot be parsed cleanly. The specific state of
369   /// the \p AA manager is unspecified if such an error is encountered and this
370   /// returns false.
371   Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
372 
373   /// Print pass names.
374   void printPassNames(raw_ostream &OS);
375 
376   /// Register a callback for a default optimizer pipeline extension
377   /// point
378   ///
379   /// This extension point allows adding passes that perform peephole
380   /// optimizations similar to the instruction combiner. These passes will be
381   /// inserted after each instance of the instruction combiner pass.
382   void registerPeepholeEPCallback(
383       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
384     PeepholeEPCallbacks.push_back(C);
385   }
386 
387   /// Register a callback for a default optimizer pipeline extension
388   /// point
389   ///
390   /// This extension point allows adding late loop canonicalization and
391   /// simplification passes. This is the last point in the loop optimization
392   /// pipeline before loop deletion. Each pass added
393   /// here must be an instance of LoopPass.
394   /// This is the place to add passes that can remove loops, such as target-
395   /// specific loop idiom recognition.
396   void registerLateLoopOptimizationsEPCallback(
397       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
398     LateLoopOptimizationsEPCallbacks.push_back(C);
399   }
400 
401   /// Register a callback for a default optimizer pipeline extension
402   /// point
403   ///
404   /// This extension point allows adding loop passes to the end of the loop
405   /// optimizer.
406   void registerLoopOptimizerEndEPCallback(
407       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
408     LoopOptimizerEndEPCallbacks.push_back(C);
409   }
410 
411   /// Register a callback for a default optimizer pipeline extension
412   /// point
413   ///
414   /// This extension point allows adding optimization passes after most of the
415   /// main optimizations, but before the last cleanup-ish optimizations.
416   void registerScalarOptimizerLateEPCallback(
417       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
418     ScalarOptimizerLateEPCallbacks.push_back(C);
419   }
420 
421   /// Register a callback for a default optimizer pipeline extension
422   /// point
423   ///
424   /// This extension point allows adding CallGraphSCC passes at the end of the
425   /// main CallGraphSCC passes and before any function simplification passes run
426   /// by CGPassManager.
427   void registerCGSCCOptimizerLateEPCallback(
428       const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
429     CGSCCOptimizerLateEPCallbacks.push_back(C);
430   }
431 
432   /// Register a callback for a default optimizer pipeline extension
433   /// point
434   ///
435   /// This extension point allows adding optimization passes before the
436   /// vectorizer and other highly target specific optimization passes are
437   /// executed.
438   void registerVectorizerStartEPCallback(
439       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
440     VectorizerStartEPCallbacks.push_back(C);
441   }
442 
443   /// Register a callback for a default optimizer pipeline extension point.
444   ///
445   /// This extension point allows adding optimization once at the start of the
446   /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
447   /// link-time pipelines).
448   void registerPipelineStartEPCallback(
449       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
450     PipelineStartEPCallbacks.push_back(C);
451   }
452 
453   /// Register a callback for a default optimizer pipeline extension point.
454   ///
455   /// This extension point allows adding optimization right after passes that do
456   /// basic simplification of the input IR.
457   void registerPipelineEarlySimplificationEPCallback(
458       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
459     PipelineEarlySimplificationEPCallbacks.push_back(C);
460   }
461 
462   /// Register a callback for a default optimizer pipeline extension point
463   ///
464   /// This extension point allows adding optimizations before the function
465   /// optimization pipeline.
466   void registerOptimizerEarlyEPCallback(
467       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
468     OptimizerEarlyEPCallbacks.push_back(C);
469   }
470 
471   /// Register a callback for a default optimizer pipeline extension point
472   ///
473   /// This extension point allows adding optimizations at the very end of the
474   /// function optimization pipeline.
475   void registerOptimizerLastEPCallback(
476       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
477     OptimizerLastEPCallbacks.push_back(C);
478   }
479 
480   /// Register a callback for a default optimizer pipeline extension point
481   ///
482   /// This extension point allows adding optimizations at the start of the full
483   /// LTO pipeline.
484   void registerFullLinkTimeOptimizationEarlyEPCallback(
485       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
486     FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C);
487   }
488 
489   /// Register a callback for a default optimizer pipeline extension point
490   ///
491   /// This extension point allows adding optimizations at the end of the full
492   /// LTO pipeline.
493   void registerFullLinkTimeOptimizationLastEPCallback(
494       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
495     FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
496   }
497 
498   /// Register a callback for parsing an AliasAnalysis Name to populate
499   /// the given AAManager \p AA
500   void registerParseAACallback(
501       const std::function<bool(StringRef Name, AAManager &AA)> &C) {
502     AAParsingCallbacks.push_back(C);
503   }
504 
505   /// {{@ Register callbacks for analysis registration with this PassBuilder
506   /// instance.
507   /// Callees register their analyses with the given AnalysisManager objects.
508   void registerAnalysisRegistrationCallback(
509       const std::function<void(CGSCCAnalysisManager &)> &C) {
510     CGSCCAnalysisRegistrationCallbacks.push_back(C);
511   }
512   void registerAnalysisRegistrationCallback(
513       const std::function<void(FunctionAnalysisManager &)> &C) {
514     FunctionAnalysisRegistrationCallbacks.push_back(C);
515   }
516   void registerAnalysisRegistrationCallback(
517       const std::function<void(LoopAnalysisManager &)> &C) {
518     LoopAnalysisRegistrationCallbacks.push_back(C);
519   }
520   void registerAnalysisRegistrationCallback(
521       const std::function<void(ModuleAnalysisManager &)> &C) {
522     ModuleAnalysisRegistrationCallbacks.push_back(C);
523   }
524   /// @}}
525 
526   /// {{@ Register pipeline parsing callbacks with this pass builder instance.
527   /// Using these callbacks, callers can parse both a single pass name, as well
528   /// as entire sub-pipelines, and populate the PassManager instance
529   /// accordingly.
530   void registerPipelineParsingCallback(
531       const std::function<bool(StringRef Name, CGSCCPassManager &,
532                                ArrayRef<PipelineElement>)> &C) {
533     CGSCCPipelineParsingCallbacks.push_back(C);
534   }
535   void registerPipelineParsingCallback(
536       const std::function<bool(StringRef Name, FunctionPassManager &,
537                                ArrayRef<PipelineElement>)> &C) {
538     FunctionPipelineParsingCallbacks.push_back(C);
539   }
540   void registerPipelineParsingCallback(
541       const std::function<bool(StringRef Name, LoopPassManager &,
542                                ArrayRef<PipelineElement>)> &C) {
543     LoopPipelineParsingCallbacks.push_back(C);
544   }
545   void registerPipelineParsingCallback(
546       const std::function<bool(StringRef Name, ModulePassManager &,
547                                ArrayRef<PipelineElement>)> &C) {
548     ModulePipelineParsingCallbacks.push_back(C);
549   }
550   /// @}}
551 
552   /// Register a callback for a top-level pipeline entry.
553   ///
554   /// If the PassManager type is not given at the top level of the pipeline
555   /// text, this Callback should be used to determine the appropriate stack of
556   /// PassManagers and populate the passed ModulePassManager.
557   void registerParseTopLevelPipelineCallback(
558       const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
559           &C);
560 
561   /// Add PGOInstrumenation passes for O0 only.
562   void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
563                               bool IsCS, 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.
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   void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
631                          bool RunProfileGen, bool IsCS, std::string ProfileFile,
632                          std::string ProfileRemappingFile,
633                          ThinOrFullLTOPhase LTOPhase,
634                          IntrusiveRefCntPtr<vfs::FileSystem> FS);
635 
636   // Extension Point callbacks
637   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
638       PeepholeEPCallbacks;
639   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
640       LateLoopOptimizationsEPCallbacks;
641   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
642       LoopOptimizerEndEPCallbacks;
643   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
644       ScalarOptimizerLateEPCallbacks;
645   SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
646       CGSCCOptimizerLateEPCallbacks;
647   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
648       VectorizerStartEPCallbacks;
649   // Module callbacks
650   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
651       OptimizerEarlyEPCallbacks;
652   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
653       OptimizerLastEPCallbacks;
654   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
655       FullLinkTimeOptimizationEarlyEPCallbacks;
656   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
657       FullLinkTimeOptimizationLastEPCallbacks;
658   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
659       PipelineStartEPCallbacks;
660   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
661       PipelineEarlySimplificationEPCallbacks;
662 
663   SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
664       ModuleAnalysisRegistrationCallbacks;
665   SmallVector<std::function<bool(StringRef, ModulePassManager &,
666                                  ArrayRef<PipelineElement>)>,
667               2>
668       ModulePipelineParsingCallbacks;
669   SmallVector<
670       std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
671       TopLevelPipelineParsingCallbacks;
672   // CGSCC callbacks
673   SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
674       CGSCCAnalysisRegistrationCallbacks;
675   SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
676                                  ArrayRef<PipelineElement>)>,
677               2>
678       CGSCCPipelineParsingCallbacks;
679   // Function callbacks
680   SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
681       FunctionAnalysisRegistrationCallbacks;
682   SmallVector<std::function<bool(StringRef, FunctionPassManager &,
683                                  ArrayRef<PipelineElement>)>,
684               2>
685       FunctionPipelineParsingCallbacks;
686   // Loop callbacks
687   SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
688       LoopAnalysisRegistrationCallbacks;
689   SmallVector<std::function<bool(StringRef, LoopPassManager &,
690                                  ArrayRef<PipelineElement>)>,
691               2>
692       LoopPipelineParsingCallbacks;
693   // AA callbacks
694   SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
695       AAParsingCallbacks;
696 };
697 
698 /// This utility template takes care of adding require<> and invalidate<>
699 /// passes for an analysis to a given \c PassManager. It is intended to be used
700 /// during parsing of a pass pipeline when parsing a single PipelineName.
701 /// When registering a new function analysis FancyAnalysis with the pass
702 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
703 /// like this:
704 ///
705 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
706 ///                                   ArrayRef<PipelineElement> P) {
707 ///   if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
708 ///                                                 FPM))
709 ///     return true;
710 ///   return false;
711 /// }
712 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
713           typename... ExtraArgTs>
714 bool parseAnalysisUtilityPasses(
715     StringRef AnalysisName, StringRef PipelineName,
716     PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
717   if (!PipelineName.endswith(">"))
718     return false;
719   // See if this is an invalidate<> pass name
720   if (PipelineName.startswith("invalidate<")) {
721     PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
722     if (PipelineName != AnalysisName)
723       return false;
724     PM.addPass(InvalidateAnalysisPass<AnalysisT>());
725     return true;
726   }
727 
728   // See if this is a require<> pass name
729   if (PipelineName.startswith("require<")) {
730     PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
731     if (PipelineName != AnalysisName)
732       return false;
733     PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
734                                    ExtraArgTs...>());
735     return true;
736   }
737 
738   return false;
739 }
740 }
741 
742 #endif
743