| 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 |