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.
registerPeepholeEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)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.
registerLateLoopOptimizationsEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)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.
registerLoopOptimizerEndEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)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.
registerScalarOptimizerLateEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)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.
registerCGSCCOptimizerLateEPCallback(const std::function<void (CGSCCPassManager &,OptimizationLevel)> & C)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.
registerVectorizerStartEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)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).
registerPipelineStartEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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.
registerPipelineEarlySimplificationEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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.
registerOptimizerEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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.
registerOptimizerLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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.
registerFullLinkTimeOptimizationEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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.
registerFullLinkTimeOptimizationLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)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
registerParseAACallback(const std::function<bool (StringRef Name,AAManager & AA)> & C)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.
registerAnalysisRegistrationCallback(const std::function<void (CGSCCAnalysisManager &)> & C)514 void registerAnalysisRegistrationCallback(
515 const std::function<void(CGSCCAnalysisManager &)> &C) {
516 CGSCCAnalysisRegistrationCallbacks.push_back(C);
517 }
registerAnalysisRegistrationCallback(const std::function<void (FunctionAnalysisManager &)> & C)518 void registerAnalysisRegistrationCallback(
519 const std::function<void(FunctionAnalysisManager &)> &C) {
520 FunctionAnalysisRegistrationCallbacks.push_back(C);
521 }
registerAnalysisRegistrationCallback(const std::function<void (LoopAnalysisManager &)> & C)522 void registerAnalysisRegistrationCallback(
523 const std::function<void(LoopAnalysisManager &)> &C) {
524 LoopAnalysisRegistrationCallbacks.push_back(C);
525 }
registerAnalysisRegistrationCallback(const std::function<void (ModuleAnalysisManager &)> & C)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.
registerPipelineParsingCallback(const std::function<bool (StringRef Name,CGSCCPassManager &,ArrayRef<PipelineElement>)> & C)536 void registerPipelineParsingCallback(
537 const std::function<bool(StringRef Name, CGSCCPassManager &,
538 ArrayRef<PipelineElement>)> &C) {
539 CGSCCPipelineParsingCallbacks.push_back(C);
540 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,FunctionPassManager &,ArrayRef<PipelineElement>)> & C)541 void registerPipelineParsingCallback(
542 const std::function<bool(StringRef Name, FunctionPassManager &,
543 ArrayRef<PipelineElement>)> &C) {
544 FunctionPipelineParsingCallbacks.push_back(C);
545 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,LoopPassManager &,ArrayRef<PipelineElement>)> & C)546 void registerPipelineParsingCallback(
547 const std::function<bool(StringRef Name, LoopPassManager &,
548 ArrayRef<PipelineElement>)> &C) {
549 LoopPipelineParsingCallbacks.push_back(C);
550 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,ModulePassManager &,ArrayRef<PipelineElement>)> & C)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.
getPassInstrumentationCallbacks()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>
parseAnalysisUtilityPasses(StringRef AnalysisName,StringRef PipelineName,PassManager<IRUnitT,AnalysisManagerT,ExtraArgTs...> & PM)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