Skip to content

Commit 8a20b1d

Browse files
committed
Another approach
1 parent b345adc commit 8a20b1d

File tree

4 files changed

+88
-131
lines changed

4 files changed

+88
-131
lines changed

llvm/include/llvm/CodeGen/MachinePassManager.h

Lines changed: 84 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
// their respective analysis managers such as ModuleAnalysisManager and
1717
// FunctionAnalysisManager.
1818
//
19-
// TODO: Add MachineFunctionProperties support.
20-
//
2119
//===----------------------------------------------------------------------===//
2220

2321
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
@@ -44,23 +42,67 @@ using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
4442
/// automatically mixes in \c PassInfoMixin.
4543
template <typename DerivedT>
4644
struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
47-
// TODO: Add MachineFunctionProperties support.
45+
protected:
46+
class PropertyChanger {
47+
MachineFunction &MF;
48+
49+
template <typename T>
50+
using has_get_required_properties_t =
51+
decltype(std::declval<T &>().getRequiredProperties());
52+
53+
template <typename T>
54+
using has_get_set_properties_t =
55+
decltype(std::declval<T &>().getSetProperties());
56+
57+
template <typename T>
58+
using has_get_cleared_properties_t =
59+
decltype(std::declval<T &>().getClearedProperties());
60+
61+
public:
62+
PropertyChanger(MachineFunction &MF) : MF(MF) {
63+
#ifndef NDEBUG
64+
if constexpr (is_detected<has_get_required_properties_t,
65+
DerivedT>::value) {
66+
auto &MFProps = MF.getProperties();
67+
auto RequiredProperties = DerivedT::getRequiredProperties();
68+
if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
69+
errs() << "MachineFunctionProperties required by " << DerivedT::name()
70+
<< " pass are not met by function " << MF.getName() << ".\n"
71+
<< "Required properties: ";
72+
RequiredProperties.print(errs());
73+
errs() << "\nCurrent properties: ";
74+
MFProps.print(errs());
75+
errs() << '\n';
76+
report_fatal_error("MachineFunctionProperties check failed");
77+
}
78+
#endif
79+
}
80+
}
81+
82+
~PropertyChanger() {
83+
if constexpr (is_detected<has_get_set_properties_t, DerivedT>::value)
84+
MF.getProperties().set(DerivedT::getSetProperties());
85+
if constexpr (is_detected<has_get_cleared_properties_t, DerivedT>::value)
86+
MF.getProperties().reset(DerivedT::getClearedProperties());
87+
}
88+
};
89+
90+
public:
91+
PreservedAnalyses runImpl(MachineFunction &MF,
92+
MachineFunctionAnalysisManager &MFAM) {
93+
PropertyChanger PC(MF);
94+
return static_cast<DerivedT *>(this)->run(MF, MFAM);
95+
}
4896
};
4997

