@@ -218,6 +218,22 @@ class PassManager : public PassInfoMixin<
218218
219219 static bool isRequired () { return true ; }
220220
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+
221237protected:
222238 using PassConceptT =
223239 detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
@@ -797,6 +813,28 @@ extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
797813using ModuleAnalysisManagerFunctionProxy =
798814 OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
799815
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+
800838// / Trivial adaptor that maps from a module to its functions.
801839// /
802840// / Designed to allow composition of a FunctionPass(Manager) and
@@ -821,7 +859,10 @@ using ModuleAnalysisManagerFunctionProxy =
821859// / analyses are not invalidated while the function passes are running, so they
822860// / may be stale. Function analyses will not be stale.
823861class ModuleToFunctionPassAdaptor
824- : public PassInfoMixin<ModuleToFunctionPassAdaptor> {
862+ : public PassInfoMixin<ModuleToFunctionPassAdaptor>,
863+ public AdaptorMixin<ModuleToFunctionPassAdaptor> {
864+ friend AdaptorMixin<ModuleToFunctionPassAdaptor>;
865+
825866public:
826867 using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
827868
0 commit comments