16
16
// their respective analysis managers such as ModuleAnalysisManager and
17
17
// FunctionAnalysisManager.
18
18
//
19
- // TODO: Add MachineFunctionProperties support.
20
- //
21
19
// ===----------------------------------------------------------------------===//
22
20
23
21
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
@@ -44,23 +42,67 @@ using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
44
42
// / automatically mixes in \c PassInfoMixin.
45
43
template <typename DerivedT>
46
44
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 () << " \n Current properties: " ;
74
+ MFProps.print (errs ());
75
+ errs () << ' \n ' ;
76
+ report_fatal_error (" MachineFunctionProperties check failed" );
77
+ }
78
+ }
79
+ #endif
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
+ }
48
96
};
49
97
50
98
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
- };
57
99
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)) {}
64
106
65
107
friend void swap (MachinePassModel &LHS, MachinePassModel &RHS) {
66
108
using std::swap;
@@ -75,89 +117,8 @@ template <typename PassT> struct MachinePassModel : MachinePassConcept {
75
117
MachinePassModel &operator =(const MachinePassModel &) = delete ;
76
118
PreservedAnalyses run (MachineFunction &IR,
77
119
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);
95
121
}
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;
161
122
};
162
123
} // namespace detail
163
124
@@ -251,11 +212,12 @@ class FunctionAnalysisManagerMachineFunctionProxy
251
212
252
213
class ModuleToMachineFunctionPassAdaptor
253
214
: public PassInfoMixin<ModuleToMachineFunctionPassAdaptor> {
254
- using MachinePassConcept = detail::MachinePassConcept;
255
-
256
215
public:
216
+ using PassConceptT =
217
+ detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
218
+
257
219
explicit ModuleToMachineFunctionPassAdaptor (
258
- std::unique_ptr<MachinePassConcept > Pass)
220
+ std::unique_ptr<PassConceptT > Pass)
259
221
: Pass(std::move(Pass)) {}
260
222
261
223
// / Runs the function pass across every function in the module.
@@ -266,20 +228,41 @@ class ModuleToMachineFunctionPassAdaptor
266
228
static bool isRequired () { return true ; }
267
229
268
230
private:
269
- std::unique_ptr<MachinePassConcept > Pass;
231
+ std::unique_ptr<PassConceptT > Pass;
270
232
};
271
233
272
234
template <typename MachineFunctionPassT>
273
235
ModuleToMachineFunctionPassAdaptor
274
236
createModuleToMachineFunctionPassAdaptor (MachineFunctionPassT &&Pass) {
275
- using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
237
+ using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
238
+ MachineFunctionAnalysisManager>;
276
239
// Do not use make_unique, it causes too many template instantiations,
277
240
// causing terrible compile times.
278
241
return ModuleToMachineFunctionPassAdaptor (
279
- std::unique_ptr<detail::MachinePassConcept >(
242
+ std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT >(
280
243
new PassModelT (std::forward<MachineFunctionPassT>(Pass))));
281
244
}
282
245
246
+ template <>
247
+ template <typename PassT>
248
+ void PassManager<MachineFunction>::addPass(PassT &&Pass) {
249
+ using PassModelT =
250
+ detail::PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>;
251
+ using MachinePassModelT = detail::MachinePassModel<PassT>;
252
+ // Do not use make_unique or emplace_back, they cause too many template
253
+ // instantiations, causing terrible compile times.
254
+ if constexpr (std::is_base_of_v<MachinePassInfoMixin<PassT>, PassT>) {
255
+ Passes.push_back (std::unique_ptr<PassConceptT>(
256
+ new MachinePassModelT (std::forward<PassT>(Pass))));
257
+ } else if constexpr (std::is_same_v<PassT, PassManager<MachineFunction>>) {
258
+ for (auto &P : Pass.Passes )
259
+ Passes.push_back (std::move (P));
260
+ } else {
261
+ Passes.push_back (std::unique_ptr<PassConceptT>(
262
+ new PassModelT (std::forward<PassT>(Pass))));
263
+ }
264
+ }
265
+
283
266
template <>
284
267
PreservedAnalyses
285
268
PassManager<MachineFunction>::run(MachineFunction &,
0 commit comments