@@ -385,12 +385,6 @@ findRuleToDelete(EliminationPredicate isRedundantRuleFn) {
385
385
// / occurrences of the rule in all loops with the replacement path.
386
386
void RewriteSystem::deleteRule (unsigned ruleID,
387
387
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
-
394
388
// Replace all occurrences of the rule with the replacement path in
395
389
// all remaining rewrite loops.
396
390
for (unsigned loopID : indices (Loops)) {
@@ -458,8 +452,34 @@ void RewriteSystem::performHomotopyReduction(
458
452
}
459
453
460
454
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
+ });
462
477
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.
463
483
}
464
484
465
485
if (Debug.contains (DebugFlags::RedundantRules)) {
@@ -616,12 +636,12 @@ void RewriteSystem::minimizeRewriteSystem() {
616
636
return false ;
617
637
});
618
638
639
+ normalizeRedundantRules ();
640
+
619
641
// Check invariants after homotopy reduction.
620
642
verifyRewriteLoops ();
621
643
verifyRedundantConformances (redundantConformances);
622
644
verifyMinimizedRules (redundantConformances);
623
-
624
- normalizeRedundantRules ();
625
645
}
626
646
627
647
// / Returns flags indicating if the rewrite system has unresolved or
@@ -826,5 +846,17 @@ void RewriteSystem::verifyMinimizedRules(
826
846
dump (llvm::errs ());
827
847
abort ();
828
848
}
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
+ }
829
861
}
830
862
}
0 commit comments