| Index: pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
|
| diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
|
| index 0bb70ed14ee9d9695136c159c23ebb4e491f5126..49a6c22c480866179db5a7889c649803ee20d9eb 100644
|
| --- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
|
| +++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
|
| @@ -306,6 +306,17 @@ class LogicalRewriter extends RecursiveTransformer
|
| node.elseExpression = tmp;
|
| }
|
|
|
| + // x ? y : x ==> x && y
|
| + if (isSameVariable(node.condition, node.elseExpression)) {
|
| + destroyVariableUse(node.elseExpression);
|
| + return new LogicalOperator.and(node.condition, node.thenExpression);
|
| + }
|
| + // x ? x : y ==> x || y
|
| + if (isSameVariable(node.condition, node.thenExpression)) {
|
| + destroyVariableUse(node.thenExpression);
|
| + return new LogicalOperator.or(node.condition, node.elseExpression);
|
| + }
|
| +
|
| return node;
|
| }
|
|
|
| @@ -468,6 +479,18 @@ class LogicalRewriter extends RecursiveTransformer
|
| e.elseExpression = (e.elseExpression as Not).operand;
|
| return new Not(e);
|
| }
|
| +
|
| + // x ? y : x ==> x && y
|
| + if (isSameVariable(e.condition, e.elseExpression)) {
|
| + destroyVariableUse(e.elseExpression);
|
| + return new LogicalOperator.and(e.condition, e.thenExpression);
|
| + }
|
| + // x ? x : y ==> x || y
|
| + if (isSameVariable(e.condition, e.thenExpression)) {
|
| + destroyVariableUse(e.thenExpression);
|
| + return new LogicalOperator.or(e.condition, e.elseExpression);
|
| + }
|
| +
|
| return e;
|
| }
|
| if (e is Constant && e.value.isBool) {
|
| @@ -509,5 +532,23 @@ class LogicalRewriter extends RecursiveTransformer
|
| return new LogicalOperator.or(e1, e2);
|
| }
|
| }
|
| +
|
| + /// True if [e2] is known to return the same value as [e1]
|
| + /// (with no additional side effects) if evaluated immediately after [e1].
|
| + ///
|
| + /// Concretely, this is true if [e1] and [e2] are uses of the same variable,
|
| + /// or if [e2] is a use of a variable assigned by [e1].
|
| + bool isSameVariable(Expression e1, Expression e2) {
|
| + if (e1 is VariableUse) {
|
| + return e2 is VariableUse && e1.variable == e2.variable;
|
| + } else if (e1 is Assign) {
|
| + return e2 is VariableUse && e1.variable == e2.variable;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + void destroyVariableUse(VariableUse node) {
|
| + --node.variable.readCount;
|
| + }
|
| }
|
|
|
|
|