[llvm] 4f71329 - Reland "[PassManager] Support MachineFunctionProperties (#83668)" (#87137)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 29 19:12:18 PDT 2024
Author: paperchalice
Date: 2024-03-30T10:12:14+08:00
New Revision: 4f7132952222cd9b2709e98109d6ce0ef333940c
URL: https://github.com/llvm/llvm-project/commit/4f7132952222cd9b2709e98109d6ce0ef333940c
DIFF: https://github.com/llvm/llvm-project/commit/4f7132952222cd9b2709e98109d6ce0ef333940c.diff
LOG: Reland "[PassManager] Support MachineFunctionProperties (#83668)" (#87137)
Fix preprocessor directive.
Added:
llvm/test/tools/llc/new-pm/machine-function-properties.mir
Modified:
llvm/include/llvm/CodeGen/MachinePassManager.h
llvm/include/llvm/Passes/MachinePassRegistry.def
llvm/lib/Passes/PassBuilder.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index 3faffe5c4cab29..085a78f919172d 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -16,8 +16,6 @@
// their respective analysis managers such as ModuleAnalysisManager and
// FunctionAnalysisManager.
//
-// TODO: Add MachineFunctionProperties support.
-//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
@@ -44,23 +42,67 @@ using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
/// automatically mixes in \c PassInfoMixin.
template <typename DerivedT>
struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
- // TODO: Add MachineFunctionProperties support.
+protected:
+ class PropertyChanger {
+ MachineFunction &MF;
+
+ template <typename T>
+ using has_get_required_properties_t =
+ decltype(std::declval<T &>().getRequiredProperties());
+
+ template <typename T>
+ using has_get_set_properties_t =
+ decltype(std::declval<T &>().getSetProperties());
+
+ template <typename T>
+ using has_get_cleared_properties_t =
+ decltype(std::declval<T &>().getClearedProperties());
+
+ public:
+ PropertyChanger(MachineFunction &MF) : MF(MF) {
+#ifndef NDEBUG
+ if constexpr (is_detected<has_get_required_properties_t,
+ DerivedT>::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<has_get_set_properties_t, DerivedT>::value)
+ MF.getProperties().set(DerivedT::getSetProperties());
+ if constexpr (is_detected<has_get_cleared_properties_t, DerivedT>::value)
+ MF.getProperties().reset(DerivedT::getClearedProperties());
+ }
+ };
+
+public:
+ PreservedAnalyses runImpl(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ PropertyChanger PC(MF);
+ return static_cast<DerivedT *>(this)->run(MF, MFAM);
+ }
};
namespace detail {
-struct MachinePassConcept
- : PassConcept<MachineFunction, MachineFunctionAnalysisManager> {
- virtual MachineFunctionProperties getRequiredProperties() const = 0;
- virtual MachineFunctionProperties getSetProperties() const = 0;
- virtual MachineFunctionProperties getClearedProperties() const = 0;
-};
-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)) {}
+template <typename PassT>
+struct MachinePassModel
+ : PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager> {
+ explicit MachinePassModel(PassT &&Pass)
+ : PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>(
+ std::move(Pass)) {}
friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) {
using std::swap;
@@ -75,89 +117,8 @@ template <typename PassT> struct MachinePassModel : MachinePassConcept {
MachinePassModel &operator=(const MachinePassModel &) = delete;
PreservedAnalyses run(MachineFunction &IR,
MachineFunctionAnalysisManager &AM) override {
- return Pass.run(IR, AM);
- }
-
- void printPipeline(
- raw_ostream &OS,
- function_ref<StringRef(StringRef)> MapClassName2PassName) override {
- Pass.printPipeline(OS, MapClassName2PassName);
- }
-
- StringRef name() const override { return PassT::name(); }
-
- 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();
+ return this->Pass.runImpl(IR, AM);
}
- 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>();
- }
-
- 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>();
- }
-
- 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
@@ -251,11 +212,12 @@ class FunctionAnalysisManagerMachineFunctionProxy
class ModuleToMachineFunctionPassAdaptor
: public PassInfoMixin<ModuleToMachineFunctionPassAdaptor> {
- using MachinePassConcept = detail::MachinePassConcept;
-
public:
+ using PassConceptT =
+ detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
+
explicit ModuleToMachineFunctionPassAdaptor(
- std::unique_ptr<MachinePassConcept> Pass)
+ std::unique_ptr<PassConceptT> Pass)
: Pass(std::move(Pass)) {}
/// Runs the function pass across every function in the module.
@@ -266,20 +228,39 @@ class ModuleToMachineFunctionPassAdaptor
static bool isRequired() { return true; }
private:
- std::unique_ptr<MachinePassConcept> Pass;
+ std::unique_ptr<PassConceptT> Pass;
};
template <typename MachineFunctionPassT>
ModuleToMachineFunctionPassAdaptor
createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
- using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
+ using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
+ MachineFunctionAnalysisManager>;
// Do not use make_unique, it causes too many template instantiations,
// causing terrible compile times.
return ModuleToMachineFunctionPassAdaptor(
- std::unique_ptr<detail::MachinePassConcept>(
+ std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT>(
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
}
+template <>
+template <typename PassT>
+std::enable_if_t<!std::is_same<PassT, PassManager<MachineFunction>>::value>
+PassManager<MachineFunction>::addPass(PassT &&Pass) {
+ using PassModelT =
+ detail::PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>;
+ using MachinePassModelT = detail::MachinePassModel<PassT>;
+ // 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<MachinePassInfoMixin<PassT>, PassT>) {
+ Passes.push_back(std::unique_ptr<PassConceptT>(
+ new MachinePassModelT(std::forward<PassT>(Pass))));
+ } else {
+ Passes.push_back(std::unique_ptr<PassConceptT>(
+ new PassModelT(std::forward<PassT>(Pass))));
+ }
+}
+
template <>
PreservedAnalyses
PassManager<MachineFunction>::run(MachineFunction &,
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 016602730e0e97..2f77ae655d9b22 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -127,6 +127,8 @@ 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 f60f4eb3f0ef8c..57975e34d4265b 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -365,6 +365,33 @@ class TriggerVerifierErrorPass
static StringRef name() { return "TriggerVerifierErrorPass"; }
};
+// A pass requires all MachineFunctionProperties.
+// DO NOT USE THIS EXCEPT FOR TESTING!
+class RequireAllMachineFunctionPropertiesPass
+ : public MachinePassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
+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
new file mode 100644
index 00000000000000..a9eb88ec698841
--- /dev/null
+++ b/llvm/test/tools/llc/new-pm/machine-function-properties.mir
@@ -0,0 +1,12 @@
+# 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
+...
More information about the llvm-commits
mailing list