@@ -218,6 +218,22 @@ class PassManager : public PassInfoMixin<
218
218
219
219
static bool isRequired () { return true ; }
220
220
221
+ // / Erase all passes that satisfy the predicate \p Pred.
222
+ // / For internal use only!
223
+ void eraseIf (function_ref<bool (StringRef)> Pred) {
224
+ for (auto I = Passes.begin (); I != Passes.end ();) {
225
+ auto &P = *I;
226
+ P->eraseIf (Pred);
227
+ bool IsSpecial = P->name ().ends_with (" PassAdaptor" ) ||
228
+ P->name ().contains (" PassManager" );
229
+ bool PredResult = Pred (P->name ());
230
+ if ((!IsSpecial && PredResult) || (IsSpecial && P->isEmpty ()))
231
+ I = Passes.erase (I);
232
+ else
233
+ ++I;
234
+ }
235
+ }
236
+
221
237
protected:
222
238
using PassConceptT =
223
239
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
@@ -797,6 +813,28 @@ extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
797
813
using ModuleAnalysisManagerFunctionProxy =
798
814
OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
799
815
816
+ // / Simple mix-in for pass adaptor. If adaptor contains only a single pass
817
+ // / instance in it, then it can inherit this mix-in to get default `isEmpty()`
818
+ // / and `eraseIf` implementation. This mix-in must have access to the `Pass`
819
+ // / member in adaptor.
820
+ template <typename DerivedT> struct AdaptorMixin {
821
+ bool isEmpty () const { return derived ().Pass == nullptr ; }
822
+
823
+ void eraseIf (function_ref<bool (StringRef)> Pred) {
824
+ StringRef PassName = derived ().Pass ->name ();
825
+ if (PassName.contains (" PassManager" ) || PassName.ends_with (" PassAdaptor" )) {
826
+ derived ().Pass ->eraseIf (Pred);
827
+ if (derived ().Pass ->isEmpty ())
828
+ derived ().Pass .reset ();
829
+ } else if (Pred (PassName)) {
830
+ derived ().Pass .reset ();
831
+ }
832
+ }
833
+
834
+ private:
835
+ DerivedT &derived () { return *static_cast <Derived *>(this ); }
836
+ };
837
+
800
838
// / Trivial adaptor that maps from a module to its functions.
801
839
// /
802
840
// / Designed to allow composition of a FunctionPass(Manager) and
@@ -821,7 +859,10 @@ using ModuleAnalysisManagerFunctionProxy =
821
859
// / analyses are not invalidated while the function passes are running, so they
822
860
// / may be stale. Function analyses will not be stale.
823
861
class ModuleToFunctionPassAdaptor
824
- : public PassInfoMixin<ModuleToFunctionPassAdaptor> {
862
+ : public PassInfoMixin<ModuleToFunctionPassAdaptor>,
863
+ public AdaptorMixin<ModuleToFunctionPassAdaptor> {
864
+ friend AdaptorMixin<ModuleToFunctionPassAdaptor>;
865
+
825
866
public:
826
867
using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
827
868
0 commit comments