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/CodeGen/MachinePassManager.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/Passes/OptimizationLevel.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/PGOOptions.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Transforms/IPO/Inliner.h"
26 #include "llvm/Transforms/IPO/ModuleInliner.h"
27 #include "llvm/Transforms/Instrumentation.h"
28 #include "llvm/Transforms/Scalar/LoopPassManager.h"
29 #include <vector>
30
31 namespace llvm {
32 class StringRef;
33 class AAManager;
34 class TargetMachine;
35 class ModuleSummaryIndex;
36 template <typename T> class IntrusiveRefCntPtr;
37 namespace vfs {
38 class FileSystem;
39 } // namespace vfs
40
41 /// Tunable parameters for passes in the default pipelines.
42 class PipelineTuningOptions {
43 public:
44 /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
45 /// can be set in the PassBuilder when using a LLVM as a library.
46 PipelineTuningOptions();
47
48 /// Tuning option to set loop interleaving on/off, set based on opt level.
49 bool LoopInterleaving;
50
51 /// Tuning option to enable/disable loop vectorization, set based on opt
52 /// level.
53 bool LoopVectorization;
54
55 /// Tuning option to enable/disable slp loop vectorization, set based on opt
56 /// level.
57 bool SLPVectorization;
58
59 /// Tuning option to enable/disable loop unrolling. Its default value is true.
60 bool LoopUnrolling;
61
62 /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
63 /// is that of the flag: `-forget-scev-loop-unroll`.
64 bool ForgetAllSCEVInLoopUnroll;
65
66 /// Tuning option to cap the number of calls to retrive clobbering accesses in
67 /// MemorySSA, in LICM.
68 unsigned LicmMssaOptCap;
69
70 /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
71 /// the number of access is too large.
72 unsigned LicmMssaNoAccForPromotionCap;
73
74 /// Tuning option to enable/disable call graph profile. Its default value is
75 /// that of the flag: `-enable-npm-call-graph-profile`.
76 bool CallGraphProfile;
77
78 // Add LTO pipeline tuning option to enable the unified LTO pipeline.
79 bool UnifiedLTO;
80
81 /// Tuning option to enable/disable function merging. Its default value is
82 /// false.
83 bool MergeFunctions;
84
85 /// Tuning option to override the default inliner threshold.
86 int InlinerThreshold;
87
88 // Experimental option to eagerly invalidate more analyses. This has the
89 // potential to decrease max memory usage in exchange for more compile time.
90 // This may affect codegen due to either passes using analyses only when
91 // cached, or invalidating and recalculating an analysis that was
92 // stale/imprecise but still valid. Currently this invalidates all function
93 // analyses after various module->function or cgscc->function adaptors in the
94 // default pipelines.
95 bool EagerlyInvalidateAnalyses;
96 };
97
98 /// This class provides access to building LLVM's passes.
99 ///
100 /// Its members provide the baseline state available to passes during their
101 /// construction. The \c PassRegistry.def file specifies how to construct all
102 /// of the built-in passes, and those may reference these members during
103 /// construction.
104 class PassBuilder {
105 TargetMachine *TM;
106 PipelineTuningOptions PTO;
107 std::optional<PGOOptions> PGOOpt;
108 PassInstrumentationCallbacks *PIC;
109
110 public:
111 /// A struct to capture parsed pass pipeline names.
112 ///
113 /// A pipeline is defined as a series of names, each of which may in itself
114 /// recursively contain a nested pipeline. A name is either the name of a pass
115 /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
116 /// name is the name of a pass, the InnerPipeline is empty, since passes
117 /// cannot contain inner pipelines. See parsePassPipeline() for a more
118 /// detailed description of the textual pipeline format.
119 struct PipelineElement {
120 StringRef Name;
121 std::vector<PipelineElement> InnerPipeline;
122 };
123
124 explicit PassBuilder(TargetMachine *TM = nullptr,
125 PipelineTuningOptions PTO = PipelineTuningOptions(),
126 std::optional<PGOOptions> PGOOpt = std::nullopt,
127 PassInstrumentationCallbacks *PIC = nullptr);
128
129 /// Cross register the analysis managers through their proxies.
130 ///
131 /// This is an interface that can be used to cross register each
132 /// AnalysisManager with all the others analysis managers.
133 void crossRegisterProxies(LoopAnalysisManager &LAM,
134 FunctionAnalysisManager &FAM,
135 CGSCCAnalysisManager &CGAM,
136 ModuleAnalysisManager &MAM,
137 MachineFunctionAnalysisManager *MFAM = nullptr);
138
139 /// Registers all available module analysis passes.
140 ///
141 /// This is an interface that can be used to populate a \c
142 /// ModuleAnalysisManager with all registered module analyses. Callers can
143 /// still manually register any additional analyses. Callers can also
144 /// pre-register analyses and this will not override those.
145 void registerModuleAnalyses(ModuleAnalysisManager &MAM);
146
147 /// Registers all available CGSCC analysis passes.
148 ///
149 /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
150 /// with all registered CGSCC analyses. Callers can still manually register any
151 /// additional analyses. Callers can also pre-register analyses and this will
152 /// not override those.
153 void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
154
155 /// Registers all available function analysis passes.
156 ///
157 /// This is an interface that can be used to populate a \c
158 /// FunctionAnalysisManager with all registered function analyses. Callers can
159 /// still manually register any additional analyses. Callers can also
160 /// pre-register analyses and this will not override those.
161 void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
162
163 /// Registers all available loop analysis passes.
164 ///
165 /// This is an interface that can be used to populate a \c LoopAnalysisManager
166 /// with all registered loop analyses. Callers can still manually register any
167 /// additional analyses.
168 void registerLoopAnalyses(LoopAnalysisManager &LAM);
169
170 /// Registers all available machine function analysis passes.
171 ///
172 /// This is an interface that can be used to populate a \c
173 /// MachineFunctionAnalysisManager with all registered function analyses.
174 /// Callers can still manually register any additional analyses. Callers can
175 /// also pre-register analyses and this will not override those.
176 void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM);
177
178 /// Construct the core LLVM function canonicalization and simplification
179 /// pipeline.
180 ///
181 /// This is a long pipeline and uses most of the per-function optimization
182 /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
183 /// repeatedly over the IR and is not expected to destroy important
184 /// information about the semantics of the IR.
185 ///
186 /// Note that \p Level cannot be `O0` here. The pipelines produced are
187 /// only intended for use when attempting to optimize code. If frontends
188 /// require some transformations for semantic reasons, they should explicitly
189 /// build them.
190 ///
191 /// \p Phase indicates the current ThinLTO phase.
192 FunctionPassManager
193 buildFunctionSimplificationPipeline(OptimizationLevel Level,
194 ThinOrFullLTOPhase Phase);
195
196 /// Construct the core LLVM module canonicalization and simplification
197 /// pipeline.
198 ///
199 /// This pipeline focuses on canonicalizing and simplifying the entire module
200 /// of IR. Much like the function simplification pipeline above, it is
201 /// suitable to run repeatedly over the IR and is not expected to destroy
202 /// important information. It does, however, perform inlining and other
203 /// heuristic based simplifications that are not strictly reversible.
204 ///
205 /// Note that \p Level cannot be `O0` here. The pipelines produced are
206 /// only intended for use when attempting to optimize code. If frontends
207 /// require some transformations for semantic reasons, they should explicitly
208 /// build them.
209 ///
210 /// \p Phase indicates the current ThinLTO phase.
211 ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
212 ThinOrFullLTOPhase Phase);
213
214 /// Construct the module pipeline that performs inlining as well as
215 /// the inlining-driven cleanups.
216 ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
217 ThinOrFullLTOPhase Phase);
218
219 /// Construct the module pipeline that performs inlining with
220 /// module inliner pass.
221 ModulePassManager buildModuleInlinerPipeline(OptimizationLevel Level,
222 ThinOrFullLTOPhase Phase);
223
224 /// Construct the core LLVM module optimization pipeline.
225 ///
226 /// This pipeline focuses on optimizing the execution speed of the IR. It
227 /// uses cost modeling and thresholds to balance code growth against runtime
228 /// improvements. It includes vectorization and other information destroying
229 /// transformations. It also cannot generally be run repeatedly on a module
230 /// without potentially seriously regressing either runtime performance of
231 /// the code or serious code size growth.
232 ///
233 /// Note that \p Level cannot be `O0` here. The pipelines produced are
234 /// only intended for use when attempting to optimize code. If frontends
235 /// require some transformations for semantic reasons, they should explicitly
236 /// build them.
237 ModulePassManager
238 buildModuleOptimizationPipeline(OptimizationLevel Level,
239 ThinOrFullLTOPhase LTOPhase);
240
241 /// Build a per-module default optimization pipeline.
242 ///
243 /// This provides a good default optimization pipeline for per-module
244 /// optimization and code generation without any link-time optimization. It
245 /// typically correspond to frontend "-O[123]" options for optimization
246 /// levels \c O1, \c O2 and \c O3 resp.
247 ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level,
248 bool LTOPreLink = false);
249
250 /// Build a fat object default optimization pipeline.
251 ///
252 /// This builds a pipeline that runs the LTO/ThinLTO pre-link pipeline, and
253 /// emits a section containing the pre-link bitcode along side the object code
254 /// generated in non-LTO compilation.
255 ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
256 bool ThinLTO, bool EmitSummary);
257
258 /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
259 /// a pass manager.
260 ///
261 /// This adds the pre-link optimizations tuned to prepare a module for
262 /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
263 /// without making irreversible decisions which could be made better during
264 /// the LTO run.
265 ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
266
267 /// Build an ThinLTO default optimization pipeline to a pass manager.
268 ///
269 /// This provides a good default optimization pipeline for link-time
270 /// optimization and code generation. It is particularly tuned to fit well
271 /// when IR coming into the LTO phase was first run through \c
272 /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
273 ModulePassManager
274 buildThinLTODefaultPipeline(OptimizationLevel Level,
275 const ModuleSummaryIndex *ImportSummary);
276
277 /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
278 /// manager.
279 ///
280 /// This adds the pre-link optimizations tuned to work well with a later LTO
281 /// run. It works to minimize the IR which needs to be analyzed without
282 /// making irreversible decisions which could be made better during the LTO
283 /// run.
284 ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
285
286 /// Build an LTO default optimization pipeline to a pass manager.
287 ///
288 /// This provides a good default optimization pipeline for link-time
289 /// optimization and code generation. It is particularly tuned to fit well
290 /// when IR coming into the LTO phase was first run through \c
291 /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
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 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 MIR pipeline into the provided \c MachineFunctionPass
363 /// manager.
364 /// The format of the textual machine pipeline is a comma separated list of
365 /// machine pass names:
366 ///
367 /// machine-funciton-pass,machine-module-pass,...
368 ///
369 /// There is no need to specify the pass nesting, and this function
370 /// currently cannot handle the pass nesting.
371 Error parsePassPipeline(MachineFunctionPassManager &MFPM,
372 StringRef PipelineText);
373
374 /// Parse a textual alias analysis pipeline into the provided AA manager.
375 ///
376 /// The format of the textual AA pipeline is a comma separated list of AA
377 /// pass names:
378 ///
379 /// basic-aa,globals-aa,...
380 ///
381 /// The AA manager is set up such that the provided alias analyses are tried
382 /// in the order specified. See the \c AAManaager documentation for details
383 /// about the logic used. This routine just provides the textual mapping
384 /// between AA names and the analyses to register with the manager.
385 ///
386 /// Returns false if the text cannot be parsed cleanly. The specific state of
387 /// the \p AA manager is unspecified if such an error is encountered and this
388 /// returns false.
389 Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
390
391 /// Print pass names.
392 void printPassNames(raw_ostream &OS);
393
394 /// Register a callback for a default optimizer pipeline extension
395 /// point
396 ///
397 /// This extension point allows adding passes that perform peephole
398 /// optimizations similar to the instruction combiner. These passes will be
399 /// inserted after each instance of the instruction combiner pass.
registerPeepholeEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)400 void registerPeepholeEPCallback(
401 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
402 PeepholeEPCallbacks.push_back(C);
403 }
404
405 /// Register a callback for a default optimizer pipeline extension
406 /// point
407 ///
408 /// This extension point allows adding late loop canonicalization and
409 /// simplification passes. This is the last point in the loop optimization
410 /// pipeline before loop deletion. Each pass added
411 /// here must be an instance of LoopPass.
412 /// This is the place to add passes that can remove loops, such as target-
413 /// specific loop idiom recognition.
registerLateLoopOptimizationsEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)414 void registerLateLoopOptimizationsEPCallback(
415 const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
416 LateLoopOptimizationsEPCallbacks.push_back(C);
417 }
418
419 /// Register a callback for a default optimizer pipeline extension
420 /// point
421 ///
422 /// This extension point allows adding loop passes to the end of the loop
423 /// optimizer.
registerLoopOptimizerEndEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)424 void registerLoopOptimizerEndEPCallback(
425 const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
426 LoopOptimizerEndEPCallbacks.push_back(C);
427 }
428
429 /// Register a callback for a default optimizer pipeline extension
430 /// point
431 ///
432 /// This extension point allows adding optimization passes after most of the
433 /// main optimizations, but before the last cleanup-ish optimizations.
registerScalarOptimizerLateEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)434 void registerScalarOptimizerLateEPCallback(
435 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
436 ScalarOptimizerLateEPCallbacks.push_back(C);
437 }
438
439 /// Register a callback for a default optimizer pipeline extension
440 /// point
441 ///
442 /// This extension point allows adding CallGraphSCC passes at the end of the
443 /// main CallGraphSCC passes and before any function simplification passes run
444 /// by CGPassManager.
registerCGSCCOptimizerLateEPCallback(const std::function<void (CGSCCPassManager &,OptimizationLevel)> & C)445 void registerCGSCCOptimizerLateEPCallback(
446 const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
447 CGSCCOptimizerLateEPCallbacks.push_back(C);
448 }
449
450 /// Register a callback for a default optimizer pipeline extension
451 /// point
452 ///
453 /// This extension point allows adding optimization passes before the
454 /// vectorizer and other highly target specific optimization passes are
455 /// executed.
registerVectorizerStartEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)456 void registerVectorizerStartEPCallback(
457 const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
458 VectorizerStartEPCallbacks.push_back(C);
459 }
460
461 /// Register a callback for a default optimizer pipeline extension point.
462 ///
463 /// This extension point allows adding optimization once at the start of the
464 /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
465 /// link-time pipelines).
registerPipelineStartEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)466 void registerPipelineStartEPCallback(
467 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
468 PipelineStartEPCallbacks.push_back(C);
469 }
470
471 /// Register a callback for a default optimizer pipeline extension point.
472 ///
473 /// This extension point allows adding optimization right after passes that do
474 /// basic simplification of the input IR.
registerPipelineEarlySimplificationEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)475 void registerPipelineEarlySimplificationEPCallback(
476 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
477 PipelineEarlySimplificationEPCallbacks.push_back(C);
478 }
479
480 /// Register a callback for a default optimizer pipeline extension point
481 ///
482 /// This extension point allows adding optimizations before the function
483 /// optimization pipeline.
registerOptimizerEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)484 void registerOptimizerEarlyEPCallback(
485 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
486 OptimizerEarlyEPCallbacks.push_back(C);
487 }
488
489 /// Register a callback for a default optimizer pipeline extension point
490 ///
491 /// This extension point allows adding optimizations at the very end of the
492 /// function optimization pipeline.
registerOptimizerLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)493 void registerOptimizerLastEPCallback(
494 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
495 OptimizerLastEPCallbacks.push_back(C);
496 }
497
498 /// Register a callback for a default optimizer pipeline extension point
499 ///
500 /// This extension point allows adding optimizations at the start of the full
501 /// LTO pipeline.
registerFullLinkTimeOptimizationEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)502 void registerFullLinkTimeOptimizationEarlyEPCallback(
503 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
504 FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C);
505 }
506
507 /// Register a callback for a default optimizer pipeline extension point
508 ///
509 /// This extension point allows adding optimizations at the end of the full
510 /// LTO pipeline.
registerFullLinkTimeOptimizationLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)511 void registerFullLinkTimeOptimizationLastEPCallback(
512 const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
513 FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
514 }
515
516 /// Register a callback for parsing an AliasAnalysis Name to populate
517 /// the given AAManager \p AA
registerParseAACallback(const std::function<bool (StringRef Name,AAManager & AA)> & C)518 void registerParseAACallback(
519 const std::function<bool(StringRef Name, AAManager &AA)> &C) {
520 AAParsingCallbacks.push_back(C);
521 }
522
523 /// {{@ Register callbacks for analysis registration with this PassBuilder
524 /// instance.
525 /// Callees register their analyses with the given AnalysisManager objects.
registerAnalysisRegistrationCallback(const std::function<void (CGSCCAnalysisManager &)> & C)526 void registerAnalysisRegistrationCallback(
527 const std::function<void(CGSCCAnalysisManager &)> &C) {
528 CGSCCAnalysisRegistrationCallbacks.push_back(C);
529 }
registerAnalysisRegistrationCallback(const std::function<void (FunctionAnalysisManager &)> & C)530 void registerAnalysisRegistrationCallback(
531 const std::function<void(FunctionAnalysisManager &)> &C) {
532 FunctionAnalysisRegistrationCallbacks.push_back(C);
533 }
registerAnalysisRegistrationCallback(const std::function<void (LoopAnalysisManager &)> & C)534 void registerAnalysisRegistrationCallback(
535 const std::function<void(LoopAnalysisManager &)> &C) {
536 LoopAnalysisRegistrationCallbacks.push_back(C);
537 }
registerAnalysisRegistrationCallback(const std::function<void (ModuleAnalysisManager &)> & C)538 void registerAnalysisRegistrationCallback(
539 const std::function<void(ModuleAnalysisManager &)> &C) {
540 ModuleAnalysisRegistrationCallbacks.push_back(C);
541 }
registerAnalysisRegistrationCallback(const std::function<void (MachineFunctionAnalysisManager &)> & C)542 void registerAnalysisRegistrationCallback(
543 const std::function<void(MachineFunctionAnalysisManager &)> &C) {
544 MachineFunctionAnalysisRegistrationCallbacks.push_back(C);
545 }
546 /// @}}
547
548 /// {{@ Register pipeline parsing callbacks with this pass builder instance.
549 /// Using these callbacks, callers can parse both a single pass name, as well
550 /// as entire sub-pipelines, and populate the PassManager instance
551 /// accordingly.
registerPipelineParsingCallback(const std::function<bool (StringRef Name,CGSCCPassManager &,ArrayRef<PipelineElement>)> & C)552 void registerPipelineParsingCallback(
553 const std::function<bool(StringRef Name, CGSCCPassManager &,
554 ArrayRef<PipelineElement>)> &C) {
555 CGSCCPipelineParsingCallbacks.push_back(C);
556 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,FunctionPassManager &,ArrayRef<PipelineElement>)> & C)557 void registerPipelineParsingCallback(
558 const std::function<bool(StringRef Name, FunctionPassManager &,
559 ArrayRef<PipelineElement>)> &C) {
560 FunctionPipelineParsingCallbacks.push_back(C);
561 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,LoopPassManager &,ArrayRef<PipelineElement>)> & C)562 void registerPipelineParsingCallback(
563 const std::function<bool(StringRef Name, LoopPassManager &,
564 ArrayRef<PipelineElement>)> &C) {
565 LoopPipelineParsingCallbacks.push_back(C);
566 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,ModulePassManager &,ArrayRef<PipelineElement>)> & C)567 void registerPipelineParsingCallback(
568 const std::function<bool(StringRef Name, ModulePassManager &,
569 ArrayRef<PipelineElement>)> &C) {
570 ModulePipelineParsingCallbacks.push_back(C);
571 }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,MachineFunctionPassManager &,ArrayRef<PipelineElement>)> & C)572 void registerPipelineParsingCallback(
573 const std::function<bool(StringRef Name, MachineFunctionPassManager &,
574 ArrayRef<PipelineElement>)> &C) {
575 MachineFunctionPipelineParsingCallbacks.push_back(C);
576 }
577 /// @}}
578
579 /// Register a callback for a top-level pipeline entry.
580 ///
581 /// If the PassManager type is not given at the top level of the pipeline
582 /// text, this Callback should be used to determine the appropriate stack of
583 /// PassManagers and populate the passed ModulePassManager.
584 void registerParseTopLevelPipelineCallback(
585 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
586 &C);
587
588 /// Add PGOInstrumenation passes for O0 only.
589 void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
590 bool IsCS, bool AtomicCounterUpdate,
591 std::string ProfileFile,
592 std::string ProfileRemappingFile,
593 IntrusiveRefCntPtr<vfs::FileSystem> FS);
594
595 /// Returns PIC. External libraries can use this to register pass
596 /// instrumentation callbacks.
getPassInstrumentationCallbacks()597 PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
598 return PIC;
599 }
600
601 // Invoke the callbacks registered for the various extension points.
602 // Custom pipelines should use these to invoke the callbacks registered
603 // by TargetMachines and other clients.
604 void invokePeepholeEPCallbacks(FunctionPassManager &FPM,
605 OptimizationLevel Level);
606 void invokeLateLoopOptimizationsEPCallbacks(LoopPassManager &LPM,
607 OptimizationLevel Level);
608 void invokeLoopOptimizerEndEPCallbacks(LoopPassManager &LPM,
609 OptimizationLevel Level);
610 void invokeScalarOptimizerLateEPCallbacks(FunctionPassManager &FPM,
611 OptimizationLevel Level);
612 void invokeCGSCCOptimizerLateEPCallbacks(CGSCCPassManager &CGPM,
613 OptimizationLevel Level);
614 void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
615 OptimizationLevel Level);
616 void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
617 OptimizationLevel Level);
618 void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
619 OptimizationLevel Level);
620 void invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
621 OptimizationLevel Level);
622 void invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
623 OptimizationLevel Level);
624 void invokePipelineStartEPCallbacks(ModulePassManager &MPM,
625 OptimizationLevel Level);
626 void invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM,
627 OptimizationLevel Level);
628
629 private:
630 // O1 pass pipeline
631 FunctionPassManager
632 buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
633 ThinOrFullLTOPhase Phase);
634
635 void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
636
637 void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
638 bool IsFullLTO);
639
640 static std::optional<std::vector<PipelineElement>>
641 parsePipelineText(StringRef Text);
642
643 Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
644 Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
645 Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
646 Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
647 Error parseMachinePass(MachineFunctionPassManager &MFPM,
648 const PipelineElement &E);
649 bool parseAAPassName(AAManager &AA, StringRef Name);
650
651 Error parseMachinePassPipeline(MachineFunctionPassManager &MFPM,
652 ArrayRef<PipelineElement> Pipeline);
653 Error parseLoopPassPipeline(LoopPassManager &LPM,
654 ArrayRef<PipelineElement> Pipeline);
655 Error parseFunctionPassPipeline(FunctionPassManager &FPM,
656 ArrayRef<PipelineElement> Pipeline);
657 Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
658 ArrayRef<PipelineElement> Pipeline);
659 Error parseModulePassPipeline(ModulePassManager &MPM,
660 ArrayRef<PipelineElement> Pipeline);
661
662 // Adds passes to do pre-inlining and related cleanup passes before
663 // profile instrumentation/matching (to enable better context sensitivity),
664 // and for memprof to enable better matching with missing debug frames.
665 void addPreInlinerPasses(ModulePassManager &MPM, OptimizationLevel Level,
666 ThinOrFullLTOPhase LTOPhase);
667
668 void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
669 bool RunProfileGen, bool IsCS,
670 bool AtomicCounterUpdate, std::string ProfileFile,
671 std::string ProfileRemappingFile,
672 IntrusiveRefCntPtr<vfs::FileSystem> FS);
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 // Module callbacks
688 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
689 OptimizerEarlyEPCallbacks;
690 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
691 OptimizerLastEPCallbacks;
692 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
693 FullLinkTimeOptimizationEarlyEPCallbacks;
694 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
695 FullLinkTimeOptimizationLastEPCallbacks;
696 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
697 PipelineStartEPCallbacks;
698 SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
699 PipelineEarlySimplificationEPCallbacks;
700
701 SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
702 ModuleAnalysisRegistrationCallbacks;
703 SmallVector<std::function<bool(StringRef, ModulePassManager &,
704 ArrayRef<PipelineElement>)>,
705 2>
706 ModulePipelineParsingCallbacks;
707 SmallVector<
708 std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
709 TopLevelPipelineParsingCallbacks;
710 // CGSCC callbacks
711 SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
712 CGSCCAnalysisRegistrationCallbacks;
713 SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
714 ArrayRef<PipelineElement>)>,
715 2>
716 CGSCCPipelineParsingCallbacks;
717 // Function callbacks
718 SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
719 FunctionAnalysisRegistrationCallbacks;
720 SmallVector<std::function<bool(StringRef, FunctionPassManager &,
721 ArrayRef<PipelineElement>)>,
722 2>
723 FunctionPipelineParsingCallbacks;
724 // Loop callbacks
725 SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
726 LoopAnalysisRegistrationCallbacks;
727 SmallVector<std::function<bool(StringRef, LoopPassManager &,
728 ArrayRef<PipelineElement>)>,
729 2>
730 LoopPipelineParsingCallbacks;
731 // AA callbacks
732 SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
733 AAParsingCallbacks;
734 // Machine pass callbackcs
735 SmallVector<std::function<void(MachineFunctionAnalysisManager &)>, 2>
736 MachineFunctionAnalysisRegistrationCallbacks;
737 SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &,
738 ArrayRef<PipelineElement>)>,
739 2>
740 MachineFunctionPipelineParsingCallbacks;
741 };
742
743 /// This utility template takes care of adding require<> and invalidate<>
744 /// passes for an analysis to a given \c PassManager. It is intended to be used
745 /// during parsing of a pass pipeline when parsing a single PipelineName.
746 /// When registering a new function analysis FancyAnalysis with the pass
747 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
748 /// like this:
749 ///
750 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
751 /// ArrayRef<PipelineElement> P) {
752 /// if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
753 /// FPM))
754 /// return true;
755 /// return false;
756 /// }
757 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
758 typename... ExtraArgTs>
parseAnalysisUtilityPasses(StringRef AnalysisName,StringRef PipelineName,PassManager<IRUnitT,AnalysisManagerT,ExtraArgTs...> & PM)759 bool parseAnalysisUtilityPasses(
760 StringRef AnalysisName, StringRef PipelineName,
761 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
762 if (!PipelineName.ends_with(">"))
763 return false;
764 // See if this is an invalidate<> pass name
765 if (PipelineName.starts_with("invalidate<")) {
766 PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
767 if (PipelineName != AnalysisName)
768 return false;
769 PM.addPass(InvalidateAnalysisPass<AnalysisT>());
770 return true;
771 }
772
773 // See if this is a require<> pass name
774 if (PipelineName.starts_with("require<")) {
775 PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
776 if (PipelineName != AnalysisName)
777 return false;
778 PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
779 ExtraArgTs...>());
780 return true;
781 }
782
783 return false;
784 }
785
786 // These are special since they are only for testing purposes.
787
788 /// No-op module pass which does nothing.
789 struct NoOpModulePass : PassInfoMixin<NoOpModulePass> {
runNoOpModulePass790 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
791 return PreservedAnalyses::all();
792 }
793 };
794
795 /// No-op module analysis.
796 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
797 friend AnalysisInfoMixin<NoOpModuleAnalysis>;
798 static AnalysisKey Key;
799
800 public:
801 struct Result {};
run(Module &,ModuleAnalysisManager &)802 Result run(Module &, ModuleAnalysisManager &) { return Result(); }
803 };
804
805 /// No-op CGSCC pass which does nothing.
806 struct NoOpCGSCCPass : PassInfoMixin<NoOpCGSCCPass> {
runNoOpCGSCCPass807 PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
808 LazyCallGraph &, CGSCCUpdateResult &UR) {
809 return PreservedAnalyses::all();
810 }
811 };
812
813 /// No-op CGSCC analysis.
814 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
815 friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
816 static AnalysisKey Key;
817
818 public:
819 struct Result {};
run(LazyCallGraph::SCC &,CGSCCAnalysisManager &,LazyCallGraph & G)820 Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
821 return Result();
822 }
823 };
824
825 /// No-op function pass which does nothing.
826 struct NoOpFunctionPass : PassInfoMixin<NoOpFunctionPass> {
runNoOpFunctionPass827 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
828 return PreservedAnalyses::all();
829 }
830 };
831
832 /// No-op function analysis.
833 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
834 friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
835 static AnalysisKey Key;
836
837 public:
838 struct Result {};
run(Function &,FunctionAnalysisManager &)839 Result run(Function &, FunctionAnalysisManager &) { return Result(); }
840 };
841
842 /// No-op loop nest pass which does nothing.
843 struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
runNoOpLoopNestPass844 PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
845 LoopStandardAnalysisResults &, LPMUpdater &) {
846 return PreservedAnalyses::all();
847 }
848 };
849
850 /// No-op loop pass which does nothing.
851 struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
runNoOpLoopPass852 PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
853 LoopStandardAnalysisResults &, LPMUpdater &) {
854 return PreservedAnalyses::all();
855 }
856 };
857
858 /// No-op machine function pass which does nothing.
859 struct NoOpMachineFunctionPass
860 : public MachinePassInfoMixin<NoOpMachineFunctionPass> {
runNoOpMachineFunctionPass861 PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
862 return PreservedAnalyses::all();
863 }
864 };
865
866 /// No-op loop analysis.
867 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
868 friend AnalysisInfoMixin<NoOpLoopAnalysis>;
869 static AnalysisKey Key;
870
871 public:
872 struct Result {};
run(Loop &,LoopAnalysisManager &,LoopStandardAnalysisResults &)873 Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
874 return Result();
875 }
876 };
877 }
878
879 #endif
880