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

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10696192: Transform (x && y) && z into x && (y && z). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 5 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
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen_helpers.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/ssa/builder.dart
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index a6ca20a4b62ea2a360437c6a89ce52c1cab935d6..8b3b250a3afc3dafd64b0f4639d973dfebf46462 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -1574,8 +1574,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
void visitLogicalAndOr(Send node, Operator op) {
SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
- branchBuilder.handleLogicalAndOr(
- () { visit(node.receiver); },
+ branchBuilder.handleLogicalAndOrWithLeftNode(
+ node.receiver,
() { visit(node.argumentsNode); },
isAnd: (const SourceString("&&") == op.source));
}
@@ -3456,13 +3456,11 @@ class SsaBranchBuilder {
_handleDiamondBranch(visitCondition, visitThen, visitElse, true);
}
- void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) {
+ void handleLogicalAndOr(void left(), void right(), [bool isAnd]) {
// x && y is transformed into:
// t0 = boolify(x);
// if (t0) {
// t1 = boolify(y);
- // } else {
- // t2 = t0;
// }
// result = phi(t1, false);
//
@@ -3470,8 +3468,6 @@ class SsaBranchBuilder {
// t0 = boolify(x);
// if (not(t0)) {
// t1 = boolify(y);
- // } else {
- // t2 = t0;
// }
// result = phi(t1, true);
HInstruction boolifiedLeft;
@@ -3480,14 +3476,10 @@ class SsaBranchBuilder {
void visitCondition() {
left();
boolifiedLeft = builder.popBoolified();
- HInstruction condition;
- if (isAnd) {
- condition = boolifiedLeft;
- } else {
- condition = new HNot(boolifiedLeft);
- builder.add(condition);
+ builder.stack.add(boolifiedLeft);
+ if (!isAnd) {
+ builder.push(new HNot(builder.pop()));
}
- builder.stack.add(condition);
}
void visitThen() {
@@ -3502,6 +3494,39 @@ class SsaBranchBuilder {
builder.stack.add(result);
}
+ void handleLogicalAndOrWithLeftNode(Node left,
+ void visitRight(),
+ [bool isAnd]) {
+ // This method is similar to [handleLogicalAndOr] but optimizes the case
+ // where left is a logical "and" or logical "or".
+ //
+ // For example (x && y) && z is transformed into x && (y && z):
+ // t0 = boolify(x);
+ // if (t0) {
+ // t1 = boolify(y);
+ // if (t1) {
+ // t2 = boolify(z);
+ // }
+ // t3 = phi(t2, false);
+ // }
+ // result = phi(t3, false);
+
+ Send send = left.asSend();
+ if (send !== null &&
+ (isAnd ? send.isLogicalAnd : send.isLogicalOr)) {
+ Node newLeft = send.receiver;
+ Link<Node> link = send.argumentsNode.nodes;
+ assert(link.tail.isEmpty());
+ Node middle = link.head;
+ handleLogicalAndOrWithLeftNode(
+ newLeft,
+ () => handleLogicalAndOrWithLeftNode(middle, visitRight, isAnd),
+ isAnd: isAnd);
+ } else {
+ handleLogicalAndOr(() => builder.visit(left), visitRight, isAnd);
+ }
+ }
+
void _handleDiamondBranch(void visitCondition(),
void visitThen(),
void visitElse(),
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698