LLVM  13.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"
29 #include "llvm/IR/PassManager.h"
30 #include "llvm/Support/Error.h"
32 
33 namespace llvm {
34 class Module;
35 
36 extern template class AnalysisManager<MachineFunction>;
37 
38 /// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
40 public:
42 
43  MachineFunctionAnalysisManager() : Base(), FAM(nullptr), MAM(nullptr) {}
46  : Base(), FAM(&FAM), MAM(&MAM) {}
49  operator=(MachineFunctionAnalysisManager &&) = default;
50 
51  /// Get the result of an analysis pass for a Function.
52  ///
53  /// Runs the analysis if a cached result is not available.
54  template <typename PassT> typename PassT::Result &getResult(Function &F) {
55  return FAM->getResult<PassT>(F);
56  }
57 
58  /// Get the cached result of an analysis pass for a Function.
59  ///
60  /// This method never runs the analysis.
61  ///
62  /// \returns null if there is no cached result.
63  template <typename PassT>
64  typename PassT::Result *getCachedResult(Function &F) {
65  return FAM->getCachedResult<PassT>(F);
66  }
67 
68  /// Get the result of an analysis pass for a Module.
69  ///
70  /// Runs the analysis if a cached result is not available.
71  template <typename PassT> typename PassT::Result &getResult(Module &M) {
72  return MAM->getResult<PassT>(M);
73  }
74 
75  /// Get the cached result of an analysis pass for a Module.
76  ///
77  /// This method never runs the analysis.
78  ///
79  /// \returns null if there is no cached result.
80  template <typename PassT> typename PassT::Result *getCachedResult(Module &M) {
81  return MAM->getCachedResult<PassT>(M);
82  }
83 
84  /// Get the result of an analysis pass for a MachineFunction.
85  ///
86  /// Runs the analysis if a cached result is not available.
87  using Base::getResult;
88 
89  /// Get the cached result of an analysis pass for a MachineFunction.
90  ///
91  /// This method never runs the analysis.
92  ///
93  /// returns null if there is no cached result.
94  using Base::getCachedResult;
95 
96  // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed.
99 };
100 
101 extern template class PassManager<MachineFunction>;
102 
103 /// MachineFunctionPassManager adds/removes below features to/from the base
104 /// PassManager template instantiation.
105 ///
106 /// - Support passes that implement doInitialization/doFinalization. This is for
107 /// machine function passes to work on module level constructs. One such pass
108 /// is AsmPrinter.
109 ///
110 /// - Support machine module pass which runs over the module (for example,
111 /// MachineOutliner). A machine module pass needs to define the method:
112 ///
113 /// ```Error run(Module &, MachineFunctionAnalysisManager &)```
114 ///
115 /// FIXME: machine module passes still need to define the usual machine
116 /// function pass interface, namely,
117 /// `PreservedAnalyses run(MachineFunction &,
118 /// MachineFunctionAnalysisManager &)`
119 /// But this interface wouldn't be executed. It is just a placeholder
120 /// to satisfy the pass manager type-erased inteface. This
121 /// special-casing of machine module pass is due to its limited use
122 /// cases and the unnecessary complexity it may bring to the machine
123 /// pass manager.
124 ///
125 /// - The base class `run` method is replaced by an alternative `run` method.
126 /// See details below.
127 ///
128 /// - Support codegening in the SCC order. Users include interprocedural
129 /// register allocation (IPRA).
133 
134 public:
135  MachineFunctionPassManager(bool DebugLogging = false,
136  bool RequireCodeGenSCCOrder = false,
137  bool VerifyMachineFunction = false)
138  : Base(), RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
139  VerifyMachineFunction(VerifyMachineFunction) {}
142  operator=(MachineFunctionPassManager &&) = default;
143 
144  /// Run machine passes for a Module.
145  ///
146  /// The intended use is to start the codegen pipeline for a Module. The base
147  /// class's `run` method is deliberately hidden by this due to the observation
148  /// that we don't yet have the use cases of compositing two instances of
149  /// machine pass managers, or compositing machine pass managers with other
150  /// types of pass managers.
152 
153  template <typename PassT> void addPass(PassT &&Pass) {
154  Base::addPass(std::forward<PassT>(Pass));
155  PassConceptT *P = Passes.back().get();
156  addDoInitialization<PassT>(P);
157  addDoFinalization<PassT>(P);
158 
159  // Add machine module pass.
160  addRunOnModule<PassT>(P);
161  }
162 
163 private:
164  template <typename PassT>
165  using has_init_t = decltype(std::declval<PassT &>().doInitialization(
166  std::declval<Module &>(),
167  std::declval<MachineFunctionAnalysisManager &>()));
168 
169  template <typename PassT>
170  std::enable_if_t<!is_detected<has_init_t, PassT>::value>
171  addDoInitialization(PassConceptT *Pass) {}
172 
173  template <typename PassT>
174  std::enable_if_t<is_detected<has_init_t, PassT>::value>
175  addDoInitialization(PassConceptT *Pass) {
176  using PassModelT =
177  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
178  MachineFunctionAnalysisManager>;
179  auto *P = static_cast<PassModelT *>(Pass);
180  InitializationFuncs.emplace_back(
181  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
182  return P->Pass.doInitialization(M, MFAM);
183  });
184  }
185 
186  template <typename PassT>
187  using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
188  std::declval<Module &>(),
189  std::declval<MachineFunctionAnalysisManager &>()));
190 
191  template <typename PassT>
192  std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
193  addDoFinalization(PassConceptT *Pass) {}
194 
195  template <typename PassT>
196  std::enable_if_t<is_detected<has_fini_t, PassT>::value>
197  addDoFinalization(PassConceptT *Pass) {
198  using PassModelT =
199  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
200  MachineFunctionAnalysisManager>;
201  auto *P = static_cast<PassModelT *>(Pass);
202  FinalizationFuncs.emplace_back(
203  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
204  return P->Pass.doFinalization(M, MFAM);
205  });
206  }
207 
208  template <typename PassT>
209  using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
210  std::declval<Module &>(),
211  std::declval<MachineFunctionAnalysisManager &>()));
212 
213  template <typename PassT>
214  using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
215  std::declval<MachineFunction &>(),
216  std::declval<MachineFunctionAnalysisManager &>()));
217 
218  template <typename PassT>
219  std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
220  addRunOnModule(PassConceptT *Pass) {}
221 
222  template <typename PassT>
223  std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
224  addRunOnModule(PassConceptT *Pass) {
225  static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
226  "machine module pass needs to define machine function pass "
227  "api. sorry.");
228 
229  using PassModelT =
230  detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
231  MachineFunctionAnalysisManager>;
232  auto *P = static_cast<PassModelT *>(Pass);
233  MachineModulePasses.emplace(
234  Passes.size() - 1,
235  [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
236  return P->Pass.run(M, MFAM);
237  });
238  }
239 
240  using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
241  SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
242  SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
243 
244  using PassIndex = decltype(Passes)::size_type;
245  std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
246 
247  // Run codegen in the SCC order.
248  bool RequireCodeGenSCCOrder;
249 
250  bool VerifyMachineFunction;
251 };
252 
253 } // end namespace llvm
254 
255 #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:54
llvm
Definition: AllocatorList.h:23
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:1947
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:769
llvm::Function
Definition: Function.h:61
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:56
llvm::MachineFunctionAnalysisManager::getCachedResult
PassT::Result * getCachedResult(Function &F)
Get the cached result of an analysis pass for a Function.
Definition: MachinePassManager.h:64
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::MachineFunctionAnalysisManager::MachineFunctionAnalysisManager
MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM, ModuleAnalysisManager &MAM)
Definition: MachinePassManager.h:44
llvm::MachineFunctionAnalysisManager::FAM
FunctionAnalysisManager * FAM
Definition: MachinePassManager.h:97
llvm::MachineFunctionAnalysisManager::MachineFunctionAnalysisManager
MachineFunctionAnalysisManager()
Definition: MachinePassManager.h:43
llvm::MachineFunctionAnalysisManager
An AnalysisManager<MachineFunction> that also exposes IR analysis results.
Definition: MachinePassManager.h:39
llvm::MachineFunctionAnalysisManager::MAM
ModuleAnalysisManager * MAM
Definition: MachinePassManager.h:98
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:67
llvm::MachineFunctionAnalysisManager::getResult
PassT::Result & getResult(Module &M)
Get the result of an analysis pass for a Module.
Definition: MachinePassManager.h:71
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:466
llvm::MachineFunctionPassManager::MachineFunctionPassManager
MachineFunctionPassManager(bool DebugLogging=false, bool RequireCodeGenSCCOrder=false, bool VerifyMachineFunction=false)
Definition: MachinePassManager.h:135
type_traits.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
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:788
PassManager.h
llvm::MachineFunctionPassManager::addPass
void addPass(PassT &&Pass)
Definition: MachinePassManager.h:153
llvm::MachineFunctionPassManager
MachineFunctionPassManager adds/removes below features to/from the base PassManager template instanti...
Definition: MachinePassManager.h:130
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
SmallVector.h
llvm::AnalysisManager< MachineFunction >
MachineFunction.h
llvm::MachineFunctionAnalysisManager::getCachedResult
PassT::Result * getCachedResult(Module &M)
Get the cached result of an analysis pass for a Module.
Definition: MachinePassManager.h:80