123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|