|
64 | 64 | using namespace swift; |
65 | 65 | using namespace rewriting; |
66 | 66 |
|
67 | | -/// Recompute RulesInEmptyContext and DecomposeCount if needed. |
| 67 | +/// Recompute Useful, RulesInEmptyContext, ProjectionCount and DecomposeCount |
| 68 | +/// if needed. |
68 | 69 | void RewriteLoop::recompute(const RewriteSystem &system) { |
69 | 70 | if (!Dirty) |
70 | 71 | return; |
@@ -110,6 +111,8 @@ void RewriteLoop::recompute(const RewriteSystem &system) { |
110 | 111 | evaluator.apply(step, system); |
111 | 112 | } |
112 | 113 |
|
| 114 | + Useful = !rulesInEmptyContext.empty(); |
| 115 | + |
113 | 116 | RulesInEmptyContext.clear(); |
114 | 117 |
|
115 | 118 | // Collect all rules that we saw exactly once in empty context. |
@@ -147,6 +150,14 @@ unsigned RewriteLoop::getDecomposeCount( |
147 | 150 | return DecomposeCount; |
148 | 151 | } |
149 | 152 |
|
| 153 | +/// The number of Decompose steps, used by the elimination order to prioritize |
| 154 | +/// loops that are not concrete simplifications. |
| 155 | +bool RewriteLoop::isUseful( |
| 156 | + const RewriteSystem &system) const { |
| 157 | + const_cast<RewriteLoop *>(this)->recompute(system); |
| 158 | + return Useful; |
| 159 | +} |
| 160 | + |
150 | 161 | /// If a rewrite loop contains an explicit rule in empty context, propagate the |
151 | 162 | /// explicit bit to all other rules appearing in empty context within the same |
152 | 163 | /// loop. |
@@ -419,22 +430,21 @@ findRuleToDelete(llvm::function_ref<bool(unsigned)> isRedundantRuleFn) { |
419 | 430 | if (loop.isDeleted()) |
420 | 431 | continue; |
421 | 432 |
|
422 | | - bool foundAny = false; |
423 | | - for (unsigned ruleID : loop.findRulesAppearingOnceInEmptyContext(*this)) { |
424 | | - redundancyCandidates.emplace_back(loopID, ruleID); |
425 | | - foundAny = true; |
426 | | - } |
427 | | - |
428 | 433 | // Delete loops that don't contain any rewrite rules in empty context, |
429 | | - // since such loops do not give us useful information. |
430 | | - if (!foundAny) { |
| 434 | + // since such loops do not yield any elimination candidates. |
| 435 | + if (!loop.isUseful(*this)) { |
431 | 436 | if (Debug.contains(DebugFlags::HomotopyReduction)) { |
432 | 437 | llvm::dbgs() << "** Deleting useless loop #" << loopID << ": "; |
433 | 438 | loop.dump(llvm::dbgs(), *this); |
434 | 439 | llvm::dbgs() << "\n"; |
435 | 440 | } |
436 | 441 |
|
437 | 442 | loop.markDeleted(); |
| 443 | + continue; |
| 444 | + } |
| 445 | + |
| 446 | + for (unsigned ruleID : loop.findRulesAppearingOnceInEmptyContext(*this)) { |
| 447 | + redundancyCandidates.emplace_back(loopID, ruleID); |
438 | 448 | } |
439 | 449 | } |
440 | 450 |
|
|
0 commit comments