LLVM 24.0.0git
CodeGenPassBuilder.h
Go to the documentation of this file.
1//===- Construction of codegen 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 producing common pass manager configurations.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_PASSES_CODEGENPASSBUILDER_H
15#define LLVM_PASSES_CODEGENPASSBUILDER_H
16
20#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/PassManager.h"
26#include "llvm/Support/Error.h"
29#include <cassert>
30#include <utility>
31
32namespace llvm {
33
34// FIXME: Dummy target independent passes definitions that have not yet been
35// ported to new pass manager. Once they do, remove these.
36#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME) \
37 struct PASS_NAME : public OptionalPassInfoMixin<PASS_NAME> { \
38 template <typename... Ts> PASS_NAME(Ts &&...) {} \
39 PreservedAnalyses run(Function &, FunctionAnalysisManager &) { \
40 return PreservedAnalyses::all(); \
41 } \
42 };
43#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME) \
44 struct PASS_NAME : public OptionalPassInfoMixin<PASS_NAME> { \
45 template <typename... Ts> PASS_NAME(Ts &&...) {} \
46 PreservedAnalyses run(Module &, ModuleAnalysisManager &) { \
47 return PreservedAnalyses::all(); \
48 } \
49 };
50#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME) \
51 struct PASS_NAME : public OptionalPassInfoMixin<PASS_NAME> { \
52 template <typename... Ts> PASS_NAME(Ts &&...) {} \
53 PreservedAnalyses run(MachineFunction &, \
54 MachineFunctionAnalysisManager &) { \
55 return PreservedAnalyses::all(); \
56 } \
57 };
58#include "llvm/Passes/MachinePassRegistry.def"
59
60class PassManagerWrapper {
61private:
62 PassManagerWrapper(ModulePassManager &ModulePM) : MPM(ModulePM) {};
63
67
68 friend class CodeGenPassBuilder;
69};
70
71/// This class provides access to building LLVM's passes.
72///
73/// Its members provide the baseline state available to passes during their
74/// construction. The \c MachinePassRegistry.def file specifies how to construct
75/// all of the built-in passes, and those may reference these members during
76/// construction.
77///
78/// Targets customize the pipeline by deriving from this class and overriding
79/// the virtual add* hooks below: the add%Stage hooks replace a whole stage of
80/// the pipeline, while the addPre%Stage / addPost%Stage hooks inject passes
81/// around one. See addMachinePasses for how they fit together.
82///
83/// Dispatch is virtual rather than templated on the derived builder so that the
84/// target-independent pipeline is emitted once for the whole build instead of
85/// once per target.
87public:
93
96 CodeGenFileType FileType, MCContext &Ctx);
97
101
102protected:
103 template <typename PassT>
104 using is_module_pass_t = decltype(std::declval<PassT &>().run(
105 std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
106
107 template <typename PassT>
108 using is_function_pass_t = decltype(std::declval<PassT &>().run(
109 std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));
110
111 template <typename PassT>
112 using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
113 std::declval<MachineFunction &>(),
114 std::declval<MachineFunctionAnalysisManager &>()));
115
116 template <typename PassT>
118 bool Force = false, StringRef Name = PassT::name()) {
120 "Only function passes are supported.");
121 if (!Force && !runBeforeAdding(Name))
122 return;
123 PMW.FPM.addPass(std::forward<PassT>(Pass));
124 }
125
126 template <typename PassT>
127 void addModulePass(PassT &&Pass, PassManagerWrapper &PMW, bool Force = false,
128 StringRef Name = PassT::name()) {
130 "Only module passes are suported.");
131 assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
132 "You cannot insert a module pass without first flushing the current "
133 "function pipelines to the module pipeline.");
134 if (!Force && !runBeforeAdding(Name))
135 return;
136 PMW.MPM.addPass(std::forward<PassT>(Pass));
137 }
138
139 template <typename PassT>
141 bool Force = false,
142 StringRef Name = PassT::name()) {
144 "Only machine function passes are supported.");
145
146 if (!Force && !runBeforeAdding(Name))
147 return;
148 PMW.MFPM.addPass(std::forward<PassT>(Pass));
149 for (auto &C : AfterCallbacks)
150 C(Name, PMW.MFPM);
151 }
152
153 void flushFPMsToMPM(PassManagerWrapper &PMW,
154 bool FreeMachineFunctions = false);
155
157 assert(!AddInCGSCCOrder);
158 assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
159 "Requiring CGSCC ordering requires flushing the current function "
160 "pipelines to the MPM.");
161 AddInCGSCCOrder = true;
162 }
163
165 assert(AddInCGSCCOrder);
166 assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
167 "Stopping CGSCC ordering requires flushing the current function "
168 "pipelines to the MPM.");
169 AddInCGSCCOrder = false;
170 }
171
175 /// Whether no -stop-before/-stop-after option ends the pipeline early.
176 bool CompletesPipeline = true;
177
178 CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
179
180 /// Check whether or not GlobalISel should abort on error.
181 /// When this is disabled, GlobalISel will fall back on SDISel instead of
182 /// erroring out.
184 return TM.Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
185 }
186
187 /// Check whether or not a diagnostic should be emitted when GlobalISel
188 /// uses the fallback path. In other words, it will emit a diagnostic
189 /// when GlobalISel failed and isGlobalISelAbortEnabled is false.
191 return TM.Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
192 }
193
194 /// addInstSelector - This method should install an instruction selector pass,
195 /// which converts from LLVM code to machine instructions.
196 virtual Error addInstSelector(PassManagerWrapper &PMW);
197
198 /// Target can override this to add GlobalMergePass before all IR passes.
200
201 /// Add passes that optimize instruction level parallelism for out-of-order
202 /// targets. These passes are run while the machine code is still in SSA
203 /// form, so they can use MachineTraceMetrics to control their heuristics.
204 ///
205 /// All passes added here should preserve the MachineDominatorTree,
206 /// MachineLoopInfo, and MachineTraceMetrics analyses.
207 virtual void addILPOpts(PassManagerWrapper &PMW) {}
208
209 /// This method may be implemented by targets that want to run passes
210 /// immediately before register allocation.
211 virtual void addPreRegAlloc(PassManagerWrapper &PMW) {}
212
213 /// Return true if the MachinePipeliner should run before addPreRegAlloc by
214 /// default. -enable-pipeliner overrides this.
215 virtual bool isMachinePipelinerEnabled() const { return false; }
216
217 /// addPreRewrite - Add passes to the optimized register allocation pipeline
218 /// after register allocation is complete, but before virtual registers are
219 /// rewritten to physical registers.
220 ///
221 /// These passes must preserve VirtRegMap and LiveIntervals, and when running
222 /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
223 /// When these passes run, VirtRegMap contains legal physreg assignments for
224 /// all virtual registers.
225 ///
226 /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
227 /// be honored. This is also not generally used for the fast variant,
228 /// where the allocation and rewriting are done in one pass.
229 virtual void addPreRewrite(PassManagerWrapper &PMW) {}
230
231 /// Add passes to be run immediately after virtual registers are rewritten
232 /// to physical registers.
233 virtual void addPostRewrite(PassManagerWrapper &PMW) {}
234
235 /// This method may be implemented by targets that want to run passes after
236 /// register allocation pass pipeline but before prolog-epilog insertion.
238
239 /// This method may be implemented by targets that want to run passes after
240 /// prolog-epilog insertion and before the second instruction scheduling pass.
241 virtual void addPreSched2(PassManagerWrapper &PMW) {}
242
243 /// This pass may be implemented by targets that want to run passes
244 /// immediately before machine code is emitted.
245 virtual void addPreEmitPass(PassManagerWrapper &PMW) {}
246
247 /// Targets may add passes immediately before machine code is emitted in this
248 /// callback. This is called even later than `addPreEmitPass`.
249 // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
250 // position and remove the `2` suffix here as this callback is what
251 // `addPreEmitPass` *should* be but in reality isn't.
253
254 /// {{@ For GlobalISel
255 ///
256
257 /// addPreISel - This method should add any "last minute" LLVM->LLVM
258 /// passes (which are run just before instruction selector).
259 virtual void addPreISel(PassManagerWrapper &PMW) {}
260
261 /// This method should install an IR translator pass, which converts from
262 /// LLVM code to machine instructions with possibly generic opcodes.
263 virtual Error addIRTranslator(PassManagerWrapper &PMW);
264
265 /// This method may be implemented by targets that want to run passes
266 /// immediately before legalization.
268
269 /// This method should install a legalize pass, which converts the instruction
270 /// sequence into one that can be selected by the target.
271 virtual Error addLegalizeMachineIR(PassManagerWrapper &PMW);
272
273 /// This method may be implemented by targets that want to run passes
274 /// immediately before the register bank selection.
276
277 /// This method should install a register bank selector pass, which
278 /// assigns register banks to virtual registers without a register
279 /// class or register banks.
280 virtual Error addRegBankSelect(PassManagerWrapper &PMW);
281
282 /// This method may be implemented by targets that want to run passes
283 /// immediately before the (global) instruction selection.
285
286 /// This method should install a (global) instruction selector pass, which
287 /// converts possibly generic instructions to fully target-specific
288 /// instructions, thereby constraining all generic virtual registers to
289 /// register classes.
290 virtual Error addGlobalInstructionSelect(PassManagerWrapper &PMW);
291 /// @}}
292
293 /// High level function that adds all passes necessary to go from llvm IR
294 /// representation to the MI representation.
295 /// Adds IR based lowering and target specific optimization passes and finally
296 /// the core instruction selection passes.
297 void addISelPasses(PassManagerWrapper &PMW);
298
299 /// Add the actual instruction selection passes. This does not include
300 /// preparation passes on IR.
301 Error addCoreISelPasses(PassManagerWrapper &PMW);
302
303 /// Add the complete, standard set of LLVM CodeGen passes.
304 /// Fully developed targets will not generally override this.
305 virtual Error addMachinePasses(PassManagerWrapper &PMW);
306
307 /// Add passes to lower exception handling for the code generator.
308 virtual void addPassesToHandleExceptions(PassManagerWrapper &PMW);
309
310 /// Add common target configurable passes that perform LLVM IR to IR
311 /// transforms following machine independent optimization.
312 virtual void addIRPasses(PassManagerWrapper &PMW);
313
314 /// Add pass to prepare the LLVM IR for code generation. This should be done
315 /// before exception handling preparation passes.
316 virtual void addCodeGenPrepare(PassManagerWrapper &PMW);
317
318 /// Add common passes that perform LLVM IR to IR transforms in preparation for
319 /// instruction selection.
320 virtual void addISelPrepare(PassManagerWrapper &PMW);
321
322 /// Methods with trivial inline returns are convenient points in the common
323 /// codegen pass pipeline where targets may insert passes. Methods with
324 /// out-of-line standard implementations are major CodeGen stages called by
325 /// addMachinePasses. Some targets may override major stages when inserting
326 /// passes is insufficient, but maintaining overriden stages is more work.
327 ///
328
329 /// addMachineSSAOptimization - Add standard passes that optimize machine
330 /// instructions in SSA form.
331 virtual void addMachineSSAOptimization(PassManagerWrapper &PMW);
332
333 /// addFastRegAlloc - Add the minimum set of target-independent passes that
334 /// are required for fast register allocation.
335 virtual Error addFastRegAlloc(PassManagerWrapper &PMW);
336
337 /// addOptimizedRegAlloc - Add passes related to register allocation.
338 /// CodeGenTargetMachineImpl provides standard regalloc passes for most
339 /// targets.
340 virtual Error addOptimizedRegAlloc(PassManagerWrapper &PMW);
341
342 /// Add passes that optimize machine instructions after register allocation.
343 virtual void addMachineLateOptimization(PassManagerWrapper &PMW);
344
345 /// addGCPasses - Add late codegen passes that analyze code for garbage
346 /// collection. This should return true if GC info should be printed after
347 /// these passes.
348 virtual void addGCPasses(PassManagerWrapper &PMW) {}
349
350 /// Add standard basic block placement passes.
351 virtual void addBlockPlacement(PassManagerWrapper &PMW);
352
354
355 virtual void addAsmPrinterBegin(PassManagerWrapper &PMW);
356
357 virtual void addAsmPrinter(PassManagerWrapper &PMW);
358
359 virtual void addAsmPrinterEnd(PassManagerWrapper &PMW);
360
361 /// Utilities for targets to add passes to the pass manager.
362 ///
363
364 /// Create the register allocator pass for this target at the current
365 /// optimization level.
366 virtual void addTargetRegisterAllocator(PassManagerWrapper &PMW,
367 bool Optimized);
368
369 /// addMachinePasses helper to create the target-selected or overriden
370 /// regalloc pass.
371 void addRegAllocPass(PassManagerWrapper &PMW, bool Optimized);
372
373 /// Add core register allocator passes which do the actual register assignment
374 /// and rewriting. addRegAssignAndRewriteOptimized should return true if any
375 /// passes were added.
376 virtual Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW);
377 virtual Expected<bool>
378 addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW);
379
380 /// Allow the target to disable a specific pass by default.
381 /// Backend can declare unwanted passes in constructor.
382 template <typename... PassTs> void disablePass() {
383 BeforeCallbacks.emplace_back(
384 [](StringRef Name) { return ((Name != PassTs::name()) && ...); });
385 }
386
387 /// Insert InsertedPass pass after TargetPass pass.
388 /// Only machine function passes are supported.
389 template <typename TargetPassT, typename InsertedPassT>
390 void insertPass(InsertedPassT &&Pass) {
391 AfterCallbacks.emplace_back(
392 [&](StringRef Name, MachineFunctionPassManager &MFPM) mutable {
393 if (Name == TargetPassT::name() &&
394 runBeforeAdding(InsertedPassT::name())) {
395 MFPM.addPass(std::forward<InsertedPassT>(Pass));
396 }
397 });
398 }
399
400private:
401 bool runBeforeAdding(StringRef Name) {
402 bool ShouldAdd = true;
403 for (auto &C : BeforeCallbacks)
404 ShouldAdd &= C(Name);
405 return ShouldAdd;
406 }
407
408 void setStartStopPasses(const TargetPassConfig::StartStopInfo &Info);
409
410 Error verifyStartStop(const TargetPassConfig::StartStopInfo &Info) const;
411
412 SmallVector<llvm::unique_function<bool(StringRef)>, 4> BeforeCallbacks;
413 SmallVector<
414 llvm::unique_function<void(StringRef, MachineFunctionPassManager &)>, 4>
415 AfterCallbacks;
416
417 /// Helper variable for `-start-before/-start-after/-stop-before/-stop-after`
418 bool Started = true;
419 bool Stopped = true;
420 bool AddInCGSCCOrder = false;
421};
422
423} // namespace llvm
424
425#endif // LLVM_PASSES_CODEGENPASSBUILDER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_ABI
Definition Compiler.h:211
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
This header defines various interfaces for pass management in LLVM.
ModuleAnalysisManager MAM
This file contains library features backported from future STL versions.
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
virtual void addPreEmitPass(PassManagerWrapper &PMW)
This pass may be implemented by targets that want to run passes immediately before machine code is em...
void disablePass()
Allow the target to disable a specific pass by default.
void addMachineFunctionPass(PassT &&Pass, PassManagerWrapper &PMW, bool Force=false, StringRef Name=PassT::name())
CodeGenPassBuilder(TargetMachine &TM, const CGPassBuilderOption &Opts, PassInstrumentationCallbacks *PIC)
virtual void addPreRewrite(PassManagerWrapper &PMW)
addPreRewrite - Add passes to the optimized register allocation pipeline after register allocation is...
void insertPass(InsertedPassT &&Pass)
Insert InsertedPass pass after TargetPass pass.
void addFunctionPass(PassT &&Pass, PassManagerWrapper &PMW, bool Force=false, StringRef Name=PassT::name())
CodeGenPassBuilder & operator=(const CodeGenPassBuilder &)=delete
Error buildPipeline(ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, MCContext &Ctx)
virtual void addPreRegAlloc(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes immediately before register allocat...
decltype(std::declval< PassT & >().run( std::declval< Module & >(), std::declval< ModuleAnalysisManager & >())) is_module_pass_t
virtual void addPostRegAlloc(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes after register allocation pass pipe...
bool isGlobalISelAbortEnabled() const
Check whether or not GlobalISel should abort on error.
virtual void addPreSched2(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes after prolog-epilog insertion and b...
virtual void addPreEmitPass2(PassManagerWrapper &PMW)
Targets may add passes immediately before machine code is emitted in this callback.
virtual void addPreRegBankSelect(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes immediately before the register ban...
virtual bool isMachinePipelinerEnabled() const
Return true if the MachinePipeliner should run before addPreRegAlloc by default.
virtual void addGlobalMergePass(PassManagerWrapper &PMW)
Target can override this to add GlobalMergePass before all IR passes.
decltype(std::declval< PassT & >().run( std::declval< Function & >(), std::declval< FunctionAnalysisManager & >())) is_function_pass_t
CodeGenOptLevel getOptLevel() const
virtual void addPreLegalizeMachineIR(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes immediately before legalization.
virtual void addPreISel(PassManagerWrapper &PMW)
{{@ For GlobalISel
virtual void addPostBBSections(PassManagerWrapper &PMW)
void addModulePass(PassT &&Pass, PassManagerWrapper &PMW, bool Force=false, StringRef Name=PassT::name())
PassInstrumentationCallbacks * getPassInstrumentationCallbacks() const
void stopAddingInCGSCCOrder(PassManagerWrapper &PMW)
virtual void addPreGlobalInstructionSelect(PassManagerWrapper &PMW)
This method may be implemented by targets that want to run passes immediately before the (global) ins...
virtual void addILPOpts(PassManagerWrapper &PMW)
Add passes that optimize instruction level parallelism for out-of-order targets.
PassInstrumentationCallbacks * PIC
virtual void addPostRewrite(PassManagerWrapper &PMW)
Add passes to be run immediately after virtual registers are rewritten to physical registers.
bool reportDiagnosticWhenGlobalISelFallback() const
Check whether or not a diagnostic should be emitted when GlobalISel uses the fallback path.
decltype(std::declval< PassT & >().run( std::declval< MachineFunction & >(), std::declval< MachineFunctionAnalysisManager & >())) is_machine_function_pass_t
virtual void addGCPasses(PassManagerWrapper &PMW)
addGCPasses - Add late codegen passes that analyze code for garbage collection.
CodeGenPassBuilder(const CodeGenPassBuilder &)=delete
void requireCGSCCOrder(PassManagerWrapper &PMW)
bool CompletesPipeline
Whether no -stop-before/-stop-after option ends the pipeline early.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
Context object for machine code objects.
Definition MCContext.h:83
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
bool isEmpty() const
Returns if the pass manager contains any passes.
Pass interface - Implemented by all 'passes'.
Definition Pass.h:97
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Primary interface to the complete machine description for the target machine.
An abstract base class for streams implementations that also support a pwrite operation.
unique_function is a type-erasing functor similar to std::function.
This is an optimization pass for GlobalISel generic memory operations.
CodeGenFileType
These enums are meant to be passed into addPassesToEmitFile to indicate what type of file to emit,...
Definition CodeGen.h:309
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:280
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39