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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 1c96301711577753d98346431fcc4e8fb7d3cc06..80ffa43c9cf5d24f8718e494abefa67be34142b9 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -752,16 +752,26 @@ class StatementRewriter extends Transformer implements Pass {
return node;
}
- bool sameVariable(Expression e1, Expression e2) {
- return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
- }
-
bool isCompoundableBuiltin(Expression e) {
return e is ApplyBuiltinOperator &&
- e.arguments.length == 2 &&
+ e.arguments.length >= 2 &&
isCompoundableOperator(e.operator);
}
+ /// Converts a compoundable operator application into the right-hand side for
+ /// use in a compound assignment, discarding the left-hand value.
+ ///
+ /// For example, for `x + y + z` it returns `y + z`.
+ Expression contractCompoundableBuiltin(ApplyBuiltinOperator e) {
+ assert(isCompoundableBuiltin(e));
+ if (e.arguments.length > 2) {
+ assert(e.operator == BuiltinOperator.StringConcatenate);
+ return new ApplyBuiltinOperator(e.operator, e.arguments.skip(1).toList());
+ } else {
+ return e.arguments[1];
+ }
+ }
+
void destroyVariableUse(VariableUse node) {
--node.variable.readCount;
}
@@ -772,13 +782,12 @@ class StatementRewriter extends Transformer implements Pass {
if (isCompoundableBuiltin(node.value)) {
ApplyBuiltinOperator rhs = node.value;
Expression left = rhs.arguments[0];
- Expression right = rhs.arguments[1];
if (left is GetField &&
left.field == node.field &&
- sameVariable(left.object, node.object)) {
- destroyVariableUse(left.object);
+ samePrimary(left.object, node.object)) {
+ destroyPrimaryExpression(left.object);
node.compound = rhs.operator;
- node.value = right;
+ node.value = contractCompoundableBuiltin(rhs);
}
}
node.object = visitExpression(node.object);
@@ -798,6 +807,16 @@ class StatementRewriter extends Transformer implements Pass {
Expression visitSetStatic(SetStatic node) {
allowRhsPropagation.add(true);
node.value = visitExpression(node.value);
+ if (isCompoundableBuiltin(node.value)) {
+ ApplyBuiltinOperator rhs = node.value;
+ Expression left = rhs.arguments[0];
+ if (left is GetStatic &&
+ left.element == node.element &&
+ !left.useLazyGetter) {
+ node.compound = rhs.operator;
+ node.value = contractCompoundableBuiltin(rhs);
+ }
+ }
allowRhsPropagation.removeLast();
return node;
}
@@ -857,14 +876,13 @@ class StatementRewriter extends Transformer implements Pass {
if (isCompoundableBuiltin(node.value)) {
ApplyBuiltinOperator rhs = node.value;
Expression left = rhs.arguments[0];
- Expression right = rhs.arguments[1];
if (left is GetIndex &&
- sameVariable(left.object, node.object) &&
- sameVariable(left.index, node.index)) {
- destroyVariableUse(left.object);
- destroyVariableUse(left.index);
+ samePrimary(left.object, node.object) &&
+ samePrimary(left.index, node.index)) {
+ destroyPrimaryExpression(left.object);
+ destroyPrimaryExpression(left.index);
node.compound = rhs.operator;
- node.value = right;
+ node.value = contractCompoundableBuiltin(rhs);
}
}
node.index = visitExpression(node.index);
@@ -1356,3 +1374,22 @@ class VariableUseVisitor extends RecursiveVisitor {
new VariableUseVisitor(callback).visitExpression(node);
}
}
+
+bool sameVariable(Expression e1, Expression e2) {
+ return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
+}
+
+/// True if [e1] and [e2] are primary expressions (expressions without
+/// subexpressions) with the same value.
+bool samePrimary(Expression e1, Expression e2) {
+ return sameVariable(e1, e2) || (e1 is This && e2 is This);
+}
+
+/// Decrement the reference count for [e] if it is a variable use.
+void destroyPrimaryExpression(Expression e) {
+ if (e is VariableUse) {
+ --e.variable.readCount;
+ } else {
+ assert(e is This);
+ }
+}
« 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