Skip to content

Commit aeceda3

Browse files
committed
RequirementMachine: Introduce RewriteLoop::getProjectionCount()
1 parent 6685e55 commit aeceda3

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,13 @@
6363
using namespace swift;
6464
using 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.

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,21 +433,31 @@ class RewriteLoop {
433433
RewritePath Path;
434434

435435
private:
436-
unsigned Deleted : 1;
437-
438436
/// Cached value for findRulesAppearingOnceInEmptyContext().
439437
SmallVector<unsigned, 1> RulesInEmptyContext;
440438

439+
/// Cached value for getProjectionCount().
440+
unsigned ProjectionCount : 30;
441+
442+
/// Loops are deleted once they no longer contain rules in empty context,
443+
/// since at that point they don't participate in minimization and do not
444+
/// need to be considered.
445+
unsigned Deleted : 1;
446+
441447
/// If true, RulesInEmptyContext should be recomputed.
442448
unsigned Dirty : 1;
443449

450+
void recompute(const RewriteSystem &system);
451+
444452
public:
445453
RewriteLoop(MutableTerm basepoint, RewritePath path)
446454
: Basepoint(basepoint), Path(path) {
455+
ProjectionCount = 0;
456+
447457
Deleted = 0;
448458

449-
// Initially, the RulesInEmptyContext vector is not valid because
450-
// it has not been computed yet.
459+
// Initially, RulesInEmptyContext and ProjectionCount are not valid because
460+
// they have not been computed yet.
451461
Dirty = 1;
452462
}
453463

@@ -470,6 +480,8 @@ class RewriteLoop {
470480
ArrayRef<unsigned>
471481
findRulesAppearingOnceInEmptyContext(const RewriteSystem &system) const;
472482

483+
unsigned getProjectionCount(const RewriteSystem &system) const;
484+
473485
void findProtocolConformanceRules(
474486
llvm::SmallDenseMap<const ProtocolDecl *,
475487
ProtocolConformanceRules, 2> &result,

0 commit comments

Comments
 (0)