- //===- PassManager.h --- Pass management for CodeGen ------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This header defines the pass manager interface for codegen. The codegen 
- // pipeline consists of only machine function passes. There is no container 
- // relationship between IR module/function and machine function in terms of pass 
- // manager organization. So there is no need for adaptor classes (for example 
- // ModuleToMachineFunctionAdaptor). Since invalidation could only happen among 
- // machine function passes, there is no proxy classes to handle cross-IR-unit 
- // invalidation. IR analysis results are provided for machine function passes by 
- // their respective analysis managers such as ModuleAnalysisManager and 
- // FunctionAnalysisManager. 
- // 
- // TODO: Add MachineFunctionProperties support. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H 
- #define LLVM_CODEGEN_MACHINEPASSMANAGER_H 
-   
- #include "llvm/ADT/FunctionExtras.h" 
- #include "llvm/ADT/SmallVector.h" 
- #include "llvm/IR/PassManager.h" 
- #include "llvm/Support/Error.h" 
-   
- #include <map> 
-   
- namespace llvm { 
- class Module; 
- class Function; 
- class MachineFunction; 
-   
- extern template class AnalysisManager<MachineFunction>; 
-   
- /// An AnalysisManager<MachineFunction> that also exposes IR analysis results. 
- class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> { 
- public: 
-   using Base = AnalysisManager<MachineFunction>; 
-   
-   MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {} 
-   MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM, 
-                                  ModuleAnalysisManager &MAM) 
-       : FAM(&FAM), MAM(&MAM) {} 
-   MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default; 
-   MachineFunctionAnalysisManager & 
-   operator=(MachineFunctionAnalysisManager &&) = default; 
-   
-   /// Get the result of an analysis pass for a Function. 
-   /// 
-   /// Runs the analysis if a cached result is not available. 
-   template <typename PassT> typename PassT::Result &getResult(Function &F) { 
-     return FAM->getResult<PassT>(F); 
-   } 
-   
-   /// Get the cached result of an analysis pass for a Function. 
-   /// 
-   /// This method never runs the analysis. 
-   /// 
-   /// \returns null if there is no cached result. 
-   template <typename PassT> 
-   typename PassT::Result *getCachedResult(Function &F) { 
-     return FAM->getCachedResult<PassT>(F); 
-   } 
-   
-   /// Get the result of an analysis pass for a Module. 
-   /// 
-   /// Runs the analysis if a cached result is not available. 
-   template <typename PassT> typename PassT::Result &getResult(Module &M) { 
-     return MAM->getResult<PassT>(M); 
-   } 
-   
-   /// Get the cached result of an analysis pass for a Module. 
-   /// 
-   /// This method never runs the analysis. 
-   /// 
-   /// \returns null if there is no cached result. 
-   template <typename PassT> typename PassT::Result *getCachedResult(Module &M) { 
-     return MAM->getCachedResult<PassT>(M); 
-   } 
-   
-   /// Get the result of an analysis pass for a MachineFunction. 
-   /// 
-   /// Runs the analysis if a cached result is not available. 
-   using Base::getResult; 
-   
-   /// Get the cached result of an analysis pass for a MachineFunction. 
-   /// 
-   /// This method never runs the analysis. 
-   /// 
-   /// returns null if there is no cached result. 
-   using Base::getCachedResult; 
-   
-   // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed. 
-   FunctionAnalysisManager *FAM; 
-   ModuleAnalysisManager *MAM; 
- }; 
-   
- extern template class PassManager<MachineFunction>; 
-   
- /// MachineFunctionPassManager adds/removes below features to/from the base 
- /// PassManager template instantiation. 
- /// 
- /// - Support passes that implement doInitialization/doFinalization. This is for 
- ///   machine function passes to work on module level constructs. One such pass 
- ///   is AsmPrinter. 
- /// 
- /// - Support machine module pass which runs over the module (for example, 
- ///   MachineOutliner). A machine module pass needs to define the method: 
- /// 
- ///   ```Error run(Module &, MachineFunctionAnalysisManager &)``` 
- /// 
- ///   FIXME: machine module passes still need to define the usual machine 
- ///          function pass interface, namely, 
- ///          `PreservedAnalyses run(MachineFunction &, 
- ///                                 MachineFunctionAnalysisManager &)` 
- ///          But this interface wouldn't be executed. It is just a placeholder 
- ///          to satisfy the pass manager type-erased inteface. This 
- ///          special-casing of machine module pass is due to its limited use 
- ///          cases and the unnecessary complexity it may bring to the machine 
- ///          pass manager. 
- /// 
- /// - The base class `run` method is replaced by an alternative `run` method. 
- ///   See details below. 
- /// 
- /// - Support codegening in the SCC order. Users include interprocedural 
- ///   register allocation (IPRA). 
- class MachineFunctionPassManager 
-     : public PassManager<MachineFunction, MachineFunctionAnalysisManager> { 
-   using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>; 
-   
- public: 
-   MachineFunctionPassManager(bool DebugLogging = false, 
-                              bool RequireCodeGenSCCOrder = false, 
-                              bool VerifyMachineFunction = false) 
-       : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder), 
-         VerifyMachineFunction(VerifyMachineFunction) {} 
-   MachineFunctionPassManager(MachineFunctionPassManager &&) = default; 
-   MachineFunctionPassManager & 
-   operator=(MachineFunctionPassManager &&) = default; 
-   
-   /// Run machine passes for a Module. 
-   /// 
-   /// The intended use is to start the codegen pipeline for a Module. The base 
-   /// class's `run` method is deliberately hidden by this due to the observation 
-   /// that we don't yet have the use cases of compositing two instances of 
-   /// machine pass managers, or compositing machine pass managers with other 
-   /// types of pass managers. 
-   Error run(Module &M, MachineFunctionAnalysisManager &MFAM); 
-   
-   template <typename PassT> void addPass(PassT &&Pass) { 
-     Base::addPass(std::forward<PassT>(Pass)); 
-     PassConceptT *P = Passes.back().get(); 
-     addDoInitialization<PassT>(P); 
-     addDoFinalization<PassT>(P); 
-   
-     // Add machine module pass. 
-     addRunOnModule<PassT>(P); 
-   } 
-   
- private: 
-   template <typename PassT> 
-   using has_init_t = decltype(std::declval<PassT &>().doInitialization( 
-       std::declval<Module &>(), 
-       std::declval<MachineFunctionAnalysisManager &>())); 
-   
-   template <typename PassT> 
-   std::enable_if_t<!is_detected<has_init_t, PassT>::value> 
-   addDoInitialization(PassConceptT *Pass) {} 
-   
-   template <typename PassT> 
-   std::enable_if_t<is_detected<has_init_t, PassT>::value> 
-   addDoInitialization(PassConceptT *Pass) { 
-     using PassModelT = 
-         detail::PassModel<MachineFunction, PassT, PreservedAnalyses, 
-                           MachineFunctionAnalysisManager>; 
-     auto *P = static_cast<PassModelT *>(Pass); 
-     InitializationFuncs.emplace_back( 
-         [=](Module &M, MachineFunctionAnalysisManager &MFAM) { 
-           return P->Pass.doInitialization(M, MFAM); 
-         }); 
-   } 
-   
-   template <typename PassT> 
-   using has_fini_t = decltype(std::declval<PassT &>().doFinalization( 
-       std::declval<Module &>(), 
-       std::declval<MachineFunctionAnalysisManager &>())); 
-   
-   template <typename PassT> 
-   std::enable_if_t<!is_detected<has_fini_t, PassT>::value> 
-   addDoFinalization(PassConceptT *Pass) {} 
-   
-   template <typename PassT> 
-   std::enable_if_t<is_detected<has_fini_t, PassT>::value> 
-   addDoFinalization(PassConceptT *Pass) { 
-     using PassModelT = 
-         detail::PassModel<MachineFunction, PassT, PreservedAnalyses, 
-                           MachineFunctionAnalysisManager>; 
-     auto *P = static_cast<PassModelT *>(Pass); 
-     FinalizationFuncs.emplace_back( 
-         [=](Module &M, MachineFunctionAnalysisManager &MFAM) { 
-           return P->Pass.doFinalization(M, MFAM); 
-         }); 
-   } 
-   
-   template <typename PassT> 
-   using is_machine_module_pass_t = decltype(std::declval<PassT &>().run( 
-       std::declval<Module &>(), 
-       std::declval<MachineFunctionAnalysisManager &>())); 
-   
-   template <typename PassT> 
-   using is_machine_function_pass_t = decltype(std::declval<PassT &>().run( 
-       std::declval<MachineFunction &>(), 
-       std::declval<MachineFunctionAnalysisManager &>())); 
-   
-   template <typename PassT> 
-   std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value> 
-   addRunOnModule(PassConceptT *Pass) {} 
-   
-   template <typename PassT> 
-   std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value> 
-   addRunOnModule(PassConceptT *Pass) { 
-     static_assert(is_detected<is_machine_function_pass_t, PassT>::value, 
-                   "machine module pass needs to define machine function pass " 
-                   "api. sorry."); 
-   
-     using PassModelT = 
-         detail::PassModel<MachineFunction, PassT, PreservedAnalyses, 
-                           MachineFunctionAnalysisManager>; 
-     auto *P = static_cast<PassModelT *>(Pass); 
-     MachineModulePasses.emplace( 
-         Passes.size() - 1, 
-         [=](Module &M, MachineFunctionAnalysisManager &MFAM) { 
-           return P->Pass.run(M, MFAM); 
-         }); 
-   } 
-   
-   using FuncTy = Error(Module &, MachineFunctionAnalysisManager &); 
-   SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs; 
-   SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs; 
-   
-   using PassIndex = decltype(Passes)::size_type; 
-   std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses; 
-   
-   // Run codegen in the SCC order. 
-   bool RequireCodeGenSCCOrder; 
-   
-   bool VerifyMachineFunction; 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H 
-