@@ -138,26 +138,44 @@ template <typename PassT> struct MachinePassModel : MachinePassConcept {
138
138
return getSetPropertiesImpl<PassT>();
139
139
}
140
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
- }
141
+ template <typename T>
142
+ using has_get_cleared_properties_t =
143
+ decltype (std::declval<T &>().getClearedProperties());
144
+
145
+ public:
146
+ PropertyChanger (MachineFunction &MF) : MF(MF) {
147
+ #ifndef NDEBUG
148
+ if constexpr (is_detected<has_get_required_properties_t ,
149
+ DerivedT>::value) {
150
+ auto &MFProps = MF.getProperties ();
151
+ auto RequiredProperties = DerivedT::getRequiredProperties ();
152
+ if (!MFProps.verifyRequiredProperties (RequiredProperties)) {
153
+ errs () << " MachineFunctionProperties required by " << DerivedT::name ()
154
+ << " pass are not met by function " << MF.getName () << " .\n "
155
+ << " Required properties: " ;
156
+ RequiredProperties.print (errs ());
157
+ errs () << " \n Current properties: " ;
158
+ MFProps.print (errs ());
159
+ errs () << ' \n ' ;
160
+ report_fatal_error (" MachineFunctionProperties check failed" );
161
+ }
162
+ #endif
163
+ }
164
+ }
165
+
166
+ ~PropertyChanger () {
167
+ if constexpr (is_detected<has_get_set_properties_t , DerivedT>::value)
168
+ MF.getProperties ().set (DerivedT::getSetProperties ());
169
+ if constexpr (is_detected<has_get_cleared_properties_t , DerivedT>::value)
170
+ MF.getProperties ().reset (DerivedT::getClearedProperties ());
171
+ }
172
+ };
159
173
160
- PassT Pass;
174
+ PreservedAnalyses run (MachineFunction &MF,
175
+ MachineFunctionAnalysisManager &MFAM) {
176
+ PropertyChanger PC (MF);
177
+ return static_cast <DerivedT *>(this )->run (MF, MFAM);
178
+ }
161
179
};
162
180
} // namespace detail
163
181
@@ -280,6 +298,27 @@ createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
280
298
new PassModelT (std::forward<MachineFunctionPassT>(Pass))));
281
299
}
282
300
301
+ template <>
302
+ template <typename PassT>
303
+ std::enable_if_t <!std::is_same<PassT, PassManager<MachineFunction>>::value>
304
+ PassManager<MachineFunction>::addPass (PassT &&Pass) {
305
+ using PassModelT =
306
+ detail::PassModel<MachineFunction, PassT, MachineFunctionAnalysisManager>;
307
+ using MachineFunctionPassModelT =
308
+ detail::PassModel<MachineFunction, MachinePassInfoMixin<PassT>,
309
+ MachineFunctionAnalysisManager>;
310
+ // Do not use make_unique or emplace_back, they cause too many template
311
+ // instantiations, causing terrible compile times.
312
+ if constexpr (std::is_base_of_v<MachinePassInfoMixin<PassT>, PassT>) {
313
+ Passes.push_back (
314
+ std::unique_ptr<PassConceptT>(new MachineFunctionPassModelT (
315
+ std::forward<MachinePassInfoMixin<PassT>>(Pass))));
316
+ } else {
317
+ Passes.push_back (std::unique_ptr<PassConceptT>(
318
+ new PassModelT (std::forward<PassT>(Pass))));
319
+ }
320
+ }
321
+
283
322
template <>
284
323
PreservedAnalyses
285
324
PassManager<MachineFunction>::run (MachineFunction &,
0 commit comments