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.statement_rewriter; | 5 library tree_ir.optimization.statement_rewriter; |
6 | 6 |
7 import 'optimization.dart' show Pass; | 7 import 'optimization.dart' show Pass; |
8 import '../tree_ir_nodes.dart'; | 8 import '../tree_ir_nodes.dart'; |
9 | 9 |
10 /** | 10 /** |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 Expression visitTypeExpression(TypeExpression node) { | 612 Expression visitTypeExpression(TypeExpression node) { |
613 _rewriteList(node.arguments); | 613 _rewriteList(node.arguments); |
614 return node; | 614 return node; |
615 } | 615 } |
616 | 616 |
617 Expression visitCreateInvocationMirror(CreateInvocationMirror node) { | 617 Expression visitCreateInvocationMirror(CreateInvocationMirror node) { |
618 _rewriteList(node.arguments); | 618 _rewriteList(node.arguments); |
619 return node; | 619 return node; |
620 } | 620 } |
621 | 621 |
| 622 /// True if [operator] is a binary operator that always has the same value |
| 623 /// if its arguments are swapped. |
| 624 bool isSymmetricOperator(BuiltinOperator operator) { |
| 625 switch (operator) { |
| 626 case BuiltinOperator.StrictEq: |
| 627 case BuiltinOperator.StrictNeq: |
| 628 case BuiltinOperator.LooseEq: |
| 629 case BuiltinOperator.LooseNeq: |
| 630 case BuiltinOperator.NumAnd: |
| 631 case BuiltinOperator.NumOr: |
| 632 case BuiltinOperator.NumXor: |
| 633 case BuiltinOperator.NumPlus: |
| 634 case BuiltinOperator.NumMultiply: |
| 635 return true; |
| 636 default: |
| 637 return false; |
| 638 } |
| 639 } |
| 640 |
| 641 /// If [operator] is a commutable binary operator, returns the commuted |
| 642 /// operator, possibly the operator itself, otherwise returns `null`. |
| 643 BuiltinOperator commuteBinaryOperator(BuiltinOperator operator) { |
| 644 if (isSymmetricOperator(operator)) { |
| 645 // Symmetric operators are their own commutes. |
| 646 return operator; |
| 647 } |
| 648 switch(operator) { |
| 649 case BuiltinOperator.NumLt: return BuiltinOperator.NumGt; |
| 650 case BuiltinOperator.NumLe: return BuiltinOperator.NumGe; |
| 651 case BuiltinOperator.NumGt: return BuiltinOperator.NumLt; |
| 652 case BuiltinOperator.NumGe: return BuiltinOperator.NumLe; |
| 653 default: return null; |
| 654 } |
| 655 } |
| 656 |
| 657 /// Built-in binary operators are commuted when it is safe and can enable an |
| 658 /// assignment propagation. For example: |
| 659 /// |
| 660 /// var x = foo(); |
| 661 /// var y = bar(); |
| 662 /// var z = y < x; |
| 663 /// |
| 664 /// ==> |
| 665 /// |
| 666 /// var z = foo() > bar(); |
| 667 /// |
| 668 /// foo() must be evaluated before bar(), so the propagation is only possible |
| 669 /// by commuting the operator. |
| 670 Expression visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
| 671 if (environment.isEmpty || getLeftHand(environment.last) == null) { |
| 672 // If there is no recent assignment that might propagate, so there is no |
| 673 // opportunity for optimization here. |
| 674 _rewriteList(node.arguments); |
| 675 return node; |
| 676 } |
| 677 Variable propagatableVariable = getLeftHand(environment.last); |
| 678 BuiltinOperator commuted = commuteBinaryOperator(node.operator); |
| 679 if (commuted != null) { |
| 680 assert(node.arguments.length == 2); // Only binary operators can commute. |
| 681 VariableUse arg1 = node.arguments[0]; |
| 682 VariableUse arg2 = node.arguments[1]; |
| 683 if (propagatableVariable == arg1.variable && |
| 684 propagatableVariable != arg2.variable && |
| 685 !constantEnvironment.containsKey(arg2.variable)) { |
| 686 // An assignment can be propagated if we commute the operator. |
| 687 node.operator = commuted; |
| 688 node.arguments[0] = arg2; |
| 689 node.arguments[1] = arg1; |
| 690 } |
| 691 } |
| 692 _rewriteList(node.arguments); |
| 693 return node; |
| 694 } |
| 695 |
622 /// If [s] and [t] are similar statements we extract their subexpressions | 696 /// If [s] and [t] are similar statements we extract their subexpressions |
623 /// and returns a new statement of the same type using expressions combined | 697 /// and returns a new statement of the same type using expressions combined |
624 /// with the [combine] callback. For example: | 698 /// with the [combine] callback. For example: |
625 /// | 699 /// |
626 /// combineStatements(Return E1, Return E2) = Return combine(E1, E2) | 700 /// combineStatements(Return E1, Return E2) = Return combine(E1, E2) |
627 /// | 701 /// |
628 /// If [combine] returns E1 then the unified statement is equivalent to [s], | 702 /// If [combine] returns E1 then the unified statement is equivalent to [s], |
629 /// and if [combine] returns E2 the unified statement is equivalence to [t]. | 703 /// and if [combine] returns E2 the unified statement is equivalence to [t]. |
630 /// | 704 /// |
631 /// It is guaranteed that no side effects occur between the beginning of the | 705 /// It is guaranteed that no side effects occur between the beginning of the |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 } | 990 } |
917 | 991 |
918 /// Result of combining two expressions that do not affect reference counting. | 992 /// Result of combining two expressions that do not affect reference counting. |
919 class GenericCombinedExpressions implements CombinedExpressions { | 993 class GenericCombinedExpressions implements CombinedExpressions { |
920 Expression combined; | 994 Expression combined; |
921 | 995 |
922 GenericCombinedExpressions(this.combined); | 996 GenericCombinedExpressions(this.combined); |
923 | 997 |
924 void uncombine() {} | 998 void uncombine() {} |
925 } | 999 } |
OLD | NEW |