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