• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ADT/Optional.h"
19 #include "llvm/Analysis/CGSCCPassManager.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/Support/Error.h"
22 #include "llvm/Transforms/Instrumentation.h"
23 #include "llvm/Transforms/Scalar/LoopPassManager.h"
24 #include <vector>
25 
26 namespace llvm {
27 class StringRef;
28 class AAManager;
29 class TargetMachine;
30 class ModuleSummaryIndex;
31 
32 /// A struct capturing PGO tunables.
33 struct PGOOptions {
34   enum PGOAction { NoAction, IRInstr, IRUse, SampleUse };
35   enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse };
36   PGOOptions(std::string ProfileFile = "", std::string CSProfileGenFile = "",
37              std::string ProfileRemappingFile = "", PGOAction Action = NoAction,
38              CSPGOAction CSAction = NoCSAction, bool SamplePGOSupport = false)
ProfileFilePGOOptions39       : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile),
40         ProfileRemappingFile(ProfileRemappingFile), Action(Action),
41         CSAction(CSAction),
42         SamplePGOSupport(SamplePGOSupport || Action == SampleUse) {
43     // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can
44     // callback with IRUse action without ProfileFile.
45 
46     // If there is a CSAction, PGOAction cannot be IRInstr or SampleUse.
47     assert(this->CSAction == NoCSAction ||
48            (this->Action != IRInstr && this->Action != SampleUse));
49 
50     // For CSIRInstr, CSProfileGenFile also needs to be nonempty.
51     assert(this->CSAction != CSIRInstr || !this->CSProfileGenFile.empty());
52 
53     // If CSAction is CSIRUse, PGOAction needs to be IRUse as they share
54     // a profile.
55     assert(this->CSAction != CSIRUse || this->Action == IRUse);
56 
57     // If neither Action nor CSAction, SamplePGOSupport needs to be true.
58     assert(this->Action != NoAction || this->CSAction != NoCSAction ||
59            this->SamplePGOSupport);
60   }
61   std::string ProfileFile;
62   std::string CSProfileGenFile;
63   std::string ProfileRemappingFile;
64   PGOAction Action;
65   CSPGOAction CSAction;
66   bool SamplePGOSupport;
67 };
68 
69 /// Tunable parameters for passes in the default pipelines.
70 class PipelineTuningOptions {
71 public:
72   /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
73   /// can be set in the PassBuilder when using a LLVM as a library.
74   PipelineTuningOptions();
75 
76   /// Tuning option to set loop interleaving on/off. Its default value is that
77   /// of the flag: `-interleave-loops`.
78   bool LoopInterleaving;
79 
80   /// Tuning option to enable/disable loop vectorization. Its default value is
81   /// that of the flag: `-vectorize-loops`.
82   bool LoopVectorization;
83 
84   /// Tuning option to enable/disable slp loop vectorization. Its default value
85   /// is that of the flag: `vectorize-slp`.
86   bool SLPVectorization;
87 
88   /// Tuning option to enable/disable loop unrolling. Its default value is true.
89   bool LoopUnrolling;
90 
91   /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
92   /// is that of the flag: `-forget-scev-loop-unroll`.
93   bool ForgetAllSCEVInLoopUnroll;
94 
95   /// Tuning option to cap the number of calls to retrive clobbering accesses in
96   /// MemorySSA, in LICM.
97   unsigned LicmMssaOptCap;
98 
99   /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
100   /// the number of access is too large.
101   unsigned LicmMssaNoAccForPromotionCap;
102 };
103 
104 /// This class provides access to building LLVM's passes.
105 ///
106 /// Its members provide the baseline state available to passes during their
107 /// construction. The \c PassRegistry.def file specifies how to construct all
108 /// of the built-in passes, and those may reference these members during
109 /// construction.
110 class PassBuilder {
111   TargetMachine *TM;
112   PipelineTuningOptions PTO;
113   Optional<PGOOptions> PGOOpt;
114   PassInstrumentationCallbacks *PIC;
115 
116 public:
117   /// A struct to capture parsed pass pipeline names.
118   ///
119   /// A pipeline is defined as a series of names, each of which may in itself
120   /// recursively contain a nested pipeline. A name is either the name of a pass
121   /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
122   /// name is the name of a pass, the InnerPipeline is empty, since passes
123   /// cannot contain inner pipelines. See parsePassPipeline() for a more
124   /// detailed description of the textual pipeline format.
125   struct PipelineElement {
126     StringRef Name;
127     std::vector<PipelineElement> InnerPipeline;
128   };
129 
130   /// ThinLTO phase.
131   ///
132   /// This enumerates the LLVM ThinLTO optimization phases.
133   enum class ThinLTOPhase {
134     /// No ThinLTO behavior needed.
135     None,
136     /// ThinLTO prelink (summary) phase.
137     PreLink,
138     /// ThinLTO postlink (backend compile) phase.
139     PostLink
140   };
141 
142   /// LLVM-provided high-level optimization levels.
143   ///
144   /// This enumerates the LLVM-provided high-level optimization levels. Each
145   /// level has a specific goal and rationale.
146   enum OptimizationLevel {
147     /// Disable as many optimizations as possible. This doesn't completely
148     /// disable the optimizer in all cases, for example always_inline functions
149     /// can be required to be inlined for correctness.
150     O0,
151 
152     /// Optimize quickly without destroying debuggability.
153     ///
154     /// This level is tuned to produce a result from the optimizer as quickly
155     /// as possible and to avoid destroying debuggability. This tends to result
156     /// in a very good development mode where the compiled code will be
157     /// immediately executed as part of testing. As a consequence, where
158     /// possible, we would like to produce efficient-to-execute code, but not
159     /// if it significantly slows down compilation or would prevent even basic
160     /// debugging of the resulting binary.
161     ///
162     /// As an example, complex loop transformations such as versioning,
163     /// vectorization, or fusion don't make sense here due to the degree to
164     /// which the executed code differs from the source code, and the compile time
165     /// cost.
166     O1,
167 
168     /// Optimize for fast execution as much as possible without triggering
169     /// significant incremental compile time or code size growth.
170     ///
171     /// The key idea is that optimizations at this level should "pay for
172     /// themselves". So if an optimization increases compile time by 5% or
173     /// increases code size by 5% for a particular benchmark, that benchmark
174     /// should also be one which sees a 5% runtime improvement. If the compile
175     /// time or code size penalties happen on average across a diverse range of
176     /// LLVM users' benchmarks, then the improvements should as well.
177     ///
178     /// And no matter what, the compile time needs to not grow superlinearly
179     /// with the size of input to LLVM so that users can control the runtime of
180     /// the optimizer in this mode.
181     ///
182     /// This is expected to be a good default optimization level for the vast
183     /// majority of users.
184     O2,
185 
186     /// Optimize for fast execution as much as possible.
187     ///
188     /// This mode is significantly more aggressive in trading off compile time
189     /// and code size to get execution time improvements. The core idea is that
190     /// this mode should include any optimization that helps execution time on
191     /// balance across a diverse collection of benchmarks, even if it increases
192     /// code size or compile time for some benchmarks without corresponding
193     /// improvements to execution time.
194     ///
195     /// Despite being willing to trade more compile time off to get improved
196     /// execution time, this mode still tries to avoid superlinear growth in
197     /// order to make even significantly slower compile times at least scale
198     /// reasonably. This does not preclude very substantial constant factor
199     /// costs though.
200     O3,
201 
202     /// Similar to \c O2 but tries to optimize for small code size instead of
203     /// fast execution without triggering significant incremental execution
204     /// time slowdowns.
205     ///
206     /// The logic here is exactly the same as \c O2, but with code size and
207     /// execution time metrics swapped.
208     ///
209     /// A consequence of the different core goal is that this should in general
210     /// produce substantially smaller executables that still run in
211     /// a reasonable amount of time.
212     Os,
213 
214     /// A very specialized mode that will optimize for code size at any and all
215     /// costs.
216     ///
217     /// This is useful primarily when there are absolute size limitations and
218     /// any effort taken to reduce the size is worth it regardless of the
219     /// execution time impact. You should expect this level to produce rather
220     /// slow, but very small, code.
221     Oz
222   };
223 
224   explicit PassBuilder(TargetMachine *TM = nullptr,
225                        PipelineTuningOptions PTO = PipelineTuningOptions(),
226                        Optional<PGOOptions> PGOOpt = None,
227                        PassInstrumentationCallbacks *PIC = nullptr)
TM(TM)228       : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {}
229 
230   /// Cross register the analysis managers through their proxies.
231   ///
232   /// This is an interface that can be used to cross register each
233   /// AnalysisManager with all the others analysis managers.
234   void crossRegisterProxies(LoopAnalysisManager &LAM,
235                             FunctionAnalysisManager &FAM,
236                             CGSCCAnalysisManager &CGAM,
237                             ModuleAnalysisManager &MAM);
238 
239   /// Registers all available module analysis passes.
240   ///
241   /// This is an interface that can be used to populate a \c
242   /// ModuleAnalysisManager with all registered module analyses. Callers can
243   /// still manually register any additional analyses. Callers can also
244   /// pre-register analyses and this will not override those.
245   void registerModuleAnalyses(ModuleAnalysisManager &MAM);
246 
247   /// Registers all available CGSCC analysis passes.
248   ///
249   /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
250   /// with all registered CGSCC analyses. Callers can still manually register any
251   /// additional analyses. Callers can also pre-register analyses and this will
252   /// not override those.
253   void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
254 
255   /// Registers all available function analysis passes.
256   ///
257   /// This is an interface that can be used to populate a \c
258   /// FunctionAnalysisManager with all registered function analyses. Callers can
259   /// still manually register any additional analyses. Callers can also
260   /// pre-register analyses and this will not override those.
261   void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
262 
263   /// Registers all available loop analysis passes.
264   ///
265   /// This is an interface that can be used to populate a \c LoopAnalysisManager
266   /// with all registered loop analyses. Callers can still manually register any
267   /// additional analyses.
268   void registerLoopAnalyses(LoopAnalysisManager &LAM);
269 
270   /// Construct the core LLVM function canonicalization and simplification
271   /// pipeline.
272   ///
273   /// This is a long pipeline and uses most of the per-function optimization
274   /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
275   /// repeatedly over the IR and is not expected to destroy important
276   /// information about the semantics of the IR.
277   ///
278   /// Note that \p Level cannot be `O0` here. The pipelines produced are
279   /// only intended for use when attempting to optimize code. If frontends
280   /// require some transformations for semantic reasons, they should explicitly
281   /// build them.
282   ///
283   /// \p Phase indicates the current ThinLTO phase.
284   FunctionPassManager
285   buildFunctionSimplificationPipeline(OptimizationLevel Level,
286                                       ThinLTOPhase Phase,
287                                       bool DebugLogging = false);
288 
289   /// Construct the core LLVM module canonicalization and simplification
290   /// pipeline.
291   ///
292   /// This pipeline focuses on canonicalizing and simplifying the entire module
293   /// of IR. Much like the function simplification pipeline above, it is
294   /// suitable to run repeatedly over the IR and is not expected to destroy
295   /// important information. It does, however, perform inlining and other
296   /// heuristic based simplifications that are not strictly reversible.
297   ///
298   /// Note that \p Level cannot be `O0` here. The pipelines produced are
299   /// only intended for use when attempting to optimize code. If frontends
300   /// require some transformations for semantic reasons, they should explicitly
301   /// build them.
302   ///
303   /// \p Phase indicates the current ThinLTO phase.
304   ModulePassManager
305   buildModuleSimplificationPipeline(OptimizationLevel Level,
306                                     ThinLTOPhase Phase,
307                                     bool DebugLogging = false);
308 
309   /// Construct the core LLVM module optimization pipeline.
310   ///
311   /// This pipeline focuses on optimizing the execution speed of the IR. It
312   /// uses cost modeling and thresholds to balance code growth against runtime
313   /// improvements. It includes vectorization and other information destroying
314   /// transformations. It also cannot generally be run repeatedly on a module
315   /// without potentially seriously regressing either runtime performance of
316   /// the code or serious code size growth.
317   ///
318   /// Note that \p Level cannot be `O0` here. The pipelines produced are
319   /// only intended for use when attempting to optimize code. If frontends
320   /// require some transformations for semantic reasons, they should explicitly
321   /// build them.
322   ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level,
323                                                     bool DebugLogging = false,
324                                                     bool LTOPreLink = false);
325 
326   /// Build a per-module default optimization pipeline.
327   ///
328   /// This provides a good default optimization pipeline for per-module
329   /// optimization and code generation without any link-time optimization. It
330   /// typically correspond to frontend "-O[123]" options for optimization
331   /// levels \c O1, \c O2 and \c O3 resp.
332   ///
333   /// Note that \p Level cannot be `O0` here. The pipelines produced are
334   /// only intended for use when attempting to optimize code. If frontends
335   /// require some transformations for semantic reasons, they should explicitly
336   /// build them.
337   ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level,
338                                                   bool DebugLogging = false,
339                                                   bool LTOPreLink = false);
340 
341   /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
342   /// a pass manager.
343   ///
344   /// This adds the pre-link optimizations tuned to prepare a module for
345   /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
346   /// without making irreversible decisions which could be made better during
347   /// the LTO run.
348   ///
349   /// Note that \p Level cannot be `O0` here. The pipelines produced are
350   /// only intended for use when attempting to optimize code. If frontends
351   /// require some transformations for semantic reasons, they should explicitly
352   /// build them.
353   ModulePassManager
354   buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level,
355                                      bool DebugLogging = false);
356 
357   /// Build an ThinLTO default optimization pipeline to a pass manager.
358   ///
359   /// This provides a good default optimization pipeline for link-time
360   /// optimization and code generation. It is particularly tuned to fit well
361   /// when IR coming into the LTO phase was first run through \c
362   /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
363   ///
364   /// Note that \p Level cannot be `O0` here. The pipelines produced are
365   /// only intended for use when attempting to optimize code. If frontends
366   /// require some transformations for semantic reasons, they should explicitly
367   /// build them.
368   ModulePassManager
369   buildThinLTODefaultPipeline(OptimizationLevel Level, bool DebugLogging,
370                               const ModuleSummaryIndex *ImportSummary);
371 
372   /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
373   /// manager.
374   ///
375   /// This adds the pre-link optimizations tuned to work well with a later LTO
376   /// run. It works to minimize the IR which needs to be analyzed without
377   /// making irreversible decisions which could be made better during the LTO
378   /// run.
379   ///
380   /// Note that \p Level cannot be `O0` here. The pipelines produced are
381   /// only intended for use when attempting to optimize code. If frontends
382   /// require some transformations for semantic reasons, they should explicitly
383   /// build them.
384   ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level,
385                                                    bool DebugLogging = false);
386 
387   /// Build an LTO default optimization pipeline to a pass manager.
388   ///
389   /// This provides a good default optimization pipeline for link-time
390   /// optimization and code generation. It is particularly tuned to fit well
391   /// when IR coming into the LTO phase was first run through \c
392   /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
393   ///
394   /// Note that \p Level cannot be `O0` here. The pipelines produced are
395   /// only intended for use when attempting to optimize code. If frontends
396   /// require some transformations for semantic reasons, they should explicitly
397   /// build them.
398   ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
399                                             bool DebugLogging,
400                                             ModuleSummaryIndex *ExportSummary);
401 
402   /// Build the default `AAManager` with the default alias analysis pipeline
403   /// registered.
404   AAManager buildDefaultAAPipeline();
405 
406   /// Parse a textual pass pipeline description into a \c
407   /// ModulePassManager.
408   ///
409   /// The format of the textual pass pipeline description looks something like:
410   ///
411   ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
412   ///
413   /// Pass managers have ()s describing the nest structure of passes. All passes
414   /// are comma separated. As a special shortcut, if the very first pass is not
415   /// a module pass (as a module pass manager is), this will automatically form
416   /// the shortest stack of pass managers that allow inserting that first pass.
417   /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
418   /// passes 'lpassN', all of these are valid:
419   ///
420   ///   fpass1,fpass2,fpass3
421   ///   cgpass1,cgpass2,cgpass3
422   ///   lpass1,lpass2,lpass3
423   ///
424   /// And they are equivalent to the following (resp.):
425   ///
426   ///   module(function(fpass1,fpass2,fpass3))
427   ///   module(cgscc(cgpass1,cgpass2,cgpass3))
428   ///   module(function(loop(lpass1,lpass2,lpass3)))
429   ///
430   /// This shortcut is especially useful for debugging and testing small pass
431   /// combinations. Note that these shortcuts don't introduce any other magic.
432   /// If the sequence of passes aren't all the exact same kind of pass, it will
433   /// be an error. You cannot mix different levels implicitly, you must
434   /// explicitly form a pass manager in which to nest passes.
435   Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
436                           bool VerifyEachPass = true,
437                           bool DebugLogging = false);
438 
439   /// {{@ Parse a textual pass pipeline description into a specific PassManager
440   ///
441   /// Automatic deduction of an appropriate pass manager stack is not supported.
442   /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
443   /// this is the valid pipeline text:
444   ///
445   ///   function(lpass)
446   Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText,
447                           bool VerifyEachPass = true,
448                           bool DebugLogging = false);
449   Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText,
450                           bool VerifyEachPass = true,
451                           bool DebugLogging = false);
452   Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText,
453                           bool VerifyEachPass = true,
454                           bool DebugLogging = false);
455   /// @}}
456 
457   /// Parse a textual alias analysis pipeline into the provided AA manager.
458   ///
459   /// The format of the textual AA pipeline is a comma separated list of AA
460   /// pass names:
461   ///
462   ///   basic-aa,globals-aa,...
463   ///
464   /// The AA manager is set up such that the provided alias analyses are tried
465   /// in the order specified. See the \c AAManaager documentation for details
466   /// about the logic used. This routine just provides the textual mapping
467   /// between AA names and the analyses to register with the manager.
468   ///
469   /// Returns false if the text cannot be parsed cleanly. The specific state of
470   /// the \p AA manager is unspecified if such an error is encountered and this
471   /// returns false.
472   Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
473 
474   /// Register a callback for a default optimizer pipeline extension
475   /// point
476   ///
477   /// This extension point allows adding passes that perform peephole
478   /// optimizations similar to the instruction combiner. These passes will be
479   /// inserted after each instance of the instruction combiner pass.
registerPeepholeEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)480   void registerPeepholeEPCallback(
481       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
482     PeepholeEPCallbacks.push_back(C);
483   }
484 
485   /// Register a callback for a default optimizer pipeline extension
486   /// point
487   ///
488   /// This extension point allows adding late loop canonicalization and
489   /// simplification passes. This is the last point in the loop optimization
490   /// pipeline before loop deletion. Each pass added
491   /// here must be an instance of LoopPass.
492   /// This is the place to add passes that can remove loops, such as target-
493   /// specific loop idiom recognition.
registerLateLoopOptimizationsEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)494   void registerLateLoopOptimizationsEPCallback(
495       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
496     LateLoopOptimizationsEPCallbacks.push_back(C);
497   }
498 
499   /// Register a callback for a default optimizer pipeline extension
500   /// point
501   ///
502   /// This extension point allows adding loop passes to the end of the loop
503   /// optimizer.
registerLoopOptimizerEndEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)504   void registerLoopOptimizerEndEPCallback(
505       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
506     LoopOptimizerEndEPCallbacks.push_back(C);
507   }
508 
509   /// Register a callback for a default optimizer pipeline extension
510   /// point
511   ///
512   /// This extension point allows adding optimization passes after most of the
513   /// main optimizations, but before the last cleanup-ish optimizations.
registerScalarOptimizerLateEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)514   void registerScalarOptimizerLateEPCallback(
515       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
516     ScalarOptimizerLateEPCallbacks.push_back(C);
517   }
518 
519   /// Register a callback for a default optimizer pipeline extension
520   /// point
521   ///
522   /// This extension point allows adding CallGraphSCC passes at the end of the
523   /// main CallGraphSCC passes and before any function simplification passes run
524   /// by CGPassManager.
registerCGSCCOptimizerLateEPCallback(const std::function<void (CGSCCPassManager &,OptimizationLevel)> & C)525   void registerCGSCCOptimizerLateEPCallback(
526       const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
527     CGSCCOptimizerLateEPCallbacks.push_back(C);
528   }
529 
530   /// Register a callback for a default optimizer pipeline extension
531   /// point
532   ///
533   /// This extension point allows adding optimization passes before the
534   /// vectorizer and other highly target specific optimization passes are
535   /// executed.
registerVectorizerStartEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)536   void registerVectorizerStartEPCallback(
537       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
538     VectorizerStartEPCallbacks.push_back(C);
539   }
540 
541   /// Register a callback for a default optimizer pipeline extension point.
542   ///
543   /// This extension point allows adding optimization once at the start of the
544   /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
545   /// link-time pipelines).
registerPipelineStartEPCallback(const std::function<void (ModulePassManager &)> & C)546   void registerPipelineStartEPCallback(
547       const std::function<void(ModulePassManager &)> &C) {
548     PipelineStartEPCallbacks.push_back(C);
549   }
550 
551   /// Register a callback for a default optimizer pipeline extension point
552   ///
553   /// This extension point allows adding optimizations at the very end of the
554   /// function optimization pipeline. A key difference between this and the
555   /// legacy PassManager's OptimizerLast callback is that this extension point
556   /// is not triggered at O0. Extensions to the O0 pipeline should append their
557   /// passes to the end of the overall pipeline.
registerOptimizerLastEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)558   void registerOptimizerLastEPCallback(
559       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
560     OptimizerLastEPCallbacks.push_back(C);
561   }
562 
563   /// Register a callback for parsing an AliasAnalysis Name to populate
564   /// the given AAManager \p AA
registerParseAACallback(const std::function<bool (StringRef Name,AAManager & AA)> & C)565   void registerParseAACallback(
566       const std::function<bool(StringRef Name, AAManager &AA)> &C) {
567     AAParsingCallbacks.push_back(C);
568   }
569 
570   /// {{@ Register callbacks for analysis registration with this PassBuilder
571   /// instance.
572   /// Callees register their analyses with the given AnalysisManager objects.
registerAnalysisRegistrationCallback(const std::function<void (CGSCCAnalysisManager &)> & C)573   void registerAnalysisRegistrationCallback(
574       const std::function<void(CGSCCAnalysisManager &)> &C) {
575     CGSCCAnalysisRegistrationCallbacks.push_back(C);
576   }
registerAnalysisRegistrationCallback(const std::function<void (FunctionAnalysisManager &)> & C)577   void registerAnalysisRegistrationCallback(
578       const std::function<void(FunctionAnalysisManager &)> &C) {
579     FunctionAnalysisRegistrationCallbacks.push_back(C);
580   }
registerAnalysisRegistrationCallback(const std::function<void (LoopAnalysisManager &)> & C)581   void registerAnalysisRegistrationCallback(
582       const std::function<void(LoopAnalysisManager &)> &C) {
583     LoopAnalysisRegistrationCallbacks.push_back(C);
584   }
registerAnalysisRegistrationCallback(const std::function<void (ModuleAnalysisManager &)> & C)585   void registerAnalysisRegistrationCallback(
586       const std::function<void(ModuleAnalysisManager &)> &C) {
587     ModuleAnalysisRegistrationCallbacks.push_back(C);
588   }
589   /// @}}
590 
591   /// {{@ Register pipeline parsing callbacks with this pass builder instance.
592   /// Using these callbacks, callers can parse both a single pass name, as well
593   /// as entire sub-pipelines, and populate the PassManager instance
594   /// accordingly.
registerPipelineParsingCallback(const std::function<bool (StringRef Name,CGSCCPassManager &,ArrayRef<PipelineElement>)> & C)595   void registerPipelineParsingCallback(
596       const std::function<bool(StringRef Name, CGSCCPassManager &,
597                                ArrayRef<PipelineElement>)> &C) {
598     CGSCCPipelineParsingCallbacks.push_back(C);
599   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,FunctionPassManager &,ArrayRef<PipelineElement>)> & C)600   void registerPipelineParsingCallback(
601       const std::function<bool(StringRef Name, FunctionPassManager &,
602                                ArrayRef<PipelineElement>)> &C) {
603     FunctionPipelineParsingCallbacks.push_back(C);
604   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,LoopPassManager &,ArrayRef<PipelineElement>)> & C)605   void registerPipelineParsingCallback(
606       const std::function<bool(StringRef Name, LoopPassManager &,
607                                ArrayRef<PipelineElement>)> &C) {
608     LoopPipelineParsingCallbacks.push_back(C);
609   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,ModulePassManager &,ArrayRef<PipelineElement>)> & C)610   void registerPipelineParsingCallback(
611       const std::function<bool(StringRef Name, ModulePassManager &,
612                                ArrayRef<PipelineElement>)> &C) {
613     ModulePipelineParsingCallbacks.push_back(C);
614   }
615   /// @}}
616 
617   /// Register a callback for a top-level pipeline entry.
618   ///
619   /// If the PassManager type is not given at the top level of the pipeline
620   /// text, this Callback should be used to determine the appropriate stack of
621   /// PassManagers and populate the passed ModulePassManager.
registerParseTopLevelPipelineCallback(const std::function<bool (ModulePassManager &,ArrayRef<PipelineElement>,bool VerifyEachPass,bool DebugLogging)> & C)622   void registerParseTopLevelPipelineCallback(
623       const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
624                                bool VerifyEachPass, bool DebugLogging)> &C) {
625     TopLevelPipelineParsingCallbacks.push_back(C);
626   }
627 
628   /// Add PGOInstrumenation passes for O0 only.
629   void addPGOInstrPassesForO0(ModulePassManager &MPM, bool DebugLogging,
630                               bool RunProfileGen, bool IsCS,
631                               std::string ProfileFile,
632                               std::string ProfileRemappingFile);
633 
634 
635   /// Returns PIC. External libraries can use this to register pass
636   /// instrumentation callbacks.
getPassInstrumentationCallbacks()637   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
638     return PIC;
639   }
640 
641 private:
642   static Optional<std::vector<PipelineElement>>
643   parsePipelineText(StringRef Text);
644 
645   Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E,
646                         bool VerifyEachPass, bool DebugLogging);
647   Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E,
648                        bool VerifyEachPass, bool DebugLogging);
649   Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E,
650                           bool VerifyEachPass, bool DebugLogging);
651   Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E,
652                       bool VerifyEachPass, bool DebugLogging);
653   bool parseAAPassName(AAManager &AA, StringRef Name);
654 
655   Error parseLoopPassPipeline(LoopPassManager &LPM,
656                               ArrayRef<PipelineElement> Pipeline,
657                               bool VerifyEachPass, bool DebugLogging);
658   Error parseFunctionPassPipeline(FunctionPassManager &FPM,
659                                   ArrayRef<PipelineElement> Pipeline,
660                                   bool VerifyEachPass, bool DebugLogging);
661   Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
662                                ArrayRef<PipelineElement> Pipeline,
663                                bool VerifyEachPass, bool DebugLogging);
664   Error parseModulePassPipeline(ModulePassManager &MPM,
665                                 ArrayRef<PipelineElement> Pipeline,
666                                 bool VerifyEachPass, bool DebugLogging);
667 
668   void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging,
669                          OptimizationLevel Level, bool RunProfileGen, bool IsCS,
670                          std::string ProfileFile,
671                          std::string ProfileRemappingFile);
672   void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
673 
674   // Extension Point callbacks
675   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
676       PeepholeEPCallbacks;
677   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
678       LateLoopOptimizationsEPCallbacks;
679   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
680       LoopOptimizerEndEPCallbacks;
681   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
682       ScalarOptimizerLateEPCallbacks;
683   SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
684       CGSCCOptimizerLateEPCallbacks;
685   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
686       VectorizerStartEPCallbacks;
687   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
688       OptimizerLastEPCallbacks;
689   // Module callbacks
690   SmallVector<std::function<void(ModulePassManager &)>, 2>
691       PipelineStartEPCallbacks;
692   SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
693       ModuleAnalysisRegistrationCallbacks;
694   SmallVector<std::function<bool(StringRef, ModulePassManager &,
695                                  ArrayRef<PipelineElement>)>,
696               2>
697       ModulePipelineParsingCallbacks;
698   SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>,
699                                  bool VerifyEachPass, bool DebugLogging)>,
700               2>
701       TopLevelPipelineParsingCallbacks;
702   // CGSCC callbacks
703   SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
704       CGSCCAnalysisRegistrationCallbacks;
705   SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
706                                  ArrayRef<PipelineElement>)>,
707               2>
708       CGSCCPipelineParsingCallbacks;
709   // Function callbacks
710   SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
711       FunctionAnalysisRegistrationCallbacks;
712   SmallVector<std::function<bool(StringRef, FunctionPassManager &,
713                                  ArrayRef<PipelineElement>)>,
714               2>
715       FunctionPipelineParsingCallbacks;
716   // Loop callbacks
717   SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
718       LoopAnalysisRegistrationCallbacks;
719   SmallVector<std::function<bool(StringRef, LoopPassManager &,
720                                  ArrayRef<PipelineElement>)>,
721               2>
722       LoopPipelineParsingCallbacks;
723   // AA callbacks
724   SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
725       AAParsingCallbacks;
726 };
727 
728 /// This utility template takes care of adding require<> and invalidate<>
729 /// passes for an analysis to a given \c PassManager. It is intended to be used
730 /// during parsing of a pass pipeline when parsing a single PipelineName.
731 /// When registering a new function analysis FancyAnalysis with the pass
732 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
733 /// like this:
734 ///
735 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
736 ///                                   ArrayRef<PipelineElement> P) {
737 ///   if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
738 ///                                                 FPM))
739 ///     return true;
740 ///   return false;
741 /// }
742 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
743           typename... ExtraArgTs>
parseAnalysisUtilityPasses(StringRef AnalysisName,StringRef PipelineName,PassManager<IRUnitT,AnalysisManagerT,ExtraArgTs...> & PM)744 bool parseAnalysisUtilityPasses(
745     StringRef AnalysisName, StringRef PipelineName,
746     PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
747   if (!PipelineName.endswith(">"))
748     return false;
749   // See if this is an invalidate<> pass name
750   if (PipelineName.startswith("invalidate<")) {
751     PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
752     if (PipelineName != AnalysisName)
753       return false;
754     PM.addPass(InvalidateAnalysisPass<AnalysisT>());
755     return true;
756   }
757 
758   // See if this is a require<> pass name
759   if (PipelineName.startswith("require<")) {
760     PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
761     if (PipelineName != AnalysisName)
762       return false;
763     PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
764                                    ExtraArgTs...>());
765     return true;
766   }
767 
768   return false;
769 }
770 }
771 
772 #endif
773