LLVM 18.0.0git
MachinePassManager.h
Go to the documentation of this file.
1//===- PassManager.h --- Pass management for CodeGen ------------*- 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//
9// This header defines the pass manager interface for codegen. The codegen
10// pipeline consists of only machine function passes. There is no container
11// relationship between IR module/function and machine function in terms of pass
12// manager organization. So there is no need for adaptor classes (for example
13// ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
14// machine function passes, there is no proxy classes to handle cross-IR-unit
15// invalidation. IR analysis results are provided for machine function passes by
16// their respective analysis managers such as ModuleAnalysisManager and
17// FunctionAnalysisManager.
18//
19// TODO: Add MachineFunctionProperties support.
20//
21//===----------------------------------------------------------------------===//
22
23#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
24#define LLVM_CODEGEN_MACHINEPASSMANAGER_H
25
28#include "llvm/IR/PassManager.h"
29#include "llvm/Support/Error.h"
30
31#include <map>
32
33namespace llvm {
34class Module;
35class Function;
36class MachineFunction;
37
38extern template class AnalysisManager<MachineFunction>;
39
40/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
42public:
44
45 MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {}
48 : FAM(&FAM), MAM(&MAM) {}
52
53 /// Get the result of an analysis pass for a Function.
54 ///
55 /// Runs the analysis if a cached result is not available.
56 template <typename PassT> typename PassT::Result &getResult(Function &F) {
57 return FAM->getResult<PassT>(F);
58 }
59
60 /// Get the cached result of an analysis pass for a Function.
61 ///
62 /// This method never runs the analysis.
63 ///
64 /// \returns null if there is no cached result.
65 template <typename PassT>
66 typename PassT::Result *getCachedResult(Function &F) {
67 return FAM->getCachedResult<PassT>(F);
68 }
69
70 /// Get the result of an analysis pass for a Module.
71 ///
72 /// Runs the analysis if a cached result is not available.
73 template <typename PassT> typename PassT::Result &getResult(Module &M) {
74 return MAM->getResult<PassT>(M);
75 }
76
77 /// Get the cached result of an analysis pass for a Module.
78 ///
79 /// This method never runs the analysis.
80 ///
81 /// \returns null if there is no cached result.
82 template <typename PassT> typename PassT::Result *getCachedResult(Module &M) {
83 return MAM->getCachedResult<PassT>(M);
84 }
85
86 /// Get the result of an analysis pass for a MachineFunction.
87 ///
88 /// Runs the analysis if a cached result is not available.
89 using Base::getResult;
90
91 /// Get the cached result of an analysis pass for a MachineFunction.
92 ///
93 /// This method never runs the analysis.
94 ///
95 /// returns null if there is no cached result.
96 using Base::getCachedResult;
97
98 // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed.
101};
102
103extern template class PassManager<MachineFunction>;
104
105/// MachineFunctionPassManager adds/removes below features to/from the base
106/// PassManager template instantiation.
107///
108/// - Support passes that implement doInitialization/doFinalization. This is for
109/// machine function passes to work on module level constructs. One such pass
110/// is AsmPrinter.
111///
112/// - Support machine module pass which runs over the module (for example,
113/// MachineOutliner). A machine module pass needs to define the method:
114///
115/// ```Error run(Module &, MachineFunctionAnalysisManager &)```
116///
117/// FIXME: machine module passes still need to define the usual machine
118/// function pass interface, namely,
119/// `PreservedAnalyses run(MachineFunction &,
120/// MachineFunctionAnalysisManager &)`
121/// But this interface wouldn't be executed. It is just a placeholder
122/// to satisfy the pass manager type-erased inteface. This
123/// special-casing of machine module pass is due to its limited use
124/// cases and the unnecessary complexity it may bring to the machine
125/// pass manager.
126///
127/// - The base class `run` method is replaced by an alternative `run` method.
128/// See details below.
129///
130/// - Support codegening in the SCC order. Users include interprocedural
131/// register allocation (IPRA).
135
136public:
137 MachineFunctionPassManager(bool RequireCodeGenSCCOrder = false,
138 bool VerifyMachineFunction = false)
139 : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
140 VerifyMachineFunction(VerifyMachineFunction) {}
144
145 /// Run machine passes for a Module.
146 ///
147 /// The intended use is to start the codegen pipeline for a Module. The base
148 /// class's `run` method is deliberately hidden by this due to the observation
149 /// that we don't yet have the use cases of compositing two instances of
150 /// machine pass managers, or compositing machine pass managers with other
151 /// types of pass managers.
153
154 template <typename PassT> void addPass(PassT &&Pass) {
155 Base::addPass(std::forward<PassT>(Pass));
156 PassConceptT *P = Passes.back().get();
157 addDoInitialization<PassT>(P);
158 addDoFinalization<PassT>(P);
159
160 // Add machine module pass.
161 addRunOnModule<PassT>(P);
162 }
163
164private:
165 template <typename PassT>
166 using has_init_t = decltype(std::declval<PassT &>().doInitialization(
167 std::declval<Module &>(),
168 std::declval<MachineFunctionAnalysisManager &>()));
169
170 template <typename PassT>
171 std::enable_if_t<!is_detected<has_init_t, PassT>::value>
172 addDoInitialization(PassConceptT *Pass) {}
173
174 template <typename PassT>
175 std::enable_if_t<is_detected<has_init_t, PassT>::value>
176 addDoInitialization(PassConceptT *Pass) {
177 using PassModelT =
178 detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
179 MachineFunctionAnalysisManager>;
180 auto *P = static_cast<PassModelT *>(Pass);
181 InitializationFuncs.emplace_back(
182 [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
183 return P->Pass.doInitialization(M, MFAM);
184 });
185 }
186
187 template <typename PassT>
188 using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
189 std::declval<Module &>(),
190 std::declval<MachineFunctionAnalysisManager &>()));
191
192 template <typename PassT>
193 std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
194 addDoFinalization(PassConceptT *Pass) {}
195
196 template <typename PassT>
197 std::enable_if_t<is_detected<has_fini_t, PassT>::value>
198 addDoFinalization(PassConceptT *Pass) {
199 using PassModelT =
200 detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
201 MachineFunctionAnalysisManager>;
202 auto *P = static_cast<PassModelT *>(Pass);
203 FinalizationFuncs.emplace_back(
204 [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
205 return P->Pass.doFinalization(M, MFAM);
206 });
207 }
208
209 template <typename PassT>
210 using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
211 std::declval<Module &>(),
212 std::declval<MachineFunctionAnalysisManager &>()));
213
214 template <typename PassT>
215 using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
216 std::declval<MachineFunction &>(),
217 std::declval<MachineFunctionAnalysisManager &>()));
218
219 template <typename PassT>
220 std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
221 addRunOnModule(PassConceptT *Pass) {}
222
223 template <typename PassT>
224 std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
225 addRunOnModule(PassConceptT *Pass) {
226 static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
227 "machine module pass needs to define machine function pass "
228 "api. sorry.");
229
230 using PassModelT =
231 detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
232 MachineFunctionAnalysisManager>;
233 auto *P = static_cast<PassModelT *>(Pass);
234 MachineModulePasses.emplace(
235 Passes.size() - 1,
236 [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
237 return P->Pass.run(M, MFAM);
238 });
239 }
240
241 using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
242 SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
243 SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
244
245 using PassIndex = decltype(Passes)::size_type;
246 std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
247
248 // Run codegen in the SCC order.
249 bool RequireCodeGenSCCOrder;
250
251 bool VerifyMachineFunction;
252};
253
254} // end namespace llvm
255
256#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
print lazy value Lazy Value Info Printer Pass
#define F(x, y, z)
Definition: MD5.cpp:55
Machine Check Debug Module
#define P(N)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const char * Passes
This header defines various interfaces for pass management in LLVM.
This file defines the SmallVector class.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:793
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:774
Lightweight error class with error context and mandatory checking.
Definition: Error.h:154
An AnalysisManager<MachineFunction> that also exposes IR analysis results.
MachineFunctionAnalysisManager & operator=(MachineFunctionAnalysisManager &&)=default
PassT::Result * getCachedResult(Function &F)
Get the cached result of an analysis pass for a Function.
PassT::Result * getCachedResult(Module &M)
Get the cached result of an analysis pass for a Module.
MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&)=default
PassT::Result & getResult(Module &M)
Get the result of an analysis pass for a Module.
MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM, ModuleAnalysisManager &MAM)
PassT::Result & getResult(Function &F)
Get the result of an analysis pass for a Function.
MachineFunctionPassManager adds/removes below features to/from the base PassManager template instanti...
MachineFunctionPassManager & operator=(MachineFunctionPassManager &&)=default
MachineFunctionPassManager(bool RequireCodeGenSCCOrder=false, bool VerifyMachineFunction=false)
MachineFunctionPassManager(MachineFunctionPassManager &&)=default
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Manages a sequence of passes over a particular unit of IR.
Definition: PassManager.h:470
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Template for the abstract base class used to dispatch polymorphically over pass objects.