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 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1566 node.elsePart != null ? () => visit(node.elsePart) : null); | 1566 node.elsePart != null ? () => visit(node.elsePart) : null); |
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 handleLogicalAndOr(node, | 1576 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
1577 () { visit(node.receiver); }, | 1577 branchBuilder.handleLogicalAndOr( |
1578 () { visit(node.argumentsNode); }, | 1578 () { visit(node.receiver); }, |
1579 isAnd: (const SourceString("&&") == op.source)); | 1579 () { visit(node.argumentsNode); }, |
1580 isAnd: (const SourceString("&&") == op.source)); | |
1580 } | 1581 } |
1581 | 1582 |
1582 | 1583 |
1583 void handleLogicalAndOr(Node diagnosticNode, | |
1584 void left(), void right(), [bool isAnd = true]) { | |
1585 // x && y is transformed into: | |
1586 // t0 = boolify(x); | |
1587 // if (t0) { | |
1588 // t1 = boolify(y); | |
1589 // } else { | |
1590 // t2 = t0; | |
1591 // } | |
1592 // result = phi(t1, false); | |
1593 // | |
1594 // x || y is transformed into: | |
1595 // t0 = boolify(x); | |
1596 // if (not(t0)) { | |
1597 // t1 = boolify(y); | |
1598 // } else { | |
1599 // t2 = t0; | |
1600 // } | |
1601 // result = phi(t1, true); | |
1602 HInstruction boolifiedLeft; | |
1603 HInstruction boolifiedRight; | |
1604 | |
1605 void visitCondition() { | |
1606 left(); | |
1607 boolifiedLeft = popBoolified(); | |
1608 HInstruction condition; | |
1609 if (isAnd) { | |
1610 condition = boolifiedLeft; | |
1611 } else { | |
1612 condition = new HNot(boolifiedLeft); | |
1613 add(condition); | |
1614 } | |
1615 stack.add(condition); | |
1616 } | |
1617 | |
1618 void visitThen() { | |
1619 right(); | |
1620 boolifiedRight = popBoolified(); | |
1621 } | |
1622 | |
1623 handleIf(diagnosticNode, visitCondition, visitThen, null); | |
1624 HPhi result = new HPhi.manyInputs(null, | |
1625 <HInstruction>[boolifiedRight, graph.addConstantBool(!isAnd)]); | |
1626 current.addPhi(result); | |
1627 stack.add(result); | |
1628 } | |
1629 | |
1630 void visitLogicalNot(Send node) { | 1584 void visitLogicalNot(Send node) { |
1631 assert(node.argumentsNode is Prefix); | 1585 assert(node.argumentsNode is Prefix); |
1632 visit(node.receiver); | 1586 visit(node.receiver); |
1633 HNot not = new HNot(popBoolified()); | 1587 HNot not = new HNot(popBoolified()); |
1634 push(not); | 1588 push(not); |
1635 } | 1589 } |
1636 | 1590 |
1637 void visitUnary(Send node, Operator op) { | 1591 void visitUnary(Send node, Operator op) { |
1638 assert(node.argumentsNode is Prefix); | 1592 assert(node.argumentsNode is Prefix); |
1639 visit(node.receiver); | 1593 visit(node.receiver); |
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3134 // If this is the last expression, just return it. | 3088 // If this is the last expression, just return it. |
3135 Link<Node> tail = skipLabels(remainingCases.tail); | 3089 Link<Node> tail = skipLabels(remainingCases.tail); |
3136 if (tail.isEmpty()) { | 3090 if (tail.isEmpty()) { |
3137 left(); | 3091 left(); |
3138 return; | 3092 return; |
3139 } | 3093 } |
3140 | 3094 |
3141 void right() { | 3095 void right() { |
3142 buildTests(tail); | 3096 buildTests(tail); |
3143 } | 3097 } |
3144 handleLogicalAndOr(remainingCases.head, left, right, isAnd: false); | 3098 SsaBranchBuilder branchBuilder = |
3099 new SsaBranchBuilder(this, remainingCases.head); | |
3100 branchBuilder.handleLogicalAndOr(left, right, isAnd: false); | |
3145 } | 3101 } |
3146 | 3102 |
3147 if (node.isDefaultCase) { | 3103 if (node.isDefaultCase) { |
3148 // Default case must be last. | 3104 // Default case must be last. |
3149 assert(cases.tail.isEmpty()); | 3105 assert(cases.tail.isEmpty()); |
3150 // Perform the tests until one of them match, but then always execute the | 3106 // Perform the tests until one of them match, but then always execute the |
3151 // statements. | 3107 // statements. |
3152 // TODO(lrn): Stop performing tests when all expressions are compile-time | 3108 // TODO(lrn): Stop performing tests when all expressions are compile-time |
3153 // constant strings or integers. | 3109 // constant strings or integers. |
3154 handleIf(node, () { buildTests(labelsAndCases); }, (){}, null); | 3110 handleIf(node, () { buildTests(labelsAndCases); }, (){}, null); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3493 } | 3449 } |
3494 | 3450 |
3495 _handleDiamondBranch(visitCondition, visitThen, visitElse, false); | 3451 _handleDiamondBranch(visitCondition, visitThen, visitElse, false); |
3496 } | 3452 } |
3497 | 3453 |
3498 handleConditional(void visitCondition(), void visitThen(), void visitElse()) { | 3454 handleConditional(void visitCondition(), void visitThen(), void visitElse()) { |
3499 assert(visitElse != null); | 3455 assert(visitElse != null); |
3500 _handleDiamondBranch(visitCondition, visitThen, visitElse, true); | 3456 _handleDiamondBranch(visitCondition, visitThen, visitElse, true); |
3501 } | 3457 } |
3502 | 3458 |
3459 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) { | |
3460 // x && y is transformed into: | |
3461 // t0 = boolify(x); | |
3462 // if (t0) { | |
3463 // t1 = boolify(y); | |
3464 // } else { | |
3465 // t2 = t0; | |
3466 // } | |
3467 // result = phi(t1, false); | |
3468 // | |
3469 // x || y is transformed into: | |
3470 // t0 = boolify(x); | |
3471 // if (not(t0)) { | |
3472 // t1 = boolify(y); | |
3473 // } else { | |
3474 // t2 = t0; | |
3475 // } | |
3476 // result = phi(t1, true); | |
3477 HInstruction boolifiedLeft; | |
3478 HInstruction boolifiedRight; | |
3479 | |
3480 void visitCondition() { | |
3481 left(); | |
3482 boolifiedLeft = builder.popBoolified(); | |
3483 HInstruction condition; | |
3484 if (isAnd) { | |
3485 condition = boolifiedLeft; | |
3486 } else { | |
3487 condition = new HNot(boolifiedLeft); | |
3488 builder.add(condition); | |
3489 } | |
Lasse Reichstein Nielsen
2012/07/12 07:18:26
Could be shorter by using the stack more:
void vis
floitsch
2012/07/12 09:23:30
Agreed, but in this CL I'm not going to change any
| |
3490 builder.stack.add(condition); | |
3491 } | |
3492 | |
3493 void visitThen() { | |
3494 right(); | |
3495 boolifiedRight = builder.popBoolified(); | |
3496 } | |
3497 | |
3498 handleIf(visitCondition, visitThen, null); | |
3499 HPhi result = new HPhi.manyInputs(null, | |
3500 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]); | |
3501 builder.current.addPhi(result); | |
3502 builder.stack.add(result); | |
3503 } | |
3504 | |
3503 void _handleDiamondBranch(void visitCondition(), | 3505 void _handleDiamondBranch(void visitCondition(), |
3504 void visitThen(), | 3506 void visitThen(), |
3505 void visitElse(), | 3507 void visitElse(), |
3506 bool isExpression) { | 3508 bool isExpression) { |
3507 SsaBranch conditionBranch = new SsaBranch(this); | 3509 SsaBranch conditionBranch = new SsaBranch(this); |
3508 SsaBranch thenBranch = new SsaBranch(this); | 3510 SsaBranch thenBranch = new SsaBranch(this); |
3509 SsaBranch elseBranch = new SsaBranch(this); | 3511 SsaBranch elseBranch = new SsaBranch(this); |
3510 SsaBranch joinBranch = new SsaBranch(this); | 3512 SsaBranch joinBranch = new SsaBranch(this); |
3511 | 3513 |
3512 conditionBranch.startLocals = builder.localsHandler; | 3514 conditionBranch.startLocals = builder.localsHandler; |
(...skipping 29 matching lines...) Expand all Loading... | |
3542 new HSubGraphBlockInformation(elseBranch.graph)); | 3544 new HSubGraphBlockInformation(elseBranch.graph)); |
3543 | 3545 |
3544 HBasicBlock conditionStartBlock = conditionBranch.block; | 3546 HBasicBlock conditionStartBlock = conditionBranch.block; |
3545 conditionStartBlock.setBlockFlow(info, joinBlock); | 3547 conditionStartBlock.setBlockFlow(info, joinBlock); |
3546 SubGraph conditionGraph = conditionBranch.graph; | 3548 SubGraph conditionGraph = conditionBranch.graph; |
3547 HIf branch = conditionGraph.end.last; | 3549 HIf branch = conditionGraph.end.last; |
3548 assert(branch is HIf); | 3550 assert(branch is HIf); |
3549 branch.blockInformation = conditionStartBlock.blockFlow; | 3551 branch.blockInformation = conditionStartBlock.blockFlow; |
3550 } | 3552 } |
3551 } | 3553 } |
OLD | NEW |