Skip to content

Commit d3d7de8

Browse files
committed
dart2js cps: Add logical rewriter rules to favor null-aware operators.
These useful patterns arise with null-aware operators: x ? y : x ==> x && y x ? x : y ==> x || y BUG= [email protected] Committed: 0e46c8d Review URL: https://codereview.chromium.org//1291073002 .
1 parent 4b80cfd commit d3d7de8

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,17 @@ class LogicalRewriter extends RecursiveTransformer
306306
node.elseExpression = tmp;
307307
}
308308

309+
// x ? y : x ==> x && y
310+
if (isSameVariable(node.condition, node.elseExpression)) {
311+
destroyVariableUse(node.elseExpression);
312+
return new LogicalOperator.and(node.condition, node.thenExpression);
313+
}
314+
// x ? x : y ==> x || y
315+
if (isSameVariable(node.condition, node.thenExpression)) {
316+
destroyVariableUse(node.thenExpression);
317+
return new LogicalOperator.or(node.condition, node.elseExpression);
318+
}
319+
309320
return node;
310321
}
311322

@@ -468,6 +479,18 @@ class LogicalRewriter extends RecursiveTransformer
468479
e.elseExpression = (e.elseExpression as Not).operand;
469480
return new Not(e);
470481
}
482+
483+
// x ? y : x ==> x && y
484+
if (isSameVariable(e.condition, e.elseExpression)) {
485+
destroyVariableUse(e.elseExpression);
486+
return new LogicalOperator.and(e.condition, e.thenExpression);
487+
}
488+
// x ? x : y ==> x || y
489+
if (isSameVariable(e.condition, e.thenExpression)) {
490+
destroyVariableUse(e.thenExpression);
491+
return new LogicalOperator.or(e.condition, e.elseExpression);
492+
}
493+
471494
return e;
472495
}
473496
if (e is Constant && e.value.isBool) {
@@ -509,5 +532,23 @@ class LogicalRewriter extends RecursiveTransformer
509532
return new LogicalOperator.or(e1, e2);
510533
}
511534
}
535+
536+
/// True if [e2] is known to return the same value as [e1]
537+
/// (with no additional side effects) if evaluated immediately after [e1].
538+
///
539+
/// Concretely, this is true if [e1] and [e2] are uses of the same variable,
540+
/// or if [e2] is a use of a variable assigned by [e1].
541+
bool isSameVariable(Expression e1, Expression e2) {
542+
if (e1 is VariableUse) {
543+
return e2 is VariableUse && e1.variable == e2.variable;
544+
} else if (e1 is Assign) {
545+
return e2 is VariableUse && e1.variable == e2.variable;
546+
}
547+
return false;
548+
}
549+
550+
void destroyVariableUse(VariableUse node) {
551+
--node.variable.readCount;
552+
}
512553
}
513554

0 commit comments

Comments
 (0)