OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |