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

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

Issue 1284233003: dart2js CPS: Fix a bug in commuting binary operations. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Merge tip of tree. Created 5 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 node = node.next; 380 node = node.next;
381 } 381 }
382 Statement result = visitStatement(node); 382 Statement result = visitStatement(node);
383 for (Function fun in stack.reversed) { 383 for (Function fun in stack.reversed) {
384 result = fun(result); 384 result = fun(result);
385 } 385 }
386 return result; 386 return result;
387 } 387 }
388 388
389 /// Attempts to propagate an assignment in an expression statement. 389 /// Attempts to propagate an assignment in an expression statement.
390 /// 390 ///
391 /// Returns a callback to be invoked after the sucessor statement has 391 /// Returns a callback to be invoked after the sucessor statement has
392 /// been processed. 392 /// been processed.
393 Function processExpressionStatement(ExpressionStatement stmt) { 393 Function processExpressionStatement(ExpressionStatement stmt) {
394 Variable leftHand = getLeftHand(stmt.expression); 394 Variable leftHand = getLeftHand(stmt.expression);
395 pushDominatingAssignment(leftHand); 395 pushDominatingAssignment(leftHand);
396 if (isEffectivelyConstantAssignment(stmt.expression) && 396 if (isEffectivelyConstantAssignment(stmt.expression) &&
397 !usesRecentlyAssignedVariable(stmt.expression)) { 397 !usesRecentlyAssignedVariable(stmt.expression)) {
398 Assign assign = stmt.expression; 398 Assign assign = stmt.expression;
399 // Handle constant assignments specially. 399 // Handle constant assignments specially.
400 // They are always safe to propagate (though we should avoid duplication). 400 // They are always safe to propagate (though we should avoid duplication).
401 // Moreover, they should not prevent other expressions from propagating. 401 // Moreover, they should not prevent other expressions from propagating.
402 if (assign.variable.readCount == 1) { 402 if (assign.variable.readCount == 1) {
403 // A single-use constant should always be propagated to its use site. 403 // A single-use constant should always be propagated to its use site.
404 constantEnvironment[assign.variable] = assign.value; 404 constantEnvironment[assign.variable] = assign.value;
405 return (Statement next) { 405 return (Statement next) {
406 popDominatingAssignment(leftHand); 406 popDominatingAssignment(leftHand);
407 if (assign.variable.readCount > 0) { 407 if (assign.variable.readCount > 0) {
408 // The assignment could not be propagated into the successor, 408 // The assignment could not be propagated into the successor,
409 // either because it [hasUnsafeVariableUse] or because the 409 // either because it [hasUnsafeVariableUse] or because the
410 // use is outside the current try block, and we do not currently 410 // use is outside the current try block, and we do not currently
411 // support constant propagation out of a try block. 411 // support constant propagation out of a try block.
412 constantEnvironment.remove(assign.variable); 412 constantEnvironment.remove(assign.variable);
413 assign.value = visitExpression(assign.value); 413 assign.value = visitExpression(assign.value);
414 stmt.next = next; 414 stmt.next = next;
415 return stmt; 415 return stmt;
416 } else { 416 } else {
417 --assign.variable.writeCount; 417 --assign.variable.writeCount;
418 return next; 418 return next;
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 if (environment.isEmpty || getLeftHand(environment.last) == null) { 834 if (environment.isEmpty || getLeftHand(environment.last) == null) {
835 // If there is no recent assignment that might propagate, so there is no 835 // If there is no recent assignment that might propagate, so there is no
836 // opportunity for optimization here. 836 // opportunity for optimization here.
837 _rewriteList(node.arguments); 837 _rewriteList(node.arguments);
838 return node; 838 return node;
839 } 839 }
840 Variable propagatableVariable = getLeftHand(environment.last); 840 Variable propagatableVariable = getLeftHand(environment.last);
841 BuiltinOperator commuted = commuteBinaryOperator(node.operator); 841 BuiltinOperator commuted = commuteBinaryOperator(node.operator);
842 if (commuted != null) { 842 if (commuted != null) {
843 assert(node.arguments.length == 2); // Only binary operators can commute. 843 assert(node.arguments.length == 2); // Only binary operators can commute.
844 VariableUse arg1 = node.arguments[0]; 844 Expression left = node.arguments[0];
845 VariableUse arg2 = node.arguments[1]; 845 if (left is VariableUse && propagatableVariable == left.variable) {
846 if (propagatableVariable == arg1.variable && 846 Expression right = node.arguments[1];
847 propagatableVariable != arg2.variable && 847 if (right is This ||
848 !constantEnvironment.containsKey(arg2.variable)) { 848 (right is VariableUse &&
849 // An assignment can be propagated if we commute the operator. 849 propagatableVariable != right.variable &&
850 node.operator = commuted; 850 !constantEnvironment.containsKey(right.variable))) {
851 node.arguments[0] = arg2; 851 // An assignment can be propagated if we commute the operator.
852 node.arguments[1] = arg1; 852 node.operator = commuted;
853 node.arguments[0] = right;
854 node.arguments[1] = left;
855 }
853 } 856 }
854 } 857 }
855 _rewriteList(node.arguments); 858 _rewriteList(node.arguments);
856 return node; 859 return node;
857 } 860 }
858 861
859 /// If [s] and [t] are similar statements we extract their subexpressions 862 /// If [s] and [t] are similar statements we extract their subexpressions
860 /// and returns a new statement of the same type using expressions combined 863 /// and returns a new statement of the same type using expressions combined
861 /// with the [combine] callback. For example: 864 /// with the [combine] callback. For example:
862 /// 865 ///
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 VariableUseVisitor(this.callback); 1220 VariableUseVisitor(this.callback);
1218 1221
1219 visitVariableUse(VariableUse use) => callback(use); 1222 visitVariableUse(VariableUse use) => callback(use);
1220 1223
1221 visitInnerFunction(FunctionDefinition node) {} 1224 visitInnerFunction(FunctionDefinition node) {}
1222 1225
1223 static void visit(Expression node, VariableUseCallback callback) { 1226 static void visit(Expression node, VariableUseCallback callback) {
1224 new VariableUseVisitor(callback).visitExpression(node); 1227 new VariableUseVisitor(callback).visitExpression(node);
1225 } 1228 }
1226 } 1229 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698