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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen_helpers.dart » ('j') | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 } 1567 }
1568 1568
1569 void handleIf(Node diagnosticNode, 1569 void handleIf(Node diagnosticNode,
1570 void visitCondition(), void visitThen(), void visitElse()) { 1570 void visitCondition(), void visitThen(), void visitElse()) {
1571 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode); 1571 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode);
1572 branchBuilder.handleIf(visitCondition, visitThen, visitElse); 1572 branchBuilder.handleIf(visitCondition, visitThen, visitElse);
1573 } 1573 }
1574 1574
1575 void visitLogicalAndOr(Send node, Operator op) { 1575 void visitLogicalAndOr(Send node, Operator op) {
1576 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); 1576 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
1577 branchBuilder.handleLogicalAndOr( 1577 branchBuilder.handleLogicalAndOrWithLeftNode(
1578 () { visit(node.receiver); }, 1578 node.receiver,
1579 () { visit(node.argumentsNode); }, 1579 () { visit(node.argumentsNode); },
1580 isAnd: (const SourceString("&&") == op.source)); 1580 isAnd: (const SourceString("&&") == op.source));
1581 } 1581 }
1582 1582
1583 1583
1584 void visitLogicalNot(Send node) { 1584 void visitLogicalNot(Send node) {
1585 assert(node.argumentsNode is Prefix); 1585 assert(node.argumentsNode is Prefix);
1586 visit(node.receiver); 1586 visit(node.receiver);
1587 HNot not = new HNot(popBoolified()); 1587 HNot not = new HNot(popBoolified());
1588 push(not); 1588 push(not);
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 } 3449 }
3450 3450
3451 _handleDiamondBranch(visitCondition, visitThen, visitElse, false); 3451 _handleDiamondBranch(visitCondition, visitThen, visitElse, false);
3452 } 3452 }
3453 3453
3454 handleConditional(void visitCondition(), void visitThen(), void visitElse()) { 3454 handleConditional(void visitCondition(), void visitThen(), void visitElse()) {
3455 assert(visitElse != null); 3455 assert(visitElse != null);
3456 _handleDiamondBranch(visitCondition, visitThen, visitElse, true); 3456 _handleDiamondBranch(visitCondition, visitThen, visitElse, true);
3457 } 3457 }
3458 3458
3459 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { 3459 void handleLogicalAndOr(void left(), void right(), [bool isAnd]) {
3460 // x && y is transformed into: 3460 // x && y is transformed into:
3461 // t0 = boolify(x); 3461 // t0 = boolify(x);
3462 // if (t0) { 3462 // if (t0) {
3463 // t1 = boolify(y); 3463 // t1 = boolify(y);
3464 // } else {
3465 // t2 = t0;
3466 // } 3464 // }
3467 // result = phi(t1, false); 3465 // result = phi(t1, false);
3468 // 3466 //
3469 // x || y is transformed into: 3467 // x || y is transformed into:
3470 // t0 = boolify(x); 3468 // t0 = boolify(x);
3471 // if (not(t0)) { 3469 // if (not(t0)) {
3472 // t1 = boolify(y); 3470 // t1 = boolify(y);
3473 // } else {
3474 // t2 = t0;
3475 // } 3471 // }
3476 // result = phi(t1, true); 3472 // result = phi(t1, true);
3477 HInstruction boolifiedLeft; 3473 HInstruction boolifiedLeft;
3478 HInstruction boolifiedRight; 3474 HInstruction boolifiedRight;
3479 3475
3480 void visitCondition() { 3476 void visitCondition() {
3481 left(); 3477 left();
3482 boolifiedLeft = builder.popBoolified(); 3478 boolifiedLeft = builder.popBoolified();
3483 HInstruction condition; 3479 builder.stack.add(boolifiedLeft);
3484 if (isAnd) { 3480 if (!isAnd) {
3485 condition = boolifiedLeft; 3481 builder.push(new HNot(builder.pop()));
3486 } else {
3487 condition = new HNot(boolifiedLeft);
3488 builder.add(condition);
3489 } 3482 }
3490 builder.stack.add(condition);
3491 } 3483 }
3492 3484
3493 void visitThen() { 3485 void visitThen() {
3494 right(); 3486 right();
3495 boolifiedRight = builder.popBoolified(); 3487 boolifiedRight = builder.popBoolified();
3496 } 3488 }
3497 3489
3498 handleIf(visitCondition, visitThen, null); 3490 handleIf(visitCondition, visitThen, null);
3499 HPhi result = new HPhi.manyInputs(null, 3491 HPhi result = new HPhi.manyInputs(null,
3500 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]); 3492 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]);
3501 builder.current.addPhi(result); 3493 builder.current.addPhi(result);
3502 builder.stack.add(result); 3494 builder.stack.add(result);
3503 } 3495 }
3504 3496
3497 void handleLogicalAndOrWithLeftNode(Node left,
3498 void visitRight(),
3499 [bool isAnd]) {
3500 // This method is similar to [handleLogicalAndOr] but optimizes the case
3501 // where left is a logical "and" or logical "or".
3502 //
3503 // For example (x && y) && z is transformed into x && (y && z):
3504 // t0 = boolify(x);
3505 // if (t0) {
3506 // t1 = boolify(y);
3507 // if (t1) {
3508 // t2 = boolify(z);
3509 // }
3510 // t3 = phi(t2, false);
3511 // }
3512 // result = phi(t3, false);
3513
3514 Send send = left.asSend();
3515 if (send !== null &&
3516 (isAnd ? send.isLogicalAnd : send.isLogicalOr)) {
3517 Node newLeft = send.receiver;
3518 Link<Node> link = send.argumentsNode.nodes;
3519 assert(link.tail.isEmpty());
3520 Node middle = link.head;
3521 handleLogicalAndOrWithLeftNode(
3522 newLeft,
3523 () => handleLogicalAndOrWithLeftNode(middle, visitRight, isAnd),
3524 isAnd: isAnd);
3525 } else {
3526 handleLogicalAndOr(() => builder.visit(left), visitRight, isAnd);
3527 }
3528 }
3529
3505 void _handleDiamondBranch(void visitCondition(), 3530 void _handleDiamondBranch(void visitCondition(),
3506 void visitThen(), 3531 void visitThen(),
3507 void visitElse(), 3532 void visitElse(),
3508 bool isExpression) { 3533 bool isExpression) {
3509 SsaBranch conditionBranch = new SsaBranch(this); 3534 SsaBranch conditionBranch = new SsaBranch(this);
3510 SsaBranch thenBranch = new SsaBranch(this); 3535 SsaBranch thenBranch = new SsaBranch(this);
3511 SsaBranch elseBranch = new SsaBranch(this); 3536 SsaBranch elseBranch = new SsaBranch(this);
3512 SsaBranch joinBranch = new SsaBranch(this); 3537 SsaBranch joinBranch = new SsaBranch(this);
3513 3538
3514 conditionBranch.startLocals = builder.localsHandler; 3539 conditionBranch.startLocals = builder.localsHandler;
(...skipping 29 matching lines...) Expand all
3544 new HSubGraphBlockInformation(elseBranch.graph)); 3569 new HSubGraphBlockInformation(elseBranch.graph));
3545 3570
3546 HBasicBlock conditionStartBlock = conditionBranch.block; 3571 HBasicBlock conditionStartBlock = conditionBranch.block;
3547 conditionStartBlock.setBlockFlow(info, joinBlock); 3572 conditionStartBlock.setBlockFlow(info, joinBlock);
3548 SubGraph conditionGraph = conditionBranch.graph; 3573 SubGraph conditionGraph = conditionBranch.graph;
3549 HIf branch = conditionGraph.end.last; 3574 HIf branch = conditionGraph.end.last;
3550 assert(branch is HIf); 3575 assert(branch is HIf);
3551 branch.blockInformation = conditionStartBlock.blockFlow; 3576 branch.blockInformation = conditionStartBlock.blockFlow;
3552 } 3577 }
3553 } 3578 }
OLDNEW
« 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