Skip to content

Commit 2a634ba

Browse files
committed
RequirementMachine: Optimize RewriteSystem::normalizeRedundantRules()
1 parent afafede commit 2a634ba

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,6 @@ findRuleToDelete(EliminationPredicate isRedundantRuleFn) {
385385
/// occurrences of the rule in all loops with the replacement path.
386386
void RewriteSystem::deleteRule(unsigned ruleID,
387387
const RewritePath &replacementPath) {
388-
// Replace all occurrences of the rule with the replacement path in
389-
// all redundant rule paths recorded so far.
390-
for (auto &pair : RedundantRules) {
391-
(void) pair.second.replaceRuleWithPath(ruleID, replacementPath);
392-
}
393-
394388
// Replace all occurrences of the rule with the replacement path in
395389
// all remaining rewrite loops.
396390
for (unsigned loopID : indices(Loops)) {
@@ -458,8 +452,34 @@ void RewriteSystem::performHomotopyReduction(
458452
}
459453

460454
void RewriteSystem::normalizeRedundantRules() {
461-
for (auto &pair : RedundantRules) {
455+
llvm::DenseMap<unsigned, unsigned> RedundantRuleMap;
456+
457+
// A redundant path in the range [0, i-1] might contain rewrite steps naming
458+
// rules that subsequently became redundant in the range [i, e-1].
459+
//
460+
// We back-substitute later rules into earlier paths here.
461+
for (unsigned i = 0, e = RedundantRules.size(); i < e; ++i) {
462+
// Pre-condition: Redundant paths in the range [i+1, e-1] do not involve
463+
// any other redundant rules.
464+
unsigned j = e - i - 1;
465+
466+
// Replace all occurrences of redundant rules with their path at
467+
// RedundantRules[i].
468+
auto &pair = RedundantRules[j];
469+
pair.second.replaceRulesWithPaths(
470+
[&](unsigned ruleID) -> RewritePath * {
471+
auto found = RedundantRuleMap.find(ruleID);
472+
if (found != RedundantRuleMap.end())
473+
return &RedundantRules[found->second].second;
474+
475+
return nullptr;
476+
});
462477
pair.second.computeNormalForm(*this);
478+
479+
RedundantRuleMap[RedundantRules[j].first] = j;
480+
481+
// Post-condition: the path for RedundantRules[i] does not contain any
482+
// redundant rules.
463483
}
464484

465485
if (Debug.contains(DebugFlags::RedundantRules)) {
@@ -616,12 +636,12 @@ void RewriteSystem::minimizeRewriteSystem() {
616636
return false;
617637
});
618638

639+
normalizeRedundantRules();
640+
619641
// Check invariants after homotopy reduction.
620642
verifyRewriteLoops();
621643
verifyRedundantConformances(redundantConformances);
622644
verifyMinimizedRules(redundantConformances);
623-
624-
normalizeRedundantRules();
625645
}
626646

627647
/// Returns flags indicating if the rewrite system has unresolved or
@@ -826,5 +846,17 @@ void RewriteSystem::verifyMinimizedRules(
826846
dump(llvm::errs());
827847
abort();
828848
}
849+
850+
for (const auto &step : pair.second) {
851+
if (step.Kind == RewriteStep::Rule) {
852+
const auto &rule = getRule(step.getRuleID());
853+
if (rule.isRedundant()) {
854+
llvm::errs() << "Redundant requirement path contains a redundant "
855+
"rule " << rule << "\n";
856+
dump(llvm::errs());
857+
abort();
858+
}
859+
}
860+
}
829861
}
830862
}

0 commit comments

Comments
 (0)