diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h index 965e8282ccaba..3faffe5c4cab2 100644 --- a/llvm/include/llvm/CodeGen/MachinePassManager.h +++ b/llvm/include/llvm/CodeGen/MachinePassManager.h @@ -16,6 +16,8 @@ // their respective analysis managers such as ModuleAnalysisManager and // FunctionAnalysisManager. // +// TODO: Add MachineFunctionProperties support. +// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H @@ -42,67 +44,23 @@ using MachineFunctionAnalysisManager = AnalysisManager; /// automatically mixes in \c PassInfoMixin. template struct MachinePassInfoMixin : public PassInfoMixin { -protected: - class PropertyChanger { - MachineFunction &MF; - - template - using has_get_required_properties_t = - decltype(std::declval().getRequiredProperties()); - - template - using has_get_set_properties_t = - decltype(std::declval().getSetProperties()); - - template - using has_get_cleared_properties_t = - decltype(std::declval().getClearedProperties()); - - public: - PropertyChanger(MachineFunction &MF) : MF(MF) { -#ifndef NDEBUG - if constexpr (is_detected::value) { - auto &MFProps = MF.getProperties(); - auto RequiredProperties = DerivedT::getRequiredProperties(); - if (!MFProps.verifyRequiredProperties(RequiredProperties)) { - errs() << "MachineFunctionProperties required by " << DerivedT::name() - << " pass are not met by function " << MF.getName() << ".\n" - << "Required properties: "; - RequiredProperties.print(errs()); - errs() << "\nCurrent properties: "; - MFProps.print(errs()); - errs() << '\n'; - report_fatal_error("MachineFunctionProperties check failed"); - } -#endif - } - } - - ~PropertyChanger() { - if constexpr (is_detected::value) - MF.getProperties().set(DerivedT::getSetProperties()); - if constexpr (is_detected::value) - MF.getProperties().reset(DerivedT::getClearedProperties()); - } - }; - -public: - PreservedAnalyses runImpl(MachineFunction &MF, - MachineFunctionAnalysisManager &MFAM) { - PropertyChanger PC(MF); - return static_cast(this)->run(MF, MFAM); - } + // TODO: Add MachineFunctionProperties support. }; namespace detail { +struct MachinePassConcept + : PassConcept { + virtual MachineFunctionProperties getRequiredProperties() const = 0; + virtual MachineFunctionProperties getSetProperties() const = 0; + virtual MachineFunctionProperties getClearedProperties() const = 0; +}; -template -struct MachinePassModel - : PassModel { - explicit MachinePassModel(PassT &&Pass) - : PassModel( - std::move(Pass)) {} +template 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)) {} friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) { using std::swap; @@ -117,8 +75,89 @@ struct MachinePassModel MachinePassModel &operator=(const MachinePassModel &) = delete; PreservedAnalyses run(MachineFunction &IR, MachineFunctionAnalysisManager &AM) override { - return this->Pass.runImpl(IR, AM); + return Pass.run(IR, AM); + } + + void printPipeline( + raw_ostream &OS, + function_ref MapClassName2PassName) override { + Pass.printPipeline(OS, MapClassName2PassName); + } + + StringRef name() const override { return PassT::name(); } + + template + using has_required_t = decltype(std::declval().isRequired()); + template + static std::enable_if_t::value, bool> + passIsRequiredImpl() { + return T::isRequired(); } + template + static std::enable_if_t::value, bool> + passIsRequiredImpl() { + return false; + } + bool isRequired() const override { return passIsRequiredImpl(); } + + template + using has_get_required_properties_t = + decltype(std::declval().getRequiredProperties()); + template + static std::enable_if_t::value, + MachineFunctionProperties> + getRequiredPropertiesImpl() { + return PassT::getRequiredProperties(); + } + template + static std::enable_if_t::value, + MachineFunctionProperties> + getRequiredPropertiesImpl() { + return MachineFunctionProperties(); + } + MachineFunctionProperties getRequiredProperties() const override { + return getRequiredPropertiesImpl(); + } + + template + using has_get_set_properties_t = + decltype(std::declval().getSetProperties()); + template + static std::enable_if_t::value, + MachineFunctionProperties> + getSetPropertiesImpl() { + return PassT::getSetProperties(); + } + template + static std::enable_if_t::value, + MachineFunctionProperties> + getSetPropertiesImpl() { + return MachineFunctionProperties(); + } + MachineFunctionProperties getSetProperties() const override { + return getSetPropertiesImpl(); + } + + template + using has_get_cleared_properties_t = + decltype(std::declval().getClearedProperties()); + template + static std::enable_if_t::value, + MachineFunctionProperties> + getClearedPropertiesImpl() { + return PassT::getClearedProperties(); + } + template + static std::enable_if_t::value, + MachineFunctionProperties> + getClearedPropertiesImpl() { + return MachineFunctionProperties(); + } + MachineFunctionProperties getClearedProperties() const override { + return getClearedPropertiesImpl(); + } + + PassT Pass; }; } // namespace detail @@ -212,12 +251,11 @@ class FunctionAnalysisManagerMachineFunctionProxy class ModuleToMachineFunctionPassAdaptor : public PassInfoMixin { -public: - using PassConceptT = - detail::PassConcept; + using MachinePassConcept = detail::MachinePassConcept; +public: explicit ModuleToMachineFunctionPassAdaptor( - std::unique_ptr Pass) + std::unique_ptr Pass) : Pass(std::move(Pass)) {} /// Runs the function pass across every function in the module. @@ -228,39 +266,20 @@ class ModuleToMachineFunctionPassAdaptor static bool isRequired() { return true; } private: - std::unique_ptr Pass; + std::unique_ptr Pass; }; template ModuleToMachineFunctionPassAdaptor createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) { - using PassModelT = detail::PassModel; + using PassModelT = detail::MachinePassModel; // Do not use make_unique, it causes too many template instantiations, // causing terrible compile times. return ModuleToMachineFunctionPassAdaptor( - std::unique_ptr( + std::unique_ptr( new PassModelT(std::forward(Pass)))); } -template <> -template -std::enable_if_t>::value> -PassManager::addPass(PassT &&Pass) { - using PassModelT = - detail::PassModel; - 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_base_of_v, PassT>) { - Passes.push_back(std::unique_ptr( - new MachinePassModelT(std::forward(Pass)))); - } else { - Passes.push_back(std::unique_ptr( - new PassModelT(std::forward(Pass)))); - } -} - template <> PreservedAnalyses PassManager::run(MachineFunction &, diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def index 2f77ae655d9b2..016602730e0e9 100644 --- a/llvm/include/llvm/Passes/MachinePassRegistry.def +++ b/llvm/include/llvm/Passes/MachinePassRegistry.def @@ -127,8 +127,6 @@ MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass()) // MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass()) MACHINE_FUNCTION_PASS("no-op-machine-function", NoOpMachineFunctionPass()) MACHINE_FUNCTION_PASS("print", PrintMIRPass()) -MACHINE_FUNCTION_PASS("require-all-machine-function-properties", - RequireAllMachineFunctionPropertiesPass()) #undef MACHINE_FUNCTION_PASS // After a pass is converted to new pass manager, its entry should be moved from diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 57975e34d4265..f60f4eb3f0ef8 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -365,33 +365,6 @@ class TriggerVerifierErrorPass static StringRef name() { return "TriggerVerifierErrorPass"; } }; -// A pass requires all MachineFunctionProperties. -// DO NOT USE THIS EXCEPT FOR TESTING! -class RequireAllMachineFunctionPropertiesPass - : public MachinePassInfoMixin { -public: - PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) { - return PreservedAnalyses::none(); - } - - static MachineFunctionProperties getRequiredProperties() { - MachineFunctionProperties MFProps; - MFProps.set(MachineFunctionProperties::Property::FailedISel); - MFProps.set(MachineFunctionProperties::Property::FailsVerification); - MFProps.set(MachineFunctionProperties::Property::IsSSA); - MFProps.set(MachineFunctionProperties::Property::Legalized); - MFProps.set(MachineFunctionProperties::Property::NoPHIs); - MFProps.set(MachineFunctionProperties::Property::NoVRegs); - MFProps.set(MachineFunctionProperties::Property::RegBankSelected); - MFProps.set(MachineFunctionProperties::Property::Selected); - MFProps.set(MachineFunctionProperties::Property::TiedOpsRewritten); - MFProps.set(MachineFunctionProperties::Property::TracksDebugUserValues); - MFProps.set(MachineFunctionProperties::Property::TracksLiveness); - return MFProps; - } - static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; } -}; - } // namespace PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO, diff --git a/llvm/test/tools/llc/new-pm/machine-function-properties.mir b/llvm/test/tools/llc/new-pm/machine-function-properties.mir deleted file mode 100644 index a9eb88ec69884..0000000000000 --- a/llvm/test/tools/llc/new-pm/machine-function-properties.mir +++ /dev/null @@ -1,12 +0,0 @@ -# REQUIRES: asserts -# RUN: not --crash llc -mtriple=x86_64-pc-linux-gnu -passes=require-all-machine-function-properties -filetype=null %s 2>&1 | FileCheck %s - -# CHECK: MachineFunctionProperties required by RequireAllMachineFunctionPropertiesPass pass are not met by function f. - ---- -name: f -selected: false -body: | - bb.0: - RET 0 -...