OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library tree_ir.optimization.logical_rewriter; | 5 library tree_ir.optimization.logical_rewriter; |
6 | 6 |
7 import '../tree_ir_nodes.dart'; | 7 import '../tree_ir_nodes.dart'; |
8 import 'optimization.dart' show Pass; | 8 import 'optimization.dart' show Pass; |
9 import '../../constants/values.dart' as values; | 9 import '../../constants/values.dart' as values; |
10 | 10 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 node.condition = makeCondition(node.condition, true); | 299 node.condition = makeCondition(node.condition, true); |
300 | 300 |
301 // !x ? y : z ==> x ? z : y | 301 // !x ? y : z ==> x ? z : y |
302 if (node.condition is Not) { | 302 if (node.condition is Not) { |
303 node.condition = (node.condition as Not).operand; | 303 node.condition = (node.condition as Not).operand; |
304 Expression tmp = node.thenExpression; | 304 Expression tmp = node.thenExpression; |
305 node.thenExpression = node.elseExpression; | 305 node.thenExpression = node.elseExpression; |
306 node.elseExpression = tmp; | 306 node.elseExpression = tmp; |
307 } | 307 } |
308 | 308 |
309 // x ? y : x ==> x && y | |
310 if (isSameVariable(node.condition, node.elseExpression)) { | |
311 return new LogicalOperator.and(node.condition, node.thenExpression); | |
312 } | |
313 // x ? x : y ==> x || y | |
314 if (isSameVariable(node.condition, node.thenExpression)) { | |
315 return new LogicalOperator.or(node.condition, node.elseExpression); | |
316 } | |
317 | |
318 return node; | 309 return node; |
319 } | 310 } |
320 | 311 |
321 Expression visitLogicalOperator(LogicalOperator node) { | 312 Expression visitLogicalOperator(LogicalOperator node) { |
322 node.left = visitExpression(node.left); | 313 node.left = visitExpression(node.left); |
323 node.right = visitExpression(node.right); | 314 node.right = visitExpression(node.right); |
324 return node; | 315 return node; |
325 } | 316 } |
326 | 317 |
327 /// True if the given expression is known to evaluate to a boolean. | 318 /// True if the given expression is known to evaluate to a boolean. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 Expression tmp = e.thenExpression; | 461 Expression tmp = e.thenExpression; |
471 e.thenExpression = e.elseExpression; | 462 e.thenExpression = e.elseExpression; |
472 e.elseExpression = tmp; | 463 e.elseExpression = tmp; |
473 } | 464 } |
474 // x ? !y : !z ==> !(x ? y : z) (only if lifting nots) | 465 // x ? !y : !z ==> !(x ? y : z) (only if lifting nots) |
475 if (e.thenExpression is Not && e.elseExpression is Not && liftNots) { | 466 if (e.thenExpression is Not && e.elseExpression is Not && liftNots) { |
476 e.thenExpression = (e.thenExpression as Not).operand; | 467 e.thenExpression = (e.thenExpression as Not).operand; |
477 e.elseExpression = (e.elseExpression as Not).operand; | 468 e.elseExpression = (e.elseExpression as Not).operand; |
478 return new Not(e); | 469 return new Not(e); |
479 } | 470 } |
480 | |
481 // x ? y : x ==> x && y | |
482 if (isSameVariable(e.condition, e.elseExpression)) { | |
483 return new LogicalOperator.and(e.condition, e.thenExpression); | |
484 } | |
485 // x ? x : y ==> x || y | |
486 if (isSameVariable(e.condition, e.thenExpression)) { | |
487 return new LogicalOperator.or(e.condition, e.elseExpression); | |
488 } | |
489 | |
490 return e; | 471 return e; |
491 } | 472 } |
492 if (e is Constant && e.value.isBool) { | 473 if (e is Constant && e.value.isBool) { |
493 // !true ==> false | 474 // !true ==> false |
494 if (!polarity) { | 475 if (!polarity) { |
495 values.BoolConstantValue value = e.value; | 476 values.BoolConstantValue value = e.value; |
496 return new Constant.bool(value.negate()); | 477 return new Constant.bool(value.negate()); |
497 } | 478 } |
498 return e; | 479 return e; |
499 } | 480 } |
(...skipping 21 matching lines...) Expand all Loading... |
521 } | 502 } |
522 } | 503 } |
523 | 504 |
524 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) { | 505 Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) { |
525 if (e1 is Not && e2 is Not && liftNots) { | 506 if (e1 is Not && e2 is Not && liftNots) { |
526 return new Not(new LogicalOperator.and(e1.operand, e2.operand)); | 507 return new Not(new LogicalOperator.and(e1.operand, e2.operand)); |
527 } else { | 508 } else { |
528 return new LogicalOperator.or(e1, e2); | 509 return new LogicalOperator.or(e1, e2); |
529 } | 510 } |
530 } | 511 } |
531 | |
532 /// True if [e2] is known to return the same value as [e1] | |
533 /// (with no additional side effects) if evaluated immediately after [e1]. | |
534 /// | |
535 /// Concretely, this is true if [e1] and [e2] are uses of the same variable, | |
536 /// or if [e2] is a use of a variable assigned by [e1]. | |
537 bool isSameVariable(Expression e1, Expression e2) { | |
538 if (e1 is VariableUse) { | |
539 return e2 is VariableUse && e1.variable == e2.variable; | |
540 } else if (e1 is Assign) { | |
541 return e2 is VariableUse && e1.variable == e2.variable; | |
542 } | |
543 return false; | |
544 } | |
545 } | 512 } |
546 | 513 |
OLD | NEW |