MachinePassManager.h 9.7 KB

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