LLVM  15.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 
27 #include "llvm/ADT/SmallVector.h"
28 #include "llvm/IR/PassManager.h"
29 #include "llvm/Support/Error.h"
30 
31 #include <map>
32 
33 namespace llvm {
34 class Module;
35 class Function;
36 class MachineFunction;
37 
38 extern template class AnalysisManager<MachineFunction>;
39 
40 /// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
42 public:
44 
45  MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {}
48  : FAM(&FAM), MAM(&MAM) {}
51  operator=(MachineFunctionAnalysisManager &&) = default;
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 
103 extern 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 
136 public:
137  MachineFunctionPassManager(bool DebugLogging = false,
138  bool RequireCodeGenSCCOrder = false,
139  bool VerifyMachineFunction = false)
140  : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
141  VerifyMachineFunction(VerifyMachineFunction) {}
144  operator=(MachineFunctionPassManager &&) = default;
145 
146  /// Run machine passes for a Module.
147  ///
148  /// The intended use is to start the codegen pipeline for a Module. The base
149  /// class's `run` method is deliberately hidden by this due to the observation
150  /// that we don't yet have the use cases of compositing two instances of
151  /// machine pass managers, or compositing machine pass managers with other
152  /// types of pass managers.
154 
155  template <typename PassT> void addPass(PassT &&Pass) {
156  Base::addPass(std::forward<PassT>(Pass));
157  PassConceptT *P = Passes.back().get();
158  addDoInitialization<PassT>(P);
159  addDoFinalization<PassT>(P);
160 
161  // Add machine module pass.
162  addRunOnModule<PassT>(P);
163  }
164 
165 private:
166  template <typename PassT>
167  using has_init_t = decltype(std::declval<PassT &>().doInitialization(
168  std::declval<Module &>(),
169  std::declval<MachineFunctionAnalysisManager &>()));
170 
171  template <typename PassT>
172  std::enable_if_t<!is_detected<has_init_t, PassT>::value>
173  addDoInitialization(PassConceptT *Pass) {}
174 
175  template <typename PassT>
176  std::enable_if_t<is_detected<has_init_t, PassT>::value>
177  addDoInitialization(PassConceptT *Pass) {
178  using PassModelT =
179  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
180  MachineFunctionAnalysisManager>;
181  auto *P = static_cast<PassModelT *>(Pass);
182  InitializationFuncs.emplace_back(
183  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
184  return P->Pass.doInitialization(M, MFAM);
185  });
186  }
187 
188  template <typename PassT>
189  using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
190  std::declval<Module &>(),
191  std::declval<MachineFunctionAnalysisManager &>()));
192 
193  template <typename PassT>
194  std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
195  addDoFinalization(PassConceptT *Pass) {}
196 
197  template <typename PassT>
198  std::enable_if_t<is_detected<has_fini_t, PassT>::value>
199  addDoFinalization(PassConceptT *Pass) {
200  using PassModelT =
201  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
202  MachineFunctionAnalysisManager>;
203  auto *P = static_cast<PassModelT *>(Pass);
204  FinalizationFuncs.emplace_back(
205  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
206  return P->Pass.doFinalization(M, MFAM);
207  });
208  }
209 
210  template <typename PassT>
211  using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
212  std::declval<Module &>(),
213  std::declval<MachineFunctionAnalysisManager &>()));
214 
215  template <typename PassT>
216  using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
217  std::declval<MachineFunction &>(),
218  std::declval<MachineFunctionAnalysisManager &>()));
219 
220  template <typename PassT>
221  std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
222  addRunOnModule(PassConceptT *Pass) {}
223 
224  template <typename PassT>
225  std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
226  addRunOnModule(PassConceptT *Pass) {
227  static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
228  "machine module pass needs to define machine function pass "
229  "api. sorry.");
230 
231  using PassModelT =
232  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
233  MachineFunctionAnalysisManager>;
234  auto *P = static_cast<PassModelT *>(Pass);
235  MachineModulePasses.emplace(
236  Passes.size() - 1,
237  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
238  return P->Pass.run(M, MFAM);
239  });
240  }
241 
242  using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
243  SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
244  SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
245 
246  using PassIndex = decltype(Passes)::size_type;
247  std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
248 
249  // Run codegen in the SCC order.
250  bool RequireCodeGenSCCOrder;
251 
252  bool VerifyMachineFunction;
253 };
254 
255 } // end namespace llvm
256 
257 #endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H
llvm::MachineFunctionAnalysisManager::getResult
PassT::Result & getResult(Function &F)
Get the result of an analysis pass for a Function.
Definition: MachinePassManager.h:56
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
Pass
print lazy value Lazy Value Info Printer Pass
Definition: LazyValueInfo.cpp:1978
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
FunctionExtras.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:780
llvm::Function
Definition: Function.h:60
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
Error.h
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
Passes
const char * Passes
Definition: PassBuilderBindings.cpp:46
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::MachineFunctionAnalysisManager::getCachedResult
PassT::Result * getCachedResult(Function &F)
Get the cached result of an analysis pass for a Function.
Definition: MachinePassManager.h:66
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::MachineFunctionAnalysisManager::MachineFunctionAnalysisManager
MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM, ModuleAnalysisManager &MAM)
Definition: MachinePassManager.h:46
llvm::MachineFunctionAnalysisManager::FAM
FunctionAnalysisManager * FAM
Definition: MachinePassManager.h:99
llvm::MachineFunctionAnalysisManager::MachineFunctionAnalysisManager
MachineFunctionAnalysisManager()
Definition: MachinePassManager.h:45
llvm::MachineFunctionAnalysisManager
An AnalysisManager<MachineFunction> that also exposes IR analysis results.
Definition: MachinePassManager.h:41
llvm::dxil::PointerTypeAnalysis::run
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Definition: PointerTypeAnalysis.cpp:101
llvm::MachineFunctionAnalysisManager::MAM
ModuleAnalysisManager * MAM
Definition: MachinePassManager.h:100
llvm::detail::PassConcept
Template for the abstract base class used to dispatch polymorphically over pass objects.
Definition: PassManagerInternal.h:37
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MachineFunctionAnalysisManager::getResult
PassT::Result & getResult(Module &M)
Get the result of an analysis pass for a Module.
Definition: MachinePassManager.h:73
Module
Machine Check Debug Module
Definition: MachineCheckDebugify.cpp:122
llvm::PassManager
Manages a sequence of passes over a particular unit of IR.
Definition: PassManager.h:469
llvm::MachineFunctionPassManager::MachineFunctionPassManager
MachineFunctionPassManager(bool DebugLogging=false, bool RequireCodeGenSCCOrder=false, bool VerifyMachineFunction=false)
Definition: MachinePassManager.h:137
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::AnalysisManager::getCachedResult
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:799
PassManager.h
llvm::MachineFunctionPassManager::addPass
void addPass(PassT &&Pass)
Definition: MachinePassManager.h:155
llvm::MachineFunctionPassManager
MachineFunctionPassManager adds/removes below features to/from the base PassManager template instanti...
Definition: MachinePassManager.h:132
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
SmallVector.h
llvm::AnalysisManager< MachineFunction >
llvm::codeview::PublicSymFlags::Function
@ Function
llvm::MachineFunctionAnalysisManager::getCachedResult
PassT::Result * getCachedResult(Module &M)
Get the cached result of an analysis pass for a Module.
Definition: MachinePassManager.h:82