Skip to content

Commit b5d7a01

Browse files
committed
[RequirementMachine] Factor the 'rules once in empty context' computation out
into a method on RewritePath.
1 parent 2f7018b commit b5d7a01

File tree

2 files changed

+54
-67
lines changed

2 files changed

+54
-67
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 51 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,14 @@ void RewriteLoop::recompute(const RewriteSystem &system) {
7474

7575
ProjectionCount = 0;
7676
DecomposeCount = 0;
77-
78-
// Rules appearing in empty context (possibly more than once).
79-
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
80-
81-
// The number of times each rule appears (with or without context).
82-
llvm::SmallDenseMap<unsigned, unsigned, 2> ruleMultiplicity;
77+
Useful = false;
8378

8479
RewritePathEvaluator evaluator(Basepoint);
85-
8680
for (auto step : Path) {
8781
switch (step.Kind) {
88-
case RewriteStep::Rule: {
89-
if (!step.isInContext() && !evaluator.isInContext())
90-
rulesInEmptyContext.insert(step.getRuleID());
91-
92-
++ruleMultiplicity[step.getRuleID()];
82+
case RewriteStep::Rule:
83+
Useful |= (!step.isInContext() && !evaluator.isInContext());
9384
break;
94-
}
9585

9686
case RewriteStep::LeftConcreteProjection:
9787
++ProjectionCount;
@@ -112,18 +102,7 @@ void RewriteLoop::recompute(const RewriteSystem &system) {
112102
evaluator.apply(step, system);
113103
}
114104

115-
Useful = !rulesInEmptyContext.empty();
116-
117-
RulesInEmptyContext.clear();
118-
119-
// Collect all rules that we saw exactly once in empty context.
120-
for (auto rule : rulesInEmptyContext) {
121-
auto found = ruleMultiplicity.find(rule);
122-
assert(found != ruleMultiplicity.end());
123-
124-
if (found->second == 1)
125-
RulesInEmptyContext.push_back(rule);
126-
}
105+
RulesInEmptyContext = Path.getRulesInEmptyContext(Basepoint, system);
127106
}
128107

129108
/// A rewrite rule is redundant if it appears exactly once in a loop
@@ -227,48 +206,8 @@ void RewriteSystem::propagateRedundantRequirementIDs() {
227206
if (!requirementID.hasValue())
228207
continue;
229208

230-
// FIXME: This code is almost identical to `RewriteLoop::recompute`.
231-
232-
// Rules appearing in empty context (possibly more than once).
233-
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
234-
// The number of times each rule appears (with or without context).
235-
llvm::SmallDenseMap<unsigned, unsigned, 2> ruleFrequency;
236-
237-
RewritePathEvaluator evaluator(MutableTerm(rule.getLHS()));
238-
for (auto step : rewritePath) {
239-
switch (step.Kind) {
240-
case RewriteStep::Rule: {
241-
if (!step.isInContext() && !evaluator.isInContext())
242-
rulesInEmptyContext.insert(step.getRuleID());
243-
244-
++ruleFrequency[step.getRuleID()];
245-
break;
246-
}
247-
248-
case RewriteStep::LeftConcreteProjection:
249-
case RewriteStep::Decompose:
250-
case RewriteStep::PrefixSubstitutions:
251-
case RewriteStep::Shift:
252-
case RewriteStep::Relation:
253-
case RewriteStep::DecomposeConcrete:
254-
case RewriteStep::RightConcreteProjection:
255-
break;
256-
}
257-
258-
evaluator.apply(step, *this);
259-
}
260-
261-
// Collect all rules that we saw exactly once in empty context.
262-
SmallVector<unsigned, 1> rulesOnceInEmptyContext;
263-
for (auto rule : rulesInEmptyContext) {
264-
auto found = ruleFrequency.find(rule);
265-
assert(found != ruleFrequency.end());
266-
267-
if (found->second == 1)
268-
rulesOnceInEmptyContext.push_back(rule);
269-
}
270-
271-
for (auto ruleID : rulesOnceInEmptyContext) {
209+
MutableTerm lhs(rule.getLHS());
210+
for (auto ruleID : rewritePath.getRulesInEmptyContext(lhs, *this)) {
272211
auto &replacement = Rules[ruleID];
273212
if (!replacement.isPermanent() &&
274213
!replacement.getRequirementID().hasValue()) {
@@ -489,6 +428,51 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
489428
return true;
490429
}
491430

431+
SmallVector<unsigned, 1>
432+
RewritePath::getRulesInEmptyContext(const MutableTerm &term,
433+
const RewriteSystem &system) {
434+
// Rules appearing in empty context (possibly more than once).
435+
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
436+
// The number of times each rule appears (with or without context).
437+
llvm::SmallDenseMap<unsigned, unsigned, 2> ruleFrequency;
438+
439+
RewritePathEvaluator evaluator(term);
440+
for (auto step : Steps) {
441+
switch (step.Kind) {
442+
case RewriteStep::Rule: {
443+
if (!step.isInContext() && !evaluator.isInContext())
444+
rulesInEmptyContext.insert(step.getRuleID());
445+
446+
++ruleFrequency[step.getRuleID()];
447+
break;
448+
}
449+
450+
case RewriteStep::LeftConcreteProjection:
451+
case RewriteStep::Decompose:
452+
case RewriteStep::PrefixSubstitutions:
453+
case RewriteStep::Shift:
454+
case RewriteStep::Relation:
455+
case RewriteStep::DecomposeConcrete:
456+
case RewriteStep::RightConcreteProjection:
457+
break;
458+
}
459+
460+
evaluator.apply(step, system);
461+
}
462+
463+
// Collect all rules that we saw exactly once in empty context.
464+
SmallVector<unsigned, 1> rulesOnceInEmptyContext;
465+
for (auto rule : rulesInEmptyContext) {
466+
auto found = ruleFrequency.find(rule);
467+
assert(found != ruleFrequency.end());
468+
469+
if (found->second == 1)
470+
rulesOnceInEmptyContext.push_back(rule);
471+
}
472+
473+
return rulesOnceInEmptyContext;
474+
}
475+
492476
/// Find a rule to delete by looking through all loops for rewrite rules appearing
493477
/// once in empty context. Returns a pair consisting of a loop ID and a rule ID,
494478
/// otherwise returns None.

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ class RewritePath {
409409

410410
bool replaceRuleWithPath(unsigned ruleID, const RewritePath &path);
411411

412+
SmallVector<unsigned, 1> getRulesInEmptyContext(const MutableTerm &term,
413+
const RewriteSystem &system);
414+
412415
void invert();
413416

414417
bool computeFreelyReducedForm();

0 commit comments

Comments
 (0)