From 8e9c6bfb5075a498344521d5911b6bc9ab9c901f Mon Sep 17 00:00:00 2001 From: paperchalice Date: Sat, 22 Jun 2024 17:34:03 +0800 Subject: [CodeGen][NewPM] Extract MachineFunctionProperties modification part to an RAII class (#94854) Modify MachineFunctionProperties in PassModel makes `PassT P; P.run(...);` not work properly. This is a necessary compromise. --- llvm/include/llvm/CodeGen/MachinePassManager.h | 85 +++++++++++--------------- llvm/include/llvm/IR/PassManager.h | 35 ++++++----- llvm/lib/CodeGen/RegAllocFast.cpp | 1 + llvm/lib/Passes/PassBuilder.cpp | 3 +- 4 files changed, 57 insertions(+), 67 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h index 7d15664..8c4a704 100644 --- a/llvm/include/llvm/CodeGen/MachinePassManager.h +++ b/llvm/include/llvm/CodeGen/MachinePassManager.h @@ -36,35 +36,20 @@ class MachineFunction; extern template class AnalysisManager; using MachineFunctionAnalysisManager = AnalysisManager; -namespace detail { - -template -struct MachinePassModel - : PassModel { - explicit MachinePassModel(PassT &&Pass) - : PassModel( - std::move(Pass)) {} - - friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) { - using std::swap; - swap(LHS.Pass, RHS.Pass); - } - - MachinePassModel &operator=(MachinePassModel RHS) { - swap(*this, RHS); - return *this; - } - - MachinePassModel &operator=(const MachinePassModel &) = delete; - PreservedAnalyses run(MachineFunction &IR, - MachineFunctionAnalysisManager &AM) override { +/// An RAII based helper class to modify MachineFunctionProperties when running +/// pass. Define a MFPropsModifier in PassT::run to set +/// MachineFunctionProperties properly. +template class MFPropsModifier { +public: + MFPropsModifier(PassT &P_, MachineFunction &MF_) : P(P_), MF(MF_) { + auto &MFProps = MF.getProperties(); #ifndef NDEBUG - if constexpr (is_detected::value) { - auto &MFProps = IR.getProperties(); - auto RequiredProperties = this->Pass.getRequiredProperties(); + if constexpr (has_get_required_properties_v) { + auto &MFProps = MF.getProperties(); + auto RequiredProperties = P.getRequiredProperties(); if (!MFProps.verifyRequiredProperties(RequiredProperties)) { errs() << "MachineFunctionProperties required by " << PassT::name() - << " pass are not met by function " << IR.getName() << ".\n" + << " pass are not met by function " << MF.getName() << ".\n" << "Required properties: "; RequiredProperties.print(errs()); errs() << "\nCurrent properties: "; @@ -73,18 +58,22 @@ struct MachinePassModel report_fatal_error("MachineFunctionProperties check failed"); } } -#endif - - auto PA = this->Pass.run(IR, AM); +#endif // NDEBUG + if constexpr (has_get_cleared_properties_v) + MFProps.reset(P.getClearedProperties()); + } - if constexpr (is_detected::value) - IR.getProperties().set(this->Pass.getSetProperties()); - if constexpr (is_detected::value) - IR.getProperties().reset(this->Pass.getClearedProperties()); - return PA; + ~MFPropsModifier() { + if constexpr (has_get_set_properties_v) { + auto &MFProps = MF.getProperties(); + MFProps.set(P.getSetProperties()); + } } private: + PassT &P; + MachineFunction &MF; + template using has_get_required_properties_t = decltype(std::declval().getRequiredProperties()); @@ -96,8 +85,19 @@ private: template using has_get_cleared_properties_t = decltype(std::declval().getClearedProperties()); + + template + static constexpr bool has_get_required_properties_v = + is_detected::value; + + template + static constexpr bool has_get_set_properties_v = + is_detected::value; + + template + static constexpr bool has_get_cleared_properties_v = + is_detected::value; }; -} // namespace detail using MachineFunctionAnalysisManagerModuleProxy = InnerAnalysisManagerProxy; @@ -220,21 +220,6 @@ createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) { } template <> -template -void PassManager::addPass(PassT &&Pass) { - using MachinePassModelT = detail::MachinePassModel; - // Do not use make_unique or emplace_back, they cause too many template - // instantiations, causing terrible compile times. - if constexpr (std::is_same_v>) { - for (auto &P : Pass.Passes) - Passes.push_back(std::move(P)); - } else { - Passes.push_back(std::unique_ptr( - new MachinePassModelT(std::forward(Pass)))); - } -} - -template <> PreservedAnalyses PassManager::run(MachineFunction &, AnalysisManager &); diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h index 97405ec..23a05c0 100644 --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -189,24 +189,27 @@ public: PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs); - // FIXME: Revert to enable_if style when gcc >= 11.1 - template LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass) { + template + LLVM_ATTRIBUTE_MINSIZE std::enable_if_t> + addPass(PassT &&Pass) { using PassModelT = detail::PassModel; - if constexpr (!std::is_same_v) { - // Do not use make_unique or emplace_back, they cause too many template - // instantiations, causing terrible compile times. - Passes.push_back(std::unique_ptr( - new PassModelT(std::forward(Pass)))); - } else { - /// When adding a pass manager pass that has the same type as this pass - /// manager, simply move the passes over. This is because we don't have - /// use cases rely on executing nested pass managers. Doing this could - /// reduce implementation complexity and avoid potential invalidation - /// issues that may happen with nested pass managers of the same type. - for (auto &P : Pass.Passes) - Passes.push_back(std::move(P)); - } + // Do not use make_unique or emplace_back, they cause too many template + // instantiations, causing terrible compile times. + Passes.push_back(std::unique_ptr( + new PassModelT(std::forward(Pass)))); + } + + /// When adding a pass manager pass that has the same type as this pass + /// manager, simply move the passes over. This is because we don't have + /// use cases rely on executing nested pass managers. Doing this could + /// reduce implementation complexity and avoid potential invalidation + /// issues that may happen with nested pass managers of the same type. + template + LLVM_ATTRIBUTE_MINSIZE std::enable_if_t> + addPass(PassT &&Pass) { + for (auto &P : Pass.Passes) + Passes.push_back(std::move(P)); } /// Returns if the pass manager contains any passes. diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index f68f67f..b4660d4 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -1810,6 +1810,7 @@ bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) { PreservedAnalyses RegAllocFastPass::run(MachineFunction &MF, MachineFunctionAnalysisManager &) { + MFPropsModifier _(*this, MF); RegAllocFastImpl Impl(Opts.Filter, Opts.ClearVRegs); bool Changed = Impl.runOnMachineFunction(MF); if (!Changed) diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 3aa0a60..f819345 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -387,7 +387,8 @@ public: class RequireAllMachineFunctionPropertiesPass : public PassInfoMixin { public: - PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) { + PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) { + MFPropsModifier _(*this, MF); return PreservedAnalyses::none(); } -- cgit v1.1