Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  26. #include "llvm/ADT/FunctionExtras.h"
  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.
  41. class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> {
  42. public:
  43.   using Base = AnalysisManager<MachineFunction>;
  44.  
  45.   MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {}
  46.   MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM,
  47.                                  ModuleAnalysisManager &MAM)
  48.       : FAM(&FAM), MAM(&MAM) {}
  49.   MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default;
  50.   MachineFunctionAnalysisManager &
  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.
  99.   FunctionAnalysisManager *FAM;
  100.   ModuleAnalysisManager *MAM;
  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).
  132. class MachineFunctionPassManager
  133.     : public PassManager<MachineFunction, MachineFunctionAnalysisManager> {
  134.   using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;
  135.  
  136. public:
  137.   MachineFunctionPassManager(bool DebugLogging = false,
  138.                              bool RequireCodeGenSCCOrder = false,
  139.                              bool VerifyMachineFunction = false)
  140.       : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
  141.         VerifyMachineFunction(VerifyMachineFunction) {}
  142.   MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
  143.   MachineFunctionPassManager &
  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.
  153.   Error run(Module &M, MachineFunctionAnalysisManager &MFAM);
  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
  258.