@@ -44,122 +44,50 @@ using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
44
44
// / automatically mixes in \c PassInfoMixin.
45
45
template <typename DerivedT>
46
46
struct MachinePassInfoMixin : public PassInfoMixin <DerivedT> {
47
- // TODO: Add MachineFunctionProperties support.
48
- };
49
-
50
- 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
-
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)) {}
47
+ class PropertyChanger {
48
+ MachineFunction &MF;
64
49
65
- friend void swap (MachinePassModel &LHS, MachinePassModel &RHS) {
66
- using std::swap;
67
- swap (LHS.Pass , RHS.Pass );
68
- }
50
+ template <typename T>
51
+ using has_get_required_properties_t =
52
+ decltype (std::declval<T &>().getRequiredProperties());
69
53
70
- MachinePassModel &operator =(MachinePassModel RHS) {
71
- swap (*this , RHS);
72
- return *this ;
73
- }
54
+ template <typename T>
55
+ using has_get_set_properties_t =
56
+ decltype (std::declval<T &>().getSetProperties());
74
57
75
- MachinePassModel &operator =(const MachinePassModel &) = delete ;
76
- PreservedAnalyses run (MachineFunction &IR,
77
- MachineFunctionAnalysisManager &AM) override {
78
- return Pass.run (IR, AM);
79
- }
58
+ template <typename T>
59
+ using has_get_cleared_properties_t =
60
+ decltype (std::declval<T &>().getClearedProperties());
80
61
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 ();
95
- }
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
- }
62
+ public:
63
+ PropertyChanger (MachineFunction &MF) : MF(MF) {
64
+ #ifndef NDEBUG
65
+ if constexpr (is_detected<has_get_required_properties_t ,
66
+ DerivedT>::value) {
67
+ auto &MFProps = MF.getProperties ();
68
+ auto RequiredProperties = DerivedT::getRequiredProperties ();
69
+ if (!MFProps.verifyRequiredProperties (RequiredProperties)) {
70
+ errs () << " MachineFunctionProperties required by " << DerivedT::name ()
71
+ << " pass are not met by function " << MF.getName () << " .\n "
72
+ << " Required properties: " ;
73
+ RequiredProperties.print (errs ());
74
+ errs () << " \n Current properties: " ;
75
+ MFProps.print (errs ());
76
+ errs () << ' \n ' ;
77
+ report_fatal_error (" MachineFunctionProperties check failed" );
78
+ }
79
+ #endif
80
+ }
81
+ }
159
82
160
- PassT Pass;
83
+ ~PropertyChanger () {
84
+ if constexpr (is_detected<has_get_set_properties_t , DerivedT>::value)
85
+ MF.getProperties ().set (DerivedT::getSetProperties ());
86
+ if constexpr (is_detected<has_get_cleared_properties_t , DerivedT>::value)
87
+ MF.getProperties ().reset (DerivedT::getClearedProperties ());
88
+ }
89
+ };
161
90
};
162
- } // namespace detail
163
91
164
92
using MachineFunctionAnalysisManagerModuleProxy =
165
93
InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
@@ -251,11 +179,12 @@ class FunctionAnalysisManagerMachineFunctionProxy
251
179
252
180
class ModuleToMachineFunctionPassAdaptor
253
181
: public PassInfoMixin<ModuleToMachineFunctionPassAdaptor> {
254
- using MachinePassConcept = detail::MachinePassConcept;
255
-
256
182
public:
183
+ using PassConceptT =
184
+ detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
185
+
257
186
explicit ModuleToMachineFunctionPassAdaptor (
258
- std::unique_ptr<MachinePassConcept > Pass)
187
+ std::unique_ptr<PassConceptT > Pass)
259
188
: Pass(std::move(Pass)) {}
260
189
261
190
// / Runs the function pass across every function in the module.
@@ -266,17 +195,18 @@ class ModuleToMachineFunctionPassAdaptor
266
195
static bool isRequired () { return true ; }
267
196
268
197
private:
269
- std::unique_ptr<MachinePassConcept > Pass;
198
+ std::unique_ptr<PassConceptT > Pass;
270
199
};
271
200
272
201
template <typename MachineFunctionPassT>
273
202
ModuleToMachineFunctionPassAdaptor
274
203
createModuleToMachineFunctionPassAdaptor (MachineFunctionPassT &&Pass) {
275
- using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
204
+ using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
205
+ MachineFunctionAnalysisManager>;
276
206
// Do not use make_unique, it causes too many template instantiations,
277
207
// causing terrible compile times.
278
208
return ModuleToMachineFunctionPassAdaptor (
279
- std::unique_ptr<detail::MachinePassConcept >(
209
+ std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT >(
280
210
new PassModelT (std::forward<MachineFunctionPassT>(Pass))));
281
211
}
282
212
0 commit comments