-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CodeGen] Support MachineFunctionProperties in PassConcept #79749
Conversation
@llvm/pr-subscribers-llvm-ir Author: None (paperchalice) ChangesThis patch extends Full diff: https://github.com/llvm/llvm-project/pull/79749.diff 6 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index 662b7e8689717dc..440c3b398beaa63 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -25,15 +25,13 @@
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachinePassManagerInternal.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>;
@@ -43,7 +41,28 @@ extern template class AnalysisManager<MachineFunction>;
/// automatically mixes in \c PassInfoMixin.
template <typename DerivedT>
struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
- // TODO: Add MachineFunctionProperties support.
+ static MachineFunctionProperties getRequiredProperties() {
+ return MachineFunctionProperties();
+ }
+ static MachineFunctionProperties getSetProperties() {
+ return MachineFunctionProperties();
+ }
+ static MachineFunctionProperties getClearedProperties() {
+ return MachineFunctionProperties();
+ }
+};
+
+/// A CRTP mix-in that provides informational APIs needed for MachineFunction
+/// analysis passes. See also \c PassInfoMixin.
+template <typename DerivedT>
+struct MachineFunctionAnalysisInfoMixin
+ : public MachinePassInfoMixin<DerivedT> {
+ static AnalysisKey *ID() {
+ static_assert(
+ std::is_base_of<MachineFunctionAnalysisInfoMixin, DerivedT>::value,
+ "Must pass the derived type as the template argument!");
+ return &DerivedT::Key;
+ }
};
/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
@@ -183,9 +202,7 @@ class MachineFunctionPassManager
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>;
+ using PassModelT = detail::MachinePassModel<PassT>;
auto *P = static_cast<PassModelT *>(Pass);
InitializationFuncs.emplace_back(
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -205,9 +222,7 @@ class MachineFunctionPassManager
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>;
+ using PassModelT = detail::MachinePassModel<PassT>;
auto *P = static_cast<PassModelT *>(Pass);
FinalizationFuncs.emplace_back(
[=](Module &M, MachineFunctionAnalysisManager &MFAM) {
@@ -236,9 +251,7 @@ class MachineFunctionPassManager
"machine module pass needs to define machine function pass "
"api. sorry.");
- using PassModelT =
- detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
- MachineFunctionAnalysisManager>;
+ using PassModelT = detail::MachinePassModel<PassT>;
auto *P = static_cast<PassModelT *>(Pass);
MachineModulePasses.emplace(
Passes.size() - 1,
diff --git a/llvm/include/llvm/CodeGen/MachinePassManagerInternal.h b/llvm/include/llvm/CodeGen/MachinePassManagerInternal.h
new file mode 100644
index 000000000000000..bbac8cb86affe9a
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/MachinePassManagerInternal.h
@@ -0,0 +1,68 @@
+//===- MachinePassManagerInternal.h --------------------------- -*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header provides internal APIs and implementation details used by the
+/// pass management interfaces exposed in MachinePassManager.h. Most of them are
+/// copied from PassManagerInternal.h.
+/// See also PassManagerInternal.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H
+#define LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class MachineFunctionAnalysisManager;
+
+using MachinePassConcept =
+ detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
+
+namespace detail {
+
+/// Template for the abstract base class used to dispatch
+/// polymorphically over pass objects. See also \c PassConcept.
+template <>
+struct PassConcept<MachineFunction, MachineFunctionAnalysisManager>
+ : public PassConceptBase<MachineFunction, MachineFunctionAnalysisManager> {
+ /// MachineFunction Properties.
+ PassConcept(MachineFunctionProperties RequiredProperties,
+ MachineFunctionProperties SetProperties,
+ MachineFunctionProperties ClearedProperties)
+ : RequiredProperties(RequiredProperties), SetProperties(SetProperties),
+ ClearedProperties(ClearedProperties) {}
+
+ MachineFunctionProperties RequiredProperties;
+ MachineFunctionProperties SetProperties;
+ MachineFunctionProperties ClearedProperties;
+};
+
+template <typename IRUnitT, typename PassT, typename PreservedAnalysesT,
+ typename AnalysisManagerT, typename... ExtraArgTs>
+template <typename MachineFunctionT, typename>
+PassModel<IRUnitT, PassT, PreservedAnalysesT, AnalysisManagerT, ExtraArgTs...>::
+ PassModel(PassT Pass, MachineFunctionProperties RequiredProperties,
+ MachineFunctionProperties SetProperties,
+ MachineFunctionProperties ClearedProperties)
+ : PassConcept<MachineFunction, MachineFunctionAnalysisManager>(
+ RequiredProperties, SetProperties, ClearedProperties),
+ Pass(std::move(Pass)) {}
+
+template <typename PassT>
+using MachinePassModel = PassModel<MachineFunction, PassT, PreservedAnalyses,
+ MachineFunctionAnalysisManager>;
+
+} // namespace detail
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINEPASSMANAGERINTERNAL_H
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index df548fbe9e458c4..36904bc2a784067 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -576,8 +576,13 @@ class PassManager : public PassInfoMixin<
ExtraArgTs...>;
// Do not use make_unique or emplace_back, they cause too many template
// instantiations, causing terrible compile times.
- Passes.push_back(std::unique_ptr<PassConceptT>(
- new PassModelT(std::forward<PassT>(Pass))));
+ if constexpr (std::is_same_v<IRUnitT, MachineFunction>)
+ Passes.push_back(std::unique_ptr<PassConceptT>(new PassModelT(
+ std::forward<PassT>(Pass), PassT::getRequiredProperties(),
+ PassT::getSetProperties(), PassT::getClearedProperties())));
+ else
+ Passes.push_back(std::unique_ptr<PassConceptT>(
+ new PassModelT(std::forward<PassT>(Pass))));
}
/// When adding a pass manager pass that has the same type as this pass
diff --git a/llvm/include/llvm/IR/PassManagerInternal.h b/llvm/include/llvm/IR/PassManagerInternal.h
index bcfdcb8206c45ee..8bdbdaa9dfdbd88 100644
--- a/llvm/include/llvm/IR/PassManagerInternal.h
+++ b/llvm/include/llvm/IR/PassManagerInternal.h
@@ -28,6 +28,8 @@ namespace llvm {
template <typename IRUnitT> class AllAnalysesOn;
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
class PreservedAnalyses;
+class MachineFunction;
+class MachineFunctionProperties;
// Implementation details of the pass manager interfaces.
namespace detail {
@@ -35,9 +37,9 @@ namespace detail {
/// Template for the abstract base class used to dispatch
/// polymorphically over pass objects.
template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
-struct PassConcept {
+struct PassConceptBase {
// Boiler plate necessary for the container of derived classes.
- virtual ~PassConcept() = default;
+ virtual ~PassConceptBase() = default;
/// The polymorphic API which runs the pass over a given IR entity.
///
@@ -60,6 +62,10 @@ struct PassConcept {
virtual bool isRequired() const = 0;
};
+template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
+struct PassConcept
+ : public PassConceptBase<IRUnitT, AnalysisManagerT, ExtraArgTs...> {};
+
/// A template wrapper used to implement the polymorphic API.
///
/// Can be instantiated for any object which provides a \c run method accepting
@@ -69,6 +75,13 @@ template <typename IRUnitT, typename PassT, typename PreservedAnalysesT,
typename AnalysisManagerT, typename... ExtraArgTs>
struct PassModel : PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...> {
explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
+
+ template <typename MachineFunctionT = IRUnitT,
+ typename = std::enable_if_t<
+ std::is_same_v<MachineFunctionT, MachineFunction>>>
+ explicit PassModel(PassT Pass, MachineFunctionProperties RequiredProperties,
+ MachineFunctionProperties SetProperties,
+ MachineFunctionProperties ClearedProperties);
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
diff --git a/llvm/unittests/CodeGen/PassManagerTest.cpp b/llvm/unittests/CodeGen/PassManagerTest.cpp
index 4d2c8b7bdb5f455..5e4106f286733bf 100644
--- a/llvm/unittests/CodeGen/PassManagerTest.cpp
+++ b/llvm/unittests/CodeGen/PassManagerTest.cpp
@@ -52,7 +52,7 @@ class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
AnalysisKey TestFunctionAnalysis::Key;
class TestMachineFunctionAnalysis
- : public AnalysisInfoMixin<TestMachineFunctionAnalysis> {
+ : public MachineFunctionAnalysisInfoMixin<TestMachineFunctionAnalysis> {
public:
struct Result {
Result(int Count) : InstructionCount(Count) {}
@@ -70,7 +70,7 @@ class TestMachineFunctionAnalysis
}
private:
- friend AnalysisInfoMixin<TestMachineFunctionAnalysis>;
+ friend MachineFunctionAnalysisInfoMixin<TestMachineFunctionAnalysis>;
static AnalysisKey Key;
};
@@ -79,7 +79,8 @@ AnalysisKey TestMachineFunctionAnalysis::Key;
const std::string DoInitErrMsg = "doInitialization failed";
const std::string DoFinalErrMsg = "doFinalization failed";
-struct TestMachineFunctionPass : public PassInfoMixin<TestMachineFunctionPass> {
+struct TestMachineFunctionPass
+ : public MachinePassInfoMixin<TestMachineFunctionPass> {
TestMachineFunctionPass(int &Count, std::vector<int> &BeforeInitialization,
std::vector<int> &BeforeFinalization,
std::vector<int> &MachineFunctionPassCount)
diff --git a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
index 88522d45bc6bfa9..e0bd93aafddd8bc 100644
--- a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
@@ -174,8 +174,8 @@ struct MockPassInstrumentationCallbacks {
template <typename DerivedT> class MockAnalysisHandleBase {
public:
- class Analysis : public AnalysisInfoMixin<Analysis> {
- friend AnalysisInfoMixin<Analysis>;
+ class Analysis : public MachineFunctionAnalysisInfoMixin<Analysis> {
+ friend MachineFunctionAnalysisInfoMixin<Analysis>;
friend MockAnalysisHandleBase;
static AnalysisKey Key;
|
b4dd3df
to
3403ede
Compare
8dd069b
to
93f68c4
Compare
llvm/include/llvm/IR/PassManager.h
Outdated
@@ -576,8 +576,13 @@ class PassManager : public PassInfoMixin< | |||
ExtraArgTs...>; | |||
// Do not use make_unique or emplace_back, they cause too many template | |||
// instantiations, causing terrible compile times. | |||
Passes.push_back(std::unique_ptr<PassConceptT>( | |||
new PassModelT(std::forward<PassT>(Pass)))); | |||
if constexpr (std::is_same_v<IRUnitT, MachineFunction>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Braces
93f68c4
to
bb6d4da
Compare
Address comments. |
} | ||
static MachineFunctionProperties getClearedProperties() { | ||
return MachineFunctionProperties(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge them into PassInfoMixin
seems better but impossible (at least in C++17).
bb6d4da
to
f3ccf25
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why PassManager and its surrounding infra is even in the IR library instead of Passes. we should try moving it (not necessarily right now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for the delayed review
this is kinda hairy just to make verification work (verification is obviously important, but it's still just one thing). I'm trying to think if there's a cleaner way that doesn't involve touching all the core classes
@@ -170,6 +192,17 @@ class MachineFunctionPassManager | |||
addRunOnModule<PassT>(P); | |||
} | |||
|
|||
// Avoid diamond problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you clarify that we'd be getting PassInfoMixin
twice if we directly inherited from it (PassManager
also inheriting from it)
/// A CRTP mix-in that provides informational APIs needed for MachineFunction | ||
/// analysis passes. See also \c PassInfoMixin. | ||
template <typename DerivedT> | ||
struct MachineFunctionAnalysisInfoMixin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super familiar with codegen verification. I vaguely understand that there are different parts of the pipeline that require different types of verification. but do machine function analyses also need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not, but some MachineFunction passes like StackMapLivenessAnalysis analyses and modifies machine function.
actually I'm not understanding why this is necessary. it looks like |
The relevant code is in |
oh I see, there are two parts to machine verification. one is checking that the MF has certain properties a pass requires before running the pass. two is checking that each property a MF claims it has actually holds in the instructions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will try to wrap my head around the new inheritance structure tomorrow
llvm/include/llvm/IR/PassManager.h
Outdated
@@ -1292,9 +1298,37 @@ struct RequireAnalysisPass | |||
OS << "require<" << PassName << '>'; | |||
} | |||
static bool isRequired() { return true; } | |||
|
|||
// MachineFunctionPass interface, define Define these separately to prevent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra "Define", ditto below
6cfcbcf
to
9ab7446
Compare
9ab7446
to
18bf7d0
Compare
return MachineFunctionPropertiesT(); | ||
} | ||
|
||
template <typename MachineFunctionPropertiesT = MachineFunctionProperties> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, are these templates just to work around the IR -> CodeGen depenency? that's not great
let me try some things locally, like making a completely separate MachineFunctionPassManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I see that PassModel
in PassManagerInternal.h also does this...
I'm still looking at this but I think 100fc8c goes along a better path of separating out module/function passes, matching the rest of the new pass manager infra. Let me spend some more time on it. This might take a couple of days. In the meantime I think it'd be valuable to figure out a couple of things:
|
BPF might be a good choice, it is simple enough, not an experimental target, and has initial GlobalISel support.
In legacy pass manager, all
The original |
sounds good
for for SampleProfile, I see X86InsertPrefetch, is that what you're referring to? for that, we can lazily initialize the profile since it doesn't modify the IR. the case we'd need to worry about is when initialization/finalization modifies the IR because if it's touching something outside of
I'm not understanding your point, can you clarify why it's too complicated to be a new pass manager pass? |
Just an obvious fact. We need to factor out the polymorphic part of |
Replaced by #81068. |
This patch extends
PassConcept
to supportMachineFunctionProperties
,MachineFunctionProperties
verification work may be completed within the next few days, in new codegen instrumentations rather than pass manager.