@@ -306,6 +306,17 @@ class LogicalRewriter extends RecursiveTransformer
306
306
node.elseExpression = tmp;
307
307
}
308
308
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
+
309
320
return node;
310
321
}
311
322
@@ -468,6 +479,18 @@ class LogicalRewriter extends RecursiveTransformer
468
479
e.elseExpression = (e.elseExpression as Not ).operand;
469
480
return new Not (e);
470
481
}
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
+
471
494
return e;
472
495
}
473
496
if (e is Constant && e.value.isBool) {
@@ -509,5 +532,23 @@ class LogicalRewriter extends RecursiveTransformer
509
532
return new LogicalOperator .or (e1, e2);
510
533
}
511
534
}
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
+ }
512
553
}
513
554
0 commit comments