5098
namespace detail {
51-
struct MachinePassConcept
52-
: PassConcept<MachineFunction, MachineFunctionAnalysisManager> {
53-
virtual MachineFunctionProperties getRequiredProperties() const = 0;
54-
virtual MachineFunctionProperties getSetProperties() const = 0;
55-
virtual MachineFunctionProperties getClearedProperties() const = 0;
56-
};
5799

58-
template <typename PassT> struct MachinePassModel : MachinePassConcept {
59-
explicit MachinePassModel(PassT &&Pass) : Pass(std::move(Pass)) {}
60-
// We have to explicitly define all the special member functions because MSVC
61-
// refuses to generate them.
62-
MachinePassModel(const MachinePassModel &Arg) : Pass(Arg.Pass) {}
63-
MachinePassModel(MachinePassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
100+
template <typename PassT>
101+
struct MachinePassModel
102+
: PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager> {
103+
explicit MachinePassModel(PassT &&Pass)
104+
: PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>(
105+
std::move(Pass)) {}
64106

65107
friend void swap(MachinePassModel &LHS, MachinePassModel &RHS) {
66108
using std::swap;
@@ -75,89 +117,8 @@ template <typename PassT> struct MachinePassModel : MachinePassConcept {
75117
MachinePassModel &operator=(const MachinePassModel &) = delete;
76118
PreservedAnalyses run(MachineFunction &IR,
77119
MachineFunctionAnalysisManager &AM) override {
78-
return Pass.run(IR, AM);
79-
}
80-
81-
void printPipeline(
82-
raw_ostream &OS,
83-
function_ref<StringRef(StringRef)> MapClassName2PassName) override {
84-
Pass.printPipeline(OS, MapClassName2PassName);
85-
}
86-
87-
StringRef name() const override { return PassT::name(); }
88-
89-
template <typename T>
90-
using has_required_t = decltype(std::declval<T &>().isRequired());
91-
template <typename T>
92-
static std::enable_if_t<is_detected<has_required_t, T>::value, bool>
93-
passIsRequiredImpl() {
94-
return T::isRequired();
120+
return this->Pass.runImpl(IR, AM);
95121
}
96-
template <typename T>
97-
static std::enable_if_t<!is_detected<has_required_t, T>::value, bool>
98-
passIsRequiredImpl() {
99-
return false;
100-
}
101-
bool isRequired() const override { return passIsRequiredImpl<PassT>(); }
102-
103-
template <typename T>
104-
using has_get_required_properties_t =
105-
decltype(std::declval<T &>().getRequiredProperties());
106-
template <typename T>
107-
static std::enable_if_t<is_detected<has_get_required_properties_t, T>::value,
108-
MachineFunctionProperties>
109-
getRequiredPropertiesImpl() {
110-
return PassT::getRequiredProperties();
111-
}
112-
template <typename T>
113-
static std::enable_if_t<!is_detected<has_get_required_properties_t, T>::value,
114-
MachineFunctionProperties>
115-
getRequiredPropertiesImpl() {
116-
return MachineFunctionProperties();
117-
}
118-
MachineFunctionProperties getRequiredProperties() const override {
119-
return getRequiredPropertiesImpl<PassT>();
120-
}
121-
122-
template <typename T>
123-
using has_get_set_properties_t =
124-
decltype(std::declval<T &>().getSetProperties());
125-
template <typename T>
126-
static std::enable_if_t<is_detected<has_get_set_properties_t, T>::value,
127-
MachineFunctionProperties>
128-
getSetPropertiesImpl() {
129-
return PassT::getSetProperties();
130-
}
131-
template <typename T>
132-
static std::enable_if_t<!is_detected<has_get_set_properties_t, T>::value,
133-
MachineFunctionProperties>
134-
getSetPropertiesImpl() {
135-
return MachineFunctionProperties();
136-
}
137-
MachineFunctionProperties getSetProperties() const override {
138-
return getSetPropertiesImpl<PassT>();
139-
}
140-
141-
template <typename T>
142-
using has_get_cleared_properties_t =
143-
decltype(std::declval<T &>().getClearedProperties());
144-
template <typename T>
145-
static std::enable_if_t<is_detected<has_get_cleared_properties_t, T>::value,
146-
MachineFunctionProperties>
147-
getClearedPropertiesImpl() {
148-
return PassT::getClearedProperties();
149-
}
150-
template <typename T>
151-
static std::enable_if_t<!is_detected<has_get_cleared_properties_t, T>::value,
152-
MachineFunctionProperties>
153-
getClearedPropertiesImpl() {
154-
return MachineFunctionProperties();
155-
}
156-
MachineFunctionProperties getClearedProperties() const override {
157-
return getClearedPropertiesImpl<PassT>();
158-
}
159-
160-
PassT Pass;
161122
};
162123
} // namespace detail
163124

@@ -251,11 +212,12 @@ class FunctionAnalysisManagerMachineFunctionProxy
251212

252213
class ModuleToMachineFunctionPassAdaptor
253214
: public PassInfoMixin<ModuleToMachineFunctionPassAdaptor> {
254-
using MachinePassConcept = detail::MachinePassConcept;
255-
256215
public:
216+
using PassConceptT =
217+
detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
218+
257219
explicit ModuleToMachineFunctionPassAdaptor(
258-
std::unique_ptr<MachinePassConcept> Pass)
220+
std::unique_ptr<PassConceptT> Pass)
259221
: Pass(std::move(Pass)) {}
260222

261223
/// Runs the function pass across every function in the module.
@@ -266,20 +228,39 @@ class ModuleToMachineFunctionPassAdaptor
266228
static bool isRequired() { return true; }
267229

268230
private:
269-
std::unique_ptr<MachinePassConcept> Pass;
231+
std::unique_ptr<PassConceptT> Pass;
270232
};
271233

272234
template <typename MachineFunctionPassT>
273235
ModuleToMachineFunctionPassAdaptor
274236
createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
275-
using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
237+
using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
238+
MachineFunctionAnalysisManager>;
276239
// Do not use make_unique, it causes too many template instantiations,
277240
// causing terrible compile times.
278241
return ModuleToMachineFunctionPassAdaptor(
279-
std::unique_ptr<detail::MachinePassConcept>(
242+
std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT>(
280243
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
281244
}
282245

246+
template <>
247+
template <typename PassT>
248+
std::enable_if_t<!std::is_same<PassT, PassManager<MachineFunction>>::value>
249+
PassManager<MachineFunction>::addPass(PassT &&Pass) {
250+
using PassModelT =
251+
detail::PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>;
252+
using MachinePassModelT = detail::MachinePassModel<PassT>;
253+
// Do not use make_unique or emplace_back, they cause too many template
254+
// instantiations, causing terrible compile times.
255+
if constexpr (std::is_base_of_v<MachinePassInfoMixin<PassT>, PassT>) {
256+
Passes.push_back(std::unique_ptr<PassConceptT>(
257+
new MachinePassModelT(std::forward<PassT>(Pass))));
258+
} else {
259+
Passes.push_back(std::unique_ptr<PassConceptT>(
260+
new PassModelT(std::forward<PassT>(Pass))));
261+
}
262+
}
263+
283264
template <>
284265
PreservedAnalyses
285266
PassManager<MachineFunction>::run(MachineFunction &,

llvm/include/llvm/IR/PassManager.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
6464

6565
namespace llvm {
6666

67-
class MachineFunction;
68-
6967
// RemoveDIs: Provide facilities for converting debug-info from one form to
7068
// another, which are no-ops for everything but modules.
7169
template <class IRUnitT> inline bool shouldConvertDbgInfo(IRUnitT &IR) {
@@ -273,10 +271,8 @@ class PassManager : public PassInfoMixin<
273271
LLVM_ATTRIBUTE_MINSIZE
274272
std::enable_if_t<!std::is_same<PassT, PassManager>::value>
275273
addPass(PassT &&Pass) {
276-
using PassModelT = std::conditional_t<
277-
std::is_same_v<IRUnitT, MachineFunction>,
278-
detail::MachinePassModel<PassT>,
279-
detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>>;
274+
using PassModelT =
275+
detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>;
280276
// Do not use make_unique or emplace_back, they cause too many template
281277
// instantiations, causing terrible compile times.
282278
Passes.push_back(std::unique_ptr<PassConceptT>(
@@ -302,9 +298,8 @@ class PassManager : public PassInfoMixin<
302298
static bool isRequired() { return true; }
303299

304300
protected:
305-
using PassConceptT = std::conditional_t<
306-
std::is_same_v<IRUnitT, MachineFunction>, detail::MachinePassConcept,
307-
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>>;
301+
using PassConceptT =
302+
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
308303

309304
std::vector<std::unique_ptr<PassConceptT>> Passes;
310305
};

llvm/include/llvm/IR/PassManagerInternal.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,6 @@ struct AnalysisPassModel
328328
PassT Pass;
329329
};
330330

331-
struct MachinePassConcept;
332-
template <typename PassT> struct MachinePassModel;
333-
334331
} // end namespace detail
335332

336333
} // end namespace llvm

llvm/lib/CodeGen/MachinePassManager.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,27 +121,11 @@ PassManager<MachineFunction>::run(MachineFunction &MF,
121121
for (auto &Pass : Passes) {
122122
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
123123
continue;
124-
auto &MFProps = MF.getProperties();
125-
#ifndef NDEBUG
126-
auto RequiredProperties = Pass->getRequiredProperties();
127-
if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
128-
errs() << "MachineFunctionProperties required by " << Pass->name()
129-
<< " pass are not met by function " << F.getName() << ".\n"
130-
<< "Required properties: ";
131-
RequiredProperties.print(errs());
132-
errs() << "\nCurrent properties: ";
133-
MFProps.print(errs());
134-
errs() << '\n';
135-
report_fatal_error("MachineFunctionProperties check failed");
136-
}
137-
#endif
138124

139125
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
140126
if (MMI.getMachineFunction(F)) {
141127
MFAM.invalidate(MF, PassPA);
142128
PI.runAfterPass(*Pass, MF, PassPA);
143-
MFProps.set(Pass->getSetProperties());
144-
MFProps.reset(Pass->getClearedProperties());
145129
} else {
146130
MFAM.clear(MF, F.getName());
147131
PI.runAfterPassInvalidated<MachineFunction>(*Pass, PassPA);

0 commit comments

Comments
 (0)