Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart

Issue 1613853003: dart2js cps: More rewritings for compound assignments. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove a helper method from the conditionals patch Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 import '../../io/source_information.dart'; 9 import '../../io/source_information.dart';
10 import '../../elements/elements.dart'; 10 import '../../elements/elements.dart';
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } 745 }
746 return node; 746 return node;
747 } 747 }
748 748
749 Expression visitTypeOperator(TypeOperator node) { 749 Expression visitTypeOperator(TypeOperator node) {
750 _rewriteList(node.typeArguments); 750 _rewriteList(node.typeArguments);
751 node.value = visitExpression(node.value); 751 node.value = visitExpression(node.value);
752 return node; 752 return node;
753 } 753 }
754 754
755 bool sameVariable(Expression e1, Expression e2) {
756 return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
757 }
758
759 bool isCompoundableBuiltin(Expression e) { 755 bool isCompoundableBuiltin(Expression e) {
760 return e is ApplyBuiltinOperator && 756 return e is ApplyBuiltinOperator &&
761 e.arguments.length == 2 && 757 e.arguments.length >= 2 &&
762 isCompoundableOperator(e.operator); 758 isCompoundableOperator(e.operator);
763 } 759 }
764 760
761 /// Converts a compoundable operator application into the right-hand side for
762 /// use in a compound assignment, discarding the left-hand value.
763 ///
764 /// For example, for `x + y + z` it returns `y + z`.
765 Expression contractCompoundableBuiltin(ApplyBuiltinOperator e) {
766 assert(isCompoundableBuiltin(e));
767 if (e.arguments.length > 2) {
768 assert(e.operator == BuiltinOperator.StringConcatenate);
769 return new ApplyBuiltinOperator(e.operator, e.arguments.skip(1).toList());
770 } else {
771 return e.arguments[1];
772 }
773 }
774
765 void destroyVariableUse(VariableUse node) { 775 void destroyVariableUse(VariableUse node) {
766 --node.variable.readCount; 776 --node.variable.readCount;
767 } 777 }
768 778
769 Expression visitSetField(SetField node) { 779 Expression visitSetField(SetField node) {
770 allowRhsPropagation.add(true); 780 allowRhsPropagation.add(true);
771 node.value = visitExpression(node.value); 781 node.value = visitExpression(node.value);
772 if (isCompoundableBuiltin(node.value)) { 782 if (isCompoundableBuiltin(node.value)) {
773 ApplyBuiltinOperator rhs = node.value; 783 ApplyBuiltinOperator rhs = node.value;
774 Expression left = rhs.arguments[0]; 784 Expression left = rhs.arguments[0];
775 Expression right = rhs.arguments[1];
776 if (left is GetField && 785 if (left is GetField &&
777 left.field == node.field && 786 left.field == node.field &&
778 sameVariable(left.object, node.object)) { 787 samePrimary(left.object, node.object)) {
779 destroyVariableUse(left.object); 788 destroyPrimaryExpression(left.object);
780 node.compound = rhs.operator; 789 node.compound = rhs.operator;
781 node.value = right; 790 node.value = contractCompoundableBuiltin(rhs);
782 } 791 }
783 } 792 }
784 node.object = visitExpression(node.object); 793 node.object = visitExpression(node.object);
785 allowRhsPropagation.removeLast(); 794 allowRhsPropagation.removeLast();
786 return node; 795 return node;
787 } 796 }
788 797
789 Expression visitGetField(GetField node) { 798 Expression visitGetField(GetField node) {
790 node.object = visitExpression(node.object); 799 node.object = visitExpression(node.object);
791 return node; 800 return node;
792 } 801 }
793 802
794 Expression visitGetStatic(GetStatic node) { 803 Expression visitGetStatic(GetStatic node) {
795 return node; 804 return node;
796 } 805 }
797 806
798 Expression visitSetStatic(SetStatic node) { 807 Expression visitSetStatic(SetStatic node) {
799 allowRhsPropagation.add(true); 808 allowRhsPropagation.add(true);
800 node.value = visitExpression(node.value); 809 node.value = visitExpression(node.value);
810 if (isCompoundableBuiltin(node.value)) {
811 ApplyBuiltinOperator rhs = node.value;
812 Expression left = rhs.arguments[0];
813 if (left is GetStatic &&
814 left.element == node.element &&
815 !left.useLazyGetter) {
816 node.compound = rhs.operator;
817 node.value = contractCompoundableBuiltin(rhs);
818 }
819 }
801 allowRhsPropagation.removeLast(); 820 allowRhsPropagation.removeLast();
802 return node; 821 return node;
803 } 822 }
804 823
805 Expression visitGetTypeTestProperty(GetTypeTestProperty node) { 824 Expression visitGetTypeTestProperty(GetTypeTestProperty node) {
806 node.object = visitExpression(node.object); 825 node.object = visitExpression(node.object);
807 return node; 826 return node;
808 } 827 }
809 828
810 Expression visitCreateBox(CreateBox node) { 829 Expression visitCreateBox(CreateBox node) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 node.index = visitExpression(node.index); 869 node.index = visitExpression(node.index);
851 node.object = visitExpression(node.object); 870 node.object = visitExpression(node.object);
852 return node; 871 return node;
853 } 872 }
854 873
855 Expression visitSetIndex(SetIndex node) { 874 Expression visitSetIndex(SetIndex node) {
856 node.value = visitExpression(node.value); 875 node.value = visitExpression(node.value);
857 if (isCompoundableBuiltin(node.value)) { 876 if (isCompoundableBuiltin(node.value)) {
858 ApplyBuiltinOperator rhs = node.value; 877 ApplyBuiltinOperator rhs = node.value;
859 Expression left = rhs.arguments[0]; 878 Expression left = rhs.arguments[0];
860 Expression right = rhs.arguments[1];
861 if (left is GetIndex && 879 if (left is GetIndex &&
862 sameVariable(left.object, node.object) && 880 samePrimary(left.object, node.object) &&
863 sameVariable(left.index, node.index)) { 881 samePrimary(left.index, node.index)) {
864 destroyVariableUse(left.object); 882 destroyPrimaryExpression(left.object);
865 destroyVariableUse(left.index); 883 destroyPrimaryExpression(left.index);
866 node.compound = rhs.operator; 884 node.compound = rhs.operator;
867 node.value = right; 885 node.value = contractCompoundableBuiltin(rhs);
868 } 886 }
869 } 887 }
870 node.index = visitExpression(node.index); 888 node.index = visitExpression(node.index);
871 node.object = visitExpression(node.object); 889 node.object = visitExpression(node.object);
872 return node; 890 return node;
873 } 891 }
874 892
875 /// True if [operator] is a binary operator that always has the same value 893 /// True if [operator] is a binary operator that always has the same value
876 /// if its arguments are swapped. 894 /// if its arguments are swapped.
877 bool isSymmetricOperator(BuiltinOperator operator) { 895 bool isSymmetricOperator(BuiltinOperator operator) {
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 VariableUseCallback callback; 1367 VariableUseCallback callback;
1350 1368
1351 VariableUseVisitor(this.callback); 1369 VariableUseVisitor(this.callback);
1352 1370
1353 visitVariableUse(VariableUse use) => callback(use); 1371 visitVariableUse(VariableUse use) => callback(use);
1354 1372
1355 static void visit(Expression node, VariableUseCallback callback) { 1373 static void visit(Expression node, VariableUseCallback callback) {
1356 new VariableUseVisitor(callback).visitExpression(node); 1374 new VariableUseVisitor(callback).visitExpression(node);
1357 } 1375 }
1358 } 1376 }
1377
1378 bool sameVariable(Expression e1, Expression e2) {
1379 return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
1380 }
1381
1382 /// True if [e1] and [e2] are primary expressions (expressions without
1383 /// subexpressions) with the same value.
1384 bool samePrimary(Expression e1, Expression e2) {
1385 return sameVariable(e1, e2) || (e1 is This && e2 is This);
1386 }
1387
1388 /// Decrement the reference count for [e] if it is a variable use.
1389 void destroyPrimaryExpression(Expression e) {
1390 if (e is VariableUse) {
1391 --e.variable.readCount;
1392 } else {
1393 assert(e is This);
1394 }
1395 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/codegen.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698