6363using namespace swift ;
6464using namespace rewriting ;
6565
66- // / A rewrite rule is redundant if it appears exactly once in a loop
67- // / without context.
68- // /
69- // / This method will cache the result; markDirty() must be called after
70- // / the underlying rewrite path is modified to invalidate the cached
71- // / result.
72- ArrayRef<unsigned >
73- RewriteLoop::findRulesAppearingOnceInEmptyContext (
74- const RewriteSystem &system) const {
75- // If we're allowed to use the cached result, return that.
66+ // / Recompute RulesInEmptyContext and DecomposeCount if needed.
67+ void RewriteLoop::recompute (const RewriteSystem &system) {
7668 if (!Dirty)
77- return RulesInEmptyContext;
69+ return ;
70+ Dirty = 0 ;
71+
72+ ProjectionCount = 0 ;
7873
7974 // Rules appearing in empty context (possibly more than once).
8075 llvm::SmallDenseSet<unsigned , 2 > rulesInEmptyContext;
@@ -94,36 +89,51 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
9489 break ;
9590 }
9691
92+ case RewriteStep::LeftConcreteProjection:
93+ ++ProjectionCount;
94+ break ;
95+
9796 case RewriteStep::PrefixSubstitutions:
9897 case RewriteStep::Shift:
9998 case RewriteStep::Decompose:
10099 case RewriteStep::Relation:
101100 case RewriteStep::DecomposeConcrete:
102- case RewriteStep::LeftConcreteProjection:
103101 case RewriteStep::RightConcreteProjection:
104102 break ;
105103 }
106104
107105 evaluator.apply (step, system);
108106 }
109107
110- auto *mutThis = const_cast <RewriteLoop *>(this );
111- mutThis->RulesInEmptyContext .clear ();
108+ RulesInEmptyContext.clear ();
112109
113110 // Collect all rules that we saw exactly once in empty context.
114111 for (auto rule : rulesInEmptyContext) {
115112 auto found = ruleMultiplicity.find (rule);
116113 assert (found != ruleMultiplicity.end ());
117114
118115 if (found->second == 1 )
119- mutThis-> RulesInEmptyContext .push_back (rule);
116+ RulesInEmptyContext.push_back (rule);
120117 }
118+ }
121119
122- // Cache the result for later.
123- mutThis->Dirty = 0 ;
120+ // / A rewrite rule is redundant if it appears exactly once in a loop
121+ // / without context.
122+ ArrayRef<unsigned >
123+ RewriteLoop::findRulesAppearingOnceInEmptyContext (
124+ const RewriteSystem &system) const {
125+ const_cast <RewriteLoop *>(this )->recompute (system);
124126 return RulesInEmptyContext;
125127}
126128
129+ // / The number of LeftConcreteProjection steps, used by the elimination order to
130+ // / prioritize loops that are not concrete unification projections.
131+ unsigned RewriteLoop::getProjectionCount (
132+ const RewriteSystem &system) const {
133+ const_cast <RewriteLoop *>(this )->recompute (system);
134+ return ProjectionCount;
135+ }
136+
127137// / If a rewrite loop contains an explicit rule in empty context, propagate the
128138// / explicit bit to all other rules appearing in empty context within the same
129139// / loop.
0 commit comments