@@ -66,9 +66,17 @@ using namespace rewriting;
66
66
67
67
// / A rewrite rule is redundant if it appears exactly once in a loop
68
68
// / without context.
69
- llvm::SmallVector<unsigned , 1 >
69
+ // /
70
+ // / This method will cache the result; markDirty() must be called after
71
+ // / the underlying rewrite path is modified to invalidate the cached
72
+ // / result.
73
+ ArrayRef<unsigned >
70
74
RewriteLoop::findRulesAppearingOnceInEmptyContext (
71
75
const RewriteSystem &system) const {
76
+ // If we're allowed to use the cached result, return that.
77
+ if (!Dirty)
78
+ return RulesInEmptyContext;
79
+
72
80
// Rules appearing in empty context (possibly more than once).
73
81
llvm::SmallDenseSet<unsigned , 2 > rulesInEmptyContext;
74
82
@@ -100,17 +108,21 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
100
108
evaluator.apply (step, system);
101
109
}
102
110
111
+ auto *mutThis = const_cast <RewriteLoop *>(this );
112
+ mutThis->RulesInEmptyContext .clear ();
113
+
103
114
// Collect all rules that we saw exactly once in empty context.
104
- SmallVector<unsigned , 1 > result;
105
115
for (auto rule : rulesInEmptyContext) {
106
116
auto found = ruleMultiplicity.find (rule);
107
117
assert (found != ruleMultiplicity.end ());
108
118
109
119
if (found->second == 1 )
110
- result .push_back (rule);
120
+ mutThis-> RulesInEmptyContext .push_back (rule);
111
121
}
112
122
113
- return result;
123
+ // Cache the result for later.
124
+ mutThis->Dirty = 0 ;
125
+ return RulesInEmptyContext;
114
126
}
115
127
116
128
// / If a rewrite loop contains an explicit rule in empty context, propagate the
@@ -145,7 +157,7 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
145
157
// / explicit bit from the original rule to the canonical rule.
146
158
void RewriteSystem::propagateExplicitBits () {
147
159
for (const auto &loop : Loops) {
148
- SmallVector< unsigned , 1 > rulesInEmptyContext =
160
+ auto rulesInEmptyContext =
149
161
loop.findRulesAppearingOnceInEmptyContext (*this );
150
162
151
163
bool sawExplicitRule = false ;
@@ -457,8 +469,8 @@ void RewriteSystem::deleteRule(unsigned ruleID,
457
469
llvm::dbgs () << " \n " ;
458
470
}
459
471
460
- // Replace all occurrences of the rule with the replacement path and
461
- // normalize all loops.
472
+ // Replace all occurrences of the rule with the replacement path in
473
+ // all remaining rewrite loops.
462
474
for (auto &loop : Loops) {
463
475
if (loop.isDeleted ())
464
476
continue ;
@@ -467,6 +479,10 @@ void RewriteSystem::deleteRule(unsigned ruleID,
467
479
if (!changed)
468
480
continue ;
469
481
482
+ // The loop's path has changed, so we must invalidate the cached
483
+ // result of findRulesAppearingOnceInEmptyContext().
484
+ loop.markDirty ();
485
+
470
486
if (Debug.contains (DebugFlags::HomotopyReduction)) {
471
487
llvm::dbgs () << " ** Updated loop: " ;
472
488
loop.dump (llvm::dbgs (), *this );
0 commit comments