@@ -74,24 +74,14 @@ void RewriteLoop::recompute(const RewriteSystem &system) {
74
74
75
75
ProjectionCount = 0 ;
76
76
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 ;
83
78
84
79
RewritePathEvaluator evaluator (Basepoint);
85
-
86
80
for (auto step : Path) {
87
81
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 ());
93
84
break ;
94
- }
95
85
96
86
case RewriteStep::LeftConcreteProjection:
97
87
++ProjectionCount;
@@ -112,18 +102,7 @@ void RewriteLoop::recompute(const RewriteSystem &system) {
112
102
evaluator.apply (step, system);
113
103
}
114
104
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);
127
106
}
128
107
129
108
// / A rewrite rule is redundant if it appears exactly once in a loop
@@ -227,48 +206,8 @@ void RewriteSystem::propagateRedundantRequirementIDs() {
227
206
if (!requirementID.hasValue ())
228
207
continue ;
229
208
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 )) {
272
211
auto &replacement = Rules[ruleID];
273
212
if (!replacement.isPermanent () &&
274
213
!replacement.getRequirementID ().hasValue ()) {
@@ -489,6 +428,51 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
489
428
return true ;
490
429
}
491
430
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
+
492
476
// / Find a rule to delete by looking through all loops for rewrite rules appearing
493
477
// / once in empty context. Returns a pair consisting of a loop ID and a rule ID,
494
478
// / otherwise returns None.
0 commit comments