| 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(),
|
|
|