Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Unified Diff: pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart

Issue 1601863005: Remove useless branches in shrinking_reductions. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index 16a1d15f3665c4198bfe996ea8ea1b05e8b4c694..f846dac52e5160394df62284a2b49a7d9d7b1937 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -7,6 +7,7 @@ library dart2js.cps_ir.shrinking_reductions;
import 'cps_ir_nodes.dart';
import 'optimizers.dart';
import 'cps_fragment.dart';
+import '../constants/values.dart' as values;
/**
* [ShrinkingReducer] applies shrinking reductions to CPS terms as described
@@ -81,6 +82,9 @@ class ShrinkingReducer extends Pass {
case _ReductionKind.DEAD_PARAMETER:
_reduceDeadParameter(task);
break;
+ case _ReductionKind.BRANCH:
+ _reduceBranch(task);
+ break;
default:
assert(false);
}
@@ -191,6 +195,38 @@ class ShrinkingReducer extends Pass {
new _RemovalVisitor(_worklist).visit(cont);
}
+ void _reduceBranch(_ReductionTask task) {
+ Branch branch = task.node;
+ // Task can be added as both a useless if and a constant folding.
+ if (branch.parent == _DELETED) return;
+
+ // Replace Branch with InvokeContinuation of one of the targets. When the
+ // branch is deleted the other target becomes unreferenced and the chosen
+ // target becomes available for eta-cont and further reductions.
+ Continuation target;
+
+ Primitive condition = branch.condition.definition;
+ if (condition is Constant) {
+ target = isTruthyConstant(condition.value, strict: branch.isStrictCheck)
+ ? branch.trueContinuation.definition
+ : branch.falseContinuation.definition;
+ } else if (_isBranchTargetOfUselessIf(branch.trueContinuation.definition)) {
+ target = branch.trueContinuation.definition;
+ } else {
+ return;
+ }
+
+ InvokeContinuation invoke = new InvokeContinuation(
+ target, <Primitive>[]
+ // TODO(sra): Add sourceInformation.
+ /*, sourceInformation: branch.sourceInformation*/);
+ branch.parent.body = invoke;
+ invoke.parent = branch.parent;
+ branch.parent = _DELETED;
+
+ new _RemovalVisitor(_worklist).visit(branch);
+ }
+
void _reduceDeadParameter(_ReductionTask task) {
// Continuation eta-reduction can destroy a dead parameter redex. For
// example, in the term:
@@ -371,6 +407,37 @@ bool _isEtaCont(Continuation cont) {
return true;
}
+bool _isBranchTargetOfUselessIf(Continuation cont) {
+ // A useless-if has an empty then and else branch, e.g. `if (cond);`.
+ //
+ // Detect T or F in
+ //
+ // let cont Join() = ...
+ // in let cont T() = Join()
+ // F() = Join()
+ // in branch condition T F
+ //
+ if (!cont.hasExactlyOneUse) return false;
+ if (cont.firstRef.parent is! Branch) return false;
+ Branch branch = cont.firstRef.parent;
+ Continuation trueCont = branch.trueContinuation.definition;
+ Continuation falseCont = branch.falseContinuation.definition;
+ // Are both continuations the same InvokeContinuation on a join?
+ if (trueCont.body is! InvokeContinuation) return false;
+ if (falseCont.body is! InvokeContinuation) return false;
+ InvokeContinuation trueInvoke = trueCont.body;
+ InvokeContinuation falseInvoke = falseCont.body;
+ if (trueInvoke.continuation.definition !=
+ falseInvoke.continuation.definition) {
+ return false;
+ }
+ assert(trueInvoke.arguments.length == falseInvoke.arguments.length);
+ // Matching zero arguments should be adequate, since isomorphic true and false
+ // invocations should result in redundant phis which are removed elsewhere.
+ if (trueInvoke.arguments.isNotEmpty) return false;
+ return true;
+}
+
bool _isDeadParameter(Parameter parameter) {
// We cannot remove function parameters as an intraprocedural optimization.
if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) {
@@ -411,6 +478,12 @@ class _RedexVisitor extends TrampolineRecursiveVisitor {
}
}
+ void processBranch(Branch node) {
+ if (node.condition.definition is Constant) {
+ worklist.add(new _ReductionTask(_ReductionKind.BRANCH, node));
+ }
+ }
+
void processContinuation(Continuation node) {
// While it would be nice to remove exception handlers that are provably
// unnecessary (e.g., the body cannot throw), that takes more sophisticated
@@ -430,6 +503,9 @@ class _RedexVisitor extends TrampolineRecursiveVisitor {
worklist.add(new _ReductionTask(_ReductionKind.BETA_CONT_LIN, node));
} else if (_isEtaCont(node)) {
worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, node));
+ } else if (_isBranchTargetOfUselessIf(node)) {
+ worklist.add(new _ReductionTask(_ReductionKind.BRANCH,
+ node.firstRef.parent));
}
}
@@ -486,6 +562,9 @@ class _RemovalVisitor extends TrampolineRecursiveVisitor {
worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, cont));
} else if (_isBetaContLin(cont)) {
worklist.add(new _ReductionTask(_ReductionKind.BETA_CONT_LIN, cont));
+ } else if (_isBranchTargetOfUselessIf(cont)) {
+ worklist.add(
+ new _ReductionTask(_ReductionKind.BRANCH, cont.firstRef.parent));
}
}
}
@@ -507,6 +586,7 @@ class _ReductionKind {
static const _ReductionKind ETA_CONT = const _ReductionKind('eta-cont', 3);
static const _ReductionKind DEAD_PARAMETER =
const _ReductionKind('dead-parameter', 4);
+ static const _ReductionKind BRANCH = const _ReductionKind('branch', 5);
String toString() => name;
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698