[llvm] [NewPM/CodeGen] Rewrite pass manager nesting (PR #81068)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 21:46:59 PST 2024
================
@@ -46,217 +47,247 @@ struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
// TODO: Add MachineFunctionProperties support.
};
-/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
-class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> {
-public:
- using Base = AnalysisManager<MachineFunction>;
+namespace detail {
+struct MachinePassConcept
+ : PassConcept<MachineFunction, MachineFunctionAnalysisManager> {
+ virtual MachineFunctionProperties getRequiredProperties() const = 0;
+ virtual MachineFunctionProperties getSetProperties() const = 0;
+ virtual MachineFunctionProperties getClearedProperties() const = 0;
+};
- MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {}
- MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM,
- ModuleAnalysisManager &MAM)
- : FAM(&FAM), MAM(&MAM) {}
- MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default;
- MachineFunctionAnalysisManager &
- operator=(MachineFunctionAnalysisManager &&) = default;
+template <typename PassT> struct MachinePassModel : MachinePassConcept {
+ explicit MachinePassModel(PassT Pass) : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ MachinePassModel(const MachinePassModel &Arg) : Pass(Arg.Pass) {}
+ MachinePassModel(MachinePassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
- /// 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);
+ friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
}
- /// 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);
+ MachinePassModel &operator=(MachinePassModel RHS) {
+ swap(*this, RHS);
+ return *this;
}
- /// 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);
+ PreservedAnalyses run(MachineFunction &IR,
+ MachineFunctionAnalysisManager &AM) override {
+ return Pass.run(IR, AM);
}
- /// 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);
+ void printPipeline(
+ raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName) override {
+ Pass.printPipeline(OS, MapClassName2PassName);
}
- /// Get the result of an analysis pass for a MachineFunction.
- ///
- /// Runs the analysis if a cached result is not available.
- using Base::getResult;
+ StringRef name() const override { return PassT::name(); }
- /// 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;
-};
+ template <typename T>
+ using has_required_t = decltype(std::declval<T &>().isRequired());
+ template <typename T>
+ static std::enable_if_t<is_detected<has_required_t, T>::value, bool>
+ passIsRequiredImpl() {
+ return T::isRequired();
+ }
+ template <typename T>
+ static std::enable_if_t<!is_detected<has_required_t, T>::value, bool>
+ passIsRequiredImpl() {
+ return false;
+ }
+ bool isRequired() const override { return passIsRequiredImpl<PassT>(); }
+
+ template <typename T>
+ using has_get_required_properties_t =
+ decltype(std::declval<T &>().getRequiredProperties());
+ template <typename T>
+ static std::enable_if_t<is_detected<has_get_required_properties_t, T>::value,
+ MachineFunctionProperties>
+ getRequiredPropertiesImpl() {
+ return PassT::getRequiredProperties();
+ }
+ template <typename T>
+ static std::enable_if_t<!is_detected<has_get_required_properties_t, T>::value,
+ MachineFunctionProperties>
+ getRequiredPropertiesImpl() {
+ return MachineFunctionProperties();
+ }
+ MachineFunctionProperties getRequiredProperties() const override {
+ return getRequiredPropertiesImpl<PassT>();
+ }
-extern template class PassManager<MachineFunction>;
+ template <typename T>
+ using has_get_set_properties_t =
+ decltype(std::declval<T &>().getSetProperties());
+ template <typename T>
+ static std::enable_if_t<is_detected<has_get_set_properties_t, T>::value,
+ MachineFunctionProperties>
+ getSetPropertiesImpl() {
+ return PassT::getSetProperties();
+ }
+ template <typename T>
+ static std::enable_if_t<!is_detected<has_get_set_properties_t, T>::value,
+ MachineFunctionProperties>
+ getSetPropertiesImpl() {
+ return MachineFunctionProperties();
+ }
+ MachineFunctionProperties getSetProperties() const override {
+ return getSetPropertiesImpl<PassT>();
+ }
-/// 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>;
+ template <typename T>
+ using has_get_cleared_properties_t =
+ decltype(std::declval<T &>().getClearedProperties());
+ template <typename T>
+ static std::enable_if_t<is_detected<has_get_cleared_properties_t, T>::value,
+ MachineFunctionProperties>
+ getClearedPropertiesImpl() {
+ return PassT::getClearedProperties();
+ }
+ template <typename T>
+ static std::enable_if_t<!is_detected<has_get_cleared_properties_t, T>::value,
+ MachineFunctionProperties>
+ getClearedPropertiesImpl() {
+ return MachineFunctionProperties();
+ }
+ MachineFunctionProperties getClearedProperties() const override {
+ return getClearedPropertiesImpl<PassT>();
+ }
+ PassT Pass;
+};
+} // namespace detail
+
+using MachineFunctionAnalysisManagerModuleProxy =
+ InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
+
+template <>
+bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
+ Module &M, const PreservedAnalyses &PA,
+ ModuleAnalysisManager::Invalidator &Inv);
+extern template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
+ Module>;
+
+extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
----------------
aeubanks wrote:
The parts about accessing outer analyses in https://llvm.org/docs/NewPassManager.html#using-analyses is still relevant for MachineFunction passes and Module analyses, so we should have these.
Agreed that MachineFunction passes should be able to query for Function analyses though.
https://github.com/llvm/llvm-project/pull/81068
More information about the llvm-commits
mailing list