| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class HVisitor<R> { | 7 abstract class HVisitor<R> { |
| 8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
| 9 R visitBailoutTarget(HBailoutTarget node); | 9 R visitBailoutTarget(HBailoutTarget node); |
| 10 R visitBitAnd(HBitAnd node); | 10 R visitBitAnd(HBitAnd node); |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 bool isPrimitive() => instructionType.isPrimitive(); | 896 bool isPrimitive() => instructionType.isPrimitive(); |
| 897 bool canBeNull() => instructionType.canBeNull(); | 897 bool canBeNull() => instructionType.canBeNull(); |
| 898 bool canBePrimitive(Compiler compiler) => | 898 bool canBePrimitive(Compiler compiler) => |
| 899 instructionType.canBePrimitive(compiler); | 899 instructionType.canBePrimitive(compiler); |
| 900 | 900 |
| 901 /** | 901 /** |
| 902 * Type of the unstruction. | 902 * Type of the unstruction. |
| 903 */ | 903 */ |
| 904 HType instructionType = HType.UNKNOWN; | 904 HType instructionType = HType.UNKNOWN; |
| 905 | 905 |
| 906 Selector get selector => null; |
| 907 HInstruction getDartReceiver(Compiler compiler) => null; |
| 908 |
| 906 bool isInBasicBlock() => block != null; | 909 bool isInBasicBlock() => block != null; |
| 907 | 910 |
| 908 String inputsToString() { | 911 String inputsToString() { |
| 909 void addAsCommaSeparated(StringBuffer buffer, List<HInstruction> list) { | 912 void addAsCommaSeparated(StringBuffer buffer, List<HInstruction> list) { |
| 910 for (int i = 0; i < list.length; i++) { | 913 for (int i = 0; i < list.length; i++) { |
| 911 if (i != 0) buffer.write(', '); | 914 if (i != 0) buffer.write(', '); |
| 912 buffer.write("@${list[i].id}"); | 915 buffer.write("@${list[i].id}"); |
| 913 } | 916 } |
| 914 } | 917 } |
| 915 | 918 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 users.remove(current); | 1064 users.remove(current); |
| 1062 if (--usersInCurrentBlock == 0) break; | 1065 if (--usersInCurrentBlock == 0) break; |
| 1063 } | 1066 } |
| 1064 current = current.next; | 1067 current = current.next; |
| 1065 } | 1068 } |
| 1066 } | 1069 } |
| 1067 | 1070 |
| 1068 return users; | 1071 return users; |
| 1069 } | 1072 } |
| 1070 | 1073 |
| 1074 void replaceAllUsersDominatedBy(HInstruction cursor, |
| 1075 HInstruction newInstruction) { |
| 1076 Set<HInstruction> users = dominatedUsers(cursor); |
| 1077 for (HInstruction user in users) { |
| 1078 user.changeUse(this, newInstruction); |
| 1079 } |
| 1080 } |
| 1081 |
| 1071 void moveBefore(HInstruction other) { | 1082 void moveBefore(HInstruction other) { |
| 1072 assert(this is !HControlFlow); | 1083 assert(this is !HControlFlow); |
| 1073 assert(this is !HPhi); | 1084 assert(this is !HPhi); |
| 1074 assert(other is !HPhi); | 1085 assert(other is !HPhi); |
| 1075 block.detach(this); | 1086 block.detach(this); |
| 1076 other.block.internalAddBefore(other, this); | 1087 other.block.internalAddBefore(other, this); |
| 1077 block = other.block; | 1088 block = other.block; |
| 1078 } | 1089 } |
| 1079 | 1090 |
| 1080 bool isConstant() => false; | 1091 bool isConstant() => false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 return new HTypeConversion(type, kind, HType.UNKNOWN, this); | 1139 return new HTypeConversion(type, kind, HType.UNKNOWN, this); |
| 1129 } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) { | 1140 } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) { |
| 1130 // Boolean conversion checks work on non-nullable booleans. | 1141 // Boolean conversion checks work on non-nullable booleans. |
| 1131 return new HTypeConversion(type, kind, HType.BOOLEAN, this); | 1142 return new HTypeConversion(type, kind, HType.BOOLEAN, this); |
| 1132 } else { | 1143 } else { |
| 1133 HType subtype = new HType.subtype(type, compiler); | 1144 HType subtype = new HType.subtype(type, compiler); |
| 1134 return new HTypeConversion(type, kind, subtype, this); | 1145 return new HTypeConversion(type, kind, subtype, this); |
| 1135 } | 1146 } |
| 1136 } | 1147 } |
| 1137 | 1148 |
| 1138 /** | 1149 /** |
| 1139 * Return whether the instructions do not belong to a loop or | 1150 * Return whether the instructions do not belong to a loop or |
| 1140 * belong to the same loop. | 1151 * belong to the same loop. |
| 1141 */ | 1152 */ |
| 1142 bool hasSameLoopHeaderAs(HInstruction other) { | 1153 bool hasSameLoopHeaderAs(HInstruction other) { |
| 1143 return block.enclosingLoopHeader == other.block.enclosingLoopHeader; | 1154 return block.enclosingLoopHeader == other.block.enclosingLoopHeader; |
| 1144 } | 1155 } |
| 1145 } | 1156 } |
| 1146 | 1157 |
| 1147 class HBoolify extends HInstruction { | 1158 class HBoolify extends HInstruction { |
| 1148 HBoolify(HInstruction value) : super(<HInstruction>[value]) { | 1159 HBoolify(HInstruction value) : super(<HInstruction>[value]) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 isEnabled = false; | 1231 isEnabled = false; |
| 1221 instructionType = guarded.instructionType; | 1232 instructionType = guarded.instructionType; |
| 1222 } | 1233 } |
| 1223 | 1234 |
| 1224 bool isControlFlow() => true; | 1235 bool isControlFlow() => true; |
| 1225 bool isJsStatement() => isEnabled; | 1236 bool isJsStatement() => isEnabled; |
| 1226 bool canThrow() => isEnabled; | 1237 bool canThrow() => isEnabled; |
| 1227 | 1238 |
| 1228 // A [HTypeGuard] cannot be moved anywhere in the graph, otherwise | 1239 // A [HTypeGuard] cannot be moved anywhere in the graph, otherwise |
| 1229 // instructions that have side effects could end up before the guard | 1240 // instructions that have side effects could end up before the guard |
| 1230 // in the otpimized version, and after the guard in a bailout | 1241 // in the optimized version, and after the guard in a bailout |
| 1231 // version. | 1242 // version. |
| 1232 bool isPure() => false; | 1243 bool isPure() => false; |
| 1233 | 1244 |
| 1234 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1245 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1235 int typeCode() => HInstruction.TYPE_GUARD_TYPECODE; | 1246 int typeCode() => HInstruction.TYPE_GUARD_TYPECODE; |
| 1236 bool typeEquals(other) => other is HTypeGuard; | 1247 bool typeEquals(other) => other is HTypeGuard; |
| 1237 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; | 1248 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 1238 } | 1249 } |
| 1239 | 1250 |
| 1240 class HBoundsCheck extends HCheck { | 1251 class HBoundsCheck extends HCheck { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1558 } | 1569 } |
| 1559 | 1570 |
| 1560 class HForeignNew extends HForeign { | 1571 class HForeignNew extends HForeign { |
| 1561 ClassElement element; | 1572 ClassElement element; |
| 1562 HForeignNew(this.element, HType type, List<HInstruction> inputs) | 1573 HForeignNew(this.element, HType type, List<HInstruction> inputs) |
| 1563 : super(const LiteralDartString("new"), type, inputs); | 1574 : super(const LiteralDartString("new"), type, inputs); |
| 1564 accept(HVisitor visitor) => visitor.visitForeignNew(this); | 1575 accept(HVisitor visitor) => visitor.visitForeignNew(this); |
| 1565 } | 1576 } |
| 1566 | 1577 |
| 1567 abstract class HInvokeBinary extends HInstruction { | 1578 abstract class HInvokeBinary extends HInstruction { |
| 1568 HInvokeBinary(HInstruction left, HInstruction right) | 1579 final Selector selector; |
| 1580 HInvokeBinary(HInstruction left, HInstruction right, this.selector) |
| 1569 : super(<HInstruction>[left, right]) { | 1581 : super(<HInstruction>[left, right]) { |
| 1570 clearAllSideEffects(); | 1582 clearAllSideEffects(); |
| 1571 setUseGvn(); | 1583 setUseGvn(); |
| 1572 } | 1584 } |
| 1573 | 1585 |
| 1574 HInstruction get left => inputs[0]; | 1586 HInstruction get left => inputs[0]; |
| 1575 HInstruction get right => inputs[1]; | 1587 HInstruction get right => inputs[1]; |
| 1576 | 1588 |
| 1577 BinaryOperation operation(ConstantSystem constantSystem); | 1589 BinaryOperation operation(ConstantSystem constantSystem); |
| 1578 } | 1590 } |
| 1579 | 1591 |
| 1580 abstract class HBinaryArithmetic extends HInvokeBinary { | 1592 abstract class HBinaryArithmetic extends HInvokeBinary { |
| 1581 HBinaryArithmetic(HInstruction left, HInstruction right) : super(left, right); | 1593 HBinaryArithmetic(left, right, selector) : super(left, right, selector); |
| 1582 BinaryOperation operation(ConstantSystem constantSystem); | 1594 BinaryOperation operation(ConstantSystem constantSystem); |
| 1583 } | 1595 } |
| 1584 | 1596 |
| 1585 class HAdd extends HBinaryArithmetic { | 1597 class HAdd extends HBinaryArithmetic { |
| 1586 HAdd(HInstruction left, HInstruction right) : super(left, right); | 1598 HAdd(left, right, selector) : super(left, right, selector); |
| 1587 accept(HVisitor visitor) => visitor.visitAdd(this); | 1599 accept(HVisitor visitor) => visitor.visitAdd(this); |
| 1588 | 1600 |
| 1589 BinaryOperation operation(ConstantSystem constantSystem) | 1601 BinaryOperation operation(ConstantSystem constantSystem) |
| 1590 => constantSystem.add; | 1602 => constantSystem.add; |
| 1591 int typeCode() => HInstruction.ADD_TYPECODE; | 1603 int typeCode() => HInstruction.ADD_TYPECODE; |
| 1592 bool typeEquals(other) => other is HAdd; | 1604 bool typeEquals(other) => other is HAdd; |
| 1593 bool dataEquals(HInstruction other) => true; | 1605 bool dataEquals(HInstruction other) => true; |
| 1594 } | 1606 } |
| 1595 | 1607 |
| 1596 class HDivide extends HBinaryArithmetic { | 1608 class HDivide extends HBinaryArithmetic { |
| 1597 HDivide(HInstruction left, HInstruction right) : super(left, right) { | 1609 HDivide(left, right, selector) : super(left, right, selector) { |
| 1598 instructionType = HType.DOUBLE; | 1610 instructionType = HType.DOUBLE; |
| 1599 } | 1611 } |
| 1600 accept(HVisitor visitor) => visitor.visitDivide(this); | 1612 accept(HVisitor visitor) => visitor.visitDivide(this); |
| 1601 | 1613 |
| 1602 BinaryOperation operation(ConstantSystem constantSystem) | 1614 BinaryOperation operation(ConstantSystem constantSystem) |
| 1603 => constantSystem.divide; | 1615 => constantSystem.divide; |
| 1604 int typeCode() => HInstruction.DIVIDE_TYPECODE; | 1616 int typeCode() => HInstruction.DIVIDE_TYPECODE; |
| 1605 bool typeEquals(other) => other is HDivide; | 1617 bool typeEquals(other) => other is HDivide; |
| 1606 bool dataEquals(HInstruction other) => true; | 1618 bool dataEquals(HInstruction other) => true; |
| 1607 } | 1619 } |
| 1608 | 1620 |
| 1609 class HMultiply extends HBinaryArithmetic { | 1621 class HMultiply extends HBinaryArithmetic { |
| 1610 HMultiply(HInstruction left, HInstruction right) : super(left, right); | 1622 HMultiply(left, right, selector) : super(left, right, selector); |
| 1611 accept(HVisitor visitor) => visitor.visitMultiply(this); | 1623 accept(HVisitor visitor) => visitor.visitMultiply(this); |
| 1612 | 1624 |
| 1613 BinaryOperation operation(ConstantSystem operations) | 1625 BinaryOperation operation(ConstantSystem operations) |
| 1614 => operations.multiply; | 1626 => operations.multiply; |
| 1615 int typeCode() => HInstruction.MULTIPLY_TYPECODE; | 1627 int typeCode() => HInstruction.MULTIPLY_TYPECODE; |
| 1616 bool typeEquals(other) => other is HMultiply; | 1628 bool typeEquals(other) => other is HMultiply; |
| 1617 bool dataEquals(HInstruction other) => true; | 1629 bool dataEquals(HInstruction other) => true; |
| 1618 } | 1630 } |
| 1619 | 1631 |
| 1620 class HSubtract extends HBinaryArithmetic { | 1632 class HSubtract extends HBinaryArithmetic { |
| 1621 HSubtract(HInstruction left, HInstruction right) : super(left, right); | 1633 HSubtract(left, right, selector) : super(left, right, selector); |
| 1622 accept(HVisitor visitor) => visitor.visitSubtract(this); | 1634 accept(HVisitor visitor) => visitor.visitSubtract(this); |
| 1623 | 1635 |
| 1624 BinaryOperation operation(ConstantSystem constantSystem) | 1636 BinaryOperation operation(ConstantSystem constantSystem) |
| 1625 => constantSystem.subtract; | 1637 => constantSystem.subtract; |
| 1626 int typeCode() => HInstruction.SUBTRACT_TYPECODE; | 1638 int typeCode() => HInstruction.SUBTRACT_TYPECODE; |
| 1627 bool typeEquals(other) => other is HSubtract; | 1639 bool typeEquals(other) => other is HSubtract; |
| 1628 bool dataEquals(HInstruction other) => true; | 1640 bool dataEquals(HInstruction other) => true; |
| 1629 } | 1641 } |
| 1630 | 1642 |
| 1631 /** | 1643 /** |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1645 * following join-block. | 1657 * following join-block. |
| 1646 */ | 1658 */ |
| 1647 HBasicBlock get defaultTarget => block.successors.last; | 1659 HBasicBlock get defaultTarget => block.successors.last; |
| 1648 | 1660 |
| 1649 accept(HVisitor visitor) => visitor.visitSwitch(this); | 1661 accept(HVisitor visitor) => visitor.visitSwitch(this); |
| 1650 | 1662 |
| 1651 String toString() => "HSwitch cases = $inputs"; | 1663 String toString() => "HSwitch cases = $inputs"; |
| 1652 } | 1664 } |
| 1653 | 1665 |
| 1654 abstract class HBinaryBitOp extends HInvokeBinary { | 1666 abstract class HBinaryBitOp extends HInvokeBinary { |
| 1655 HBinaryBitOp(HInstruction left, HInstruction right) : super(left, right) { | 1667 HBinaryBitOp(left, right, selector) : super(left, right, selector) { |
| 1656 instructionType = HType.INTEGER; | 1668 instructionType = HType.INTEGER; |
| 1657 } | 1669 } |
| 1658 } | 1670 } |
| 1659 | 1671 |
| 1660 class HShiftLeft extends HBinaryBitOp { | 1672 class HShiftLeft extends HBinaryBitOp { |
| 1661 HShiftLeft(HInstruction left, HInstruction right) : super(left, right); | 1673 HShiftLeft(left, right, selector) : super(left, right, selector); |
| 1662 accept(HVisitor visitor) => visitor.visitShiftLeft(this); | 1674 accept(HVisitor visitor) => visitor.visitShiftLeft(this); |
| 1663 | 1675 |
| 1664 BinaryOperation operation(ConstantSystem constantSystem) | 1676 BinaryOperation operation(ConstantSystem constantSystem) |
| 1665 => constantSystem.shiftLeft; | 1677 => constantSystem.shiftLeft; |
| 1666 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; | 1678 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; |
| 1667 bool typeEquals(other) => other is HShiftLeft; | 1679 bool typeEquals(other) => other is HShiftLeft; |
| 1668 bool dataEquals(HInstruction other) => true; | 1680 bool dataEquals(HInstruction other) => true; |
| 1669 } | 1681 } |
| 1670 | 1682 |
| 1671 class HBitOr extends HBinaryBitOp { | 1683 class HBitOr extends HBinaryBitOp { |
| 1672 HBitOr(HInstruction left, HInstruction right) : super(left, right); | 1684 HBitOr(left, right, selector) : super(left, right, selector); |
| 1673 accept(HVisitor visitor) => visitor.visitBitOr(this); | 1685 accept(HVisitor visitor) => visitor.visitBitOr(this); |
| 1674 | 1686 |
| 1675 BinaryOperation operation(ConstantSystem constantSystem) | 1687 BinaryOperation operation(ConstantSystem constantSystem) |
| 1676 => constantSystem.bitOr; | 1688 => constantSystem.bitOr; |
| 1677 int typeCode() => HInstruction.BIT_OR_TYPECODE; | 1689 int typeCode() => HInstruction.BIT_OR_TYPECODE; |
| 1678 bool typeEquals(other) => other is HBitOr; | 1690 bool typeEquals(other) => other is HBitOr; |
| 1679 bool dataEquals(HInstruction other) => true; | 1691 bool dataEquals(HInstruction other) => true; |
| 1680 } | 1692 } |
| 1681 | 1693 |
| 1682 class HBitAnd extends HBinaryBitOp { | 1694 class HBitAnd extends HBinaryBitOp { |
| 1683 HBitAnd(HInstruction left, HInstruction right) : super(left, right); | 1695 HBitAnd(left, right, selector) : super(left, right, selector); |
| 1684 accept(HVisitor visitor) => visitor.visitBitAnd(this); | 1696 accept(HVisitor visitor) => visitor.visitBitAnd(this); |
| 1685 | 1697 |
| 1686 BinaryOperation operation(ConstantSystem constantSystem) | 1698 BinaryOperation operation(ConstantSystem constantSystem) |
| 1687 => constantSystem.bitAnd; | 1699 => constantSystem.bitAnd; |
| 1688 int typeCode() => HInstruction.BIT_AND_TYPECODE; | 1700 int typeCode() => HInstruction.BIT_AND_TYPECODE; |
| 1689 bool typeEquals(other) => other is HBitAnd; | 1701 bool typeEquals(other) => other is HBitAnd; |
| 1690 bool dataEquals(HInstruction other) => true; | 1702 bool dataEquals(HInstruction other) => true; |
| 1691 } | 1703 } |
| 1692 | 1704 |
| 1693 class HBitXor extends HBinaryBitOp { | 1705 class HBitXor extends HBinaryBitOp { |
| 1694 HBitXor(HInstruction left, HInstruction right) : super(left, right); | 1706 HBitXor(left, right, selector) : super(left, right, selector); |
| 1695 accept(HVisitor visitor) => visitor.visitBitXor(this); | 1707 accept(HVisitor visitor) => visitor.visitBitXor(this); |
| 1696 | 1708 |
| 1697 BinaryOperation operation(ConstantSystem constantSystem) | 1709 BinaryOperation operation(ConstantSystem constantSystem) |
| 1698 => constantSystem.bitXor; | 1710 => constantSystem.bitXor; |
| 1699 int typeCode() => HInstruction.BIT_XOR_TYPECODE; | 1711 int typeCode() => HInstruction.BIT_XOR_TYPECODE; |
| 1700 bool typeEquals(other) => other is HBitXor; | 1712 bool typeEquals(other) => other is HBitXor; |
| 1701 bool dataEquals(HInstruction other) => true; | 1713 bool dataEquals(HInstruction other) => true; |
| 1702 } | 1714 } |
| 1703 | 1715 |
| 1704 abstract class HInvokeUnary extends HInstruction { | 1716 abstract class HInvokeUnary extends HInstruction { |
| 1705 HInvokeUnary(HInstruction input) : super(<HInstruction>[input]) { | 1717 final Selector selector; |
| 1718 HInvokeUnary(HInstruction input, this.selector) |
| 1719 : super(<HInstruction>[input]) { |
| 1706 clearAllSideEffects(); | 1720 clearAllSideEffects(); |
| 1707 setUseGvn(); | 1721 setUseGvn(); |
| 1708 } | 1722 } |
| 1709 | 1723 |
| 1710 HInstruction get operand => inputs[0]; | 1724 HInstruction get operand => inputs[0]; |
| 1711 | 1725 |
| 1712 UnaryOperation operation(ConstantSystem constantSystem); | 1726 UnaryOperation operation(ConstantSystem constantSystem); |
| 1713 } | 1727 } |
| 1714 | 1728 |
| 1715 class HNegate extends HInvokeUnary { | 1729 class HNegate extends HInvokeUnary { |
| 1716 HNegate(HInstruction input) : super(input); | 1730 HNegate(input, selector) : super(input, selector); |
| 1717 accept(HVisitor visitor) => visitor.visitNegate(this); | 1731 accept(HVisitor visitor) => visitor.visitNegate(this); |
| 1718 | 1732 |
| 1719 UnaryOperation operation(ConstantSystem constantSystem) | 1733 UnaryOperation operation(ConstantSystem constantSystem) |
| 1720 => constantSystem.negate; | 1734 => constantSystem.negate; |
| 1721 int typeCode() => HInstruction.NEGATE_TYPECODE; | 1735 int typeCode() => HInstruction.NEGATE_TYPECODE; |
| 1722 bool typeEquals(other) => other is HNegate; | 1736 bool typeEquals(other) => other is HNegate; |
| 1723 bool dataEquals(HInstruction other) => true; | 1737 bool dataEquals(HInstruction other) => true; |
| 1724 } | 1738 } |
| 1725 | 1739 |
| 1726 class HBitNot extends HInvokeUnary { | 1740 class HBitNot extends HInvokeUnary { |
| 1727 HBitNot(HInstruction input) : super(input) { | 1741 HBitNot(input, selector) : super(input, selector) { |
| 1728 instructionType = HType.INTEGER; | 1742 instructionType = HType.INTEGER; |
| 1729 } | 1743 } |
| 1730 accept(HVisitor visitor) => visitor.visitBitNot(this); | 1744 accept(HVisitor visitor) => visitor.visitBitNot(this); |
| 1731 | 1745 |
| 1732 UnaryOperation operation(ConstantSystem constantSystem) | 1746 UnaryOperation operation(ConstantSystem constantSystem) |
| 1733 => constantSystem.bitNot; | 1747 => constantSystem.bitNot; |
| 1734 int typeCode() => HInstruction.BIT_NOT_TYPECODE; | 1748 int typeCode() => HInstruction.BIT_NOT_TYPECODE; |
| 1735 bool typeEquals(other) => other is HBitNot; | 1749 bool typeEquals(other) => other is HBitNot; |
| 1736 bool dataEquals(HInstruction other) => true; | 1750 bool dataEquals(HInstruction other) => true; |
| 1737 } | 1751 } |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 assert(logicalOperatorType == IS_OR); | 1965 assert(logicalOperatorType == IS_OR); |
| 1952 return "||"; | 1966 return "||"; |
| 1953 } | 1967 } |
| 1954 | 1968 |
| 1955 toString() => 'phi'; | 1969 toString() => 'phi'; |
| 1956 accept(HVisitor visitor) => visitor.visitPhi(this); | 1970 accept(HVisitor visitor) => visitor.visitPhi(this); |
| 1957 } | 1971 } |
| 1958 | 1972 |
| 1959 abstract class HRelational extends HInvokeBinary { | 1973 abstract class HRelational extends HInvokeBinary { |
| 1960 bool usesBoolifiedInterceptor = false; | 1974 bool usesBoolifiedInterceptor = false; |
| 1961 HRelational(HInstruction left, HInstruction right) : super(left, right) { | 1975 HRelational(left, right, selector) : super(left, right, selector) { |
| 1962 instructionType = HType.BOOLEAN; | 1976 instructionType = HType.BOOLEAN; |
| 1963 } | 1977 } |
| 1964 } | 1978 } |
| 1965 | 1979 |
| 1966 class HIdentity extends HRelational { | 1980 class HIdentity extends HRelational { |
| 1967 HIdentity(HInstruction left, HInstruction right) : super(left, right); | 1981 HIdentity(left, right, [selector]) : super(left, right, selector); |
| 1968 accept(HVisitor visitor) => visitor.visitIdentity(this); | 1982 accept(HVisitor visitor) => visitor.visitIdentity(this); |
| 1969 | 1983 |
| 1970 BinaryOperation operation(ConstantSystem constantSystem) | 1984 BinaryOperation operation(ConstantSystem constantSystem) |
| 1971 => constantSystem.identity; | 1985 => constantSystem.identity; |
| 1972 int typeCode() => HInstruction.IDENTITY_TYPECODE; | 1986 int typeCode() => HInstruction.IDENTITY_TYPECODE; |
| 1973 bool typeEquals(other) => other is HIdentity; | 1987 bool typeEquals(other) => other is HIdentity; |
| 1974 bool dataEquals(HInstruction other) => true; | 1988 bool dataEquals(HInstruction other) => true; |
| 1975 } | 1989 } |
| 1976 | 1990 |
| 1977 class HGreater extends HRelational { | 1991 class HGreater extends HRelational { |
| 1978 HGreater(HInstruction left, HInstruction right) : super(left, right); | 1992 HGreater(left, right, selector) : super(left, right, selector); |
| 1979 accept(HVisitor visitor) => visitor.visitGreater(this); | 1993 accept(HVisitor visitor) => visitor.visitGreater(this); |
| 1980 | 1994 |
| 1981 BinaryOperation operation(ConstantSystem constantSystem) | 1995 BinaryOperation operation(ConstantSystem constantSystem) |
| 1982 => constantSystem.greater; | 1996 => constantSystem.greater; |
| 1983 int typeCode() => HInstruction.GREATER_TYPECODE; | 1997 int typeCode() => HInstruction.GREATER_TYPECODE; |
| 1984 bool typeEquals(other) => other is HGreater; | 1998 bool typeEquals(other) => other is HGreater; |
| 1985 bool dataEquals(HInstruction other) => true; | 1999 bool dataEquals(HInstruction other) => true; |
| 1986 } | 2000 } |
| 1987 | 2001 |
| 1988 class HGreaterEqual extends HRelational { | 2002 class HGreaterEqual extends HRelational { |
| 1989 HGreaterEqual(HInstruction left, HInstruction right) : super(left, right); | 2003 HGreaterEqual(left, right, selector) : super(left, right, selector); |
| 1990 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); | 2004 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); |
| 1991 | 2005 |
| 1992 BinaryOperation operation(ConstantSystem constantSystem) | 2006 BinaryOperation operation(ConstantSystem constantSystem) |
| 1993 => constantSystem.greaterEqual; | 2007 => constantSystem.greaterEqual; |
| 1994 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; | 2008 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; |
| 1995 bool typeEquals(other) => other is HGreaterEqual; | 2009 bool typeEquals(other) => other is HGreaterEqual; |
| 1996 bool dataEquals(HInstruction other) => true; | 2010 bool dataEquals(HInstruction other) => true; |
| 1997 } | 2011 } |
| 1998 | 2012 |
| 1999 class HLess extends HRelational { | 2013 class HLess extends HRelational { |
| 2000 HLess(HInstruction left, HInstruction right) : super(left, right); | 2014 HLess(left, right, selector) : super(left, right, selector); |
| 2001 accept(HVisitor visitor) => visitor.visitLess(this); | 2015 accept(HVisitor visitor) => visitor.visitLess(this); |
| 2002 | 2016 |
| 2003 BinaryOperation operation(ConstantSystem constantSystem) | 2017 BinaryOperation operation(ConstantSystem constantSystem) |
| 2004 => constantSystem.less; | 2018 => constantSystem.less; |
| 2005 int typeCode() => HInstruction.LESS_TYPECODE; | 2019 int typeCode() => HInstruction.LESS_TYPECODE; |
| 2006 bool typeEquals(other) => other is HLess; | 2020 bool typeEquals(other) => other is HLess; |
| 2007 bool dataEquals(HInstruction other) => true; | 2021 bool dataEquals(HInstruction other) => true; |
| 2008 } | 2022 } |
| 2009 | 2023 |
| 2010 class HLessEqual extends HRelational { | 2024 class HLessEqual extends HRelational { |
| 2011 HLessEqual(HInstruction left, HInstruction right) : super(left, right); | 2025 HLessEqual(left, right, selector) : super(left, right, selector); |
| 2012 accept(HVisitor visitor) => visitor.visitLessEqual(this); | 2026 accept(HVisitor visitor) => visitor.visitLessEqual(this); |
| 2013 | 2027 |
| 2014 BinaryOperation operation(ConstantSystem constantSystem) | 2028 BinaryOperation operation(ConstantSystem constantSystem) |
| 2015 => constantSystem.lessEqual; | 2029 => constantSystem.lessEqual; |
| 2016 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; | 2030 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; |
| 2017 bool typeEquals(other) => other is HLessEqual; | 2031 bool typeEquals(other) => other is HLessEqual; |
| 2018 bool dataEquals(HInstruction other) => true; | 2032 bool dataEquals(HInstruction other) => true; |
| 2019 } | 2033 } |
| 2020 | 2034 |
| 2021 class HReturn extends HControlFlow { | 2035 class HReturn extends HControlFlow { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2145 } | 2159 } |
| 2146 toString() => 'literal list'; | 2160 toString() => 'literal list'; |
| 2147 accept(HVisitor visitor) => visitor.visitLiteralList(this); | 2161 accept(HVisitor visitor) => visitor.visitLiteralList(this); |
| 2148 } | 2162 } |
| 2149 | 2163 |
| 2150 /** | 2164 /** |
| 2151 * The primitive array indexing operation. Note that this instruction | 2165 * The primitive array indexing operation. Note that this instruction |
| 2152 * does not throw because we generate the checks explicitly. | 2166 * does not throw because we generate the checks explicitly. |
| 2153 */ | 2167 */ |
| 2154 class HIndex extends HInstruction { | 2168 class HIndex extends HInstruction { |
| 2155 HIndex(HInstruction receiver, HInstruction index) | 2169 final Selector selector; |
| 2170 HIndex(HInstruction receiver, HInstruction index, this.selector) |
| 2156 : super(<HInstruction>[receiver, index]) { | 2171 : super(<HInstruction>[receiver, index]) { |
| 2157 clearAllSideEffects(); | 2172 clearAllSideEffects(); |
| 2158 setDependsOnIndexStore(); | 2173 setDependsOnIndexStore(); |
| 2159 setUseGvn(); | 2174 setUseGvn(); |
| 2160 } | 2175 } |
| 2161 | 2176 |
| 2162 String toString() => 'index operator'; | 2177 String toString() => 'index operator'; |
| 2163 accept(HVisitor visitor) => visitor.visitIndex(this); | 2178 accept(HVisitor visitor) => visitor.visitIndex(this); |
| 2164 | 2179 |
| 2165 HInstruction get receiver => inputs[0]; | 2180 HInstruction get receiver => inputs[0]; |
| 2166 HInstruction get index => inputs[1]; | 2181 HInstruction get index => inputs[1]; |
| 2167 | 2182 |
| 2168 int typeCode() => HInstruction.INDEX_TYPECODE; | 2183 int typeCode() => HInstruction.INDEX_TYPECODE; |
| 2169 bool typeEquals(HInstruction other) => other is HIndex; | 2184 bool typeEquals(HInstruction other) => other is HIndex; |
| 2170 bool dataEquals(HIndex other) => true; | 2185 bool dataEquals(HIndex other) => true; |
| 2171 } | 2186 } |
| 2172 | 2187 |
| 2173 /** | 2188 /** |
| 2174 * The primitive array assignment operation. Note that this instruction | 2189 * The primitive array assignment operation. Note that this instruction |
| 2175 * does not throw because we generate the checks explicitly. | 2190 * does not throw because we generate the checks explicitly. |
| 2176 */ | 2191 */ |
| 2177 class HIndexAssign extends HInstruction { | 2192 class HIndexAssign extends HInstruction { |
| 2193 final Selector selector; |
| 2178 HIndexAssign(HInstruction receiver, | 2194 HIndexAssign(HInstruction receiver, |
| 2179 HInstruction index, | 2195 HInstruction index, |
| 2180 HInstruction value) | 2196 HInstruction value, |
| 2197 this.selector) |
| 2181 : super(<HInstruction>[receiver, index, value]) { | 2198 : super(<HInstruction>[receiver, index, value]) { |
| 2182 clearAllSideEffects(); | 2199 clearAllSideEffects(); |
| 2183 setChangesIndex(); | 2200 setChangesIndex(); |
| 2184 } | 2201 } |
| 2185 String toString() => 'index assign operator'; | 2202 String toString() => 'index assign operator'; |
| 2186 accept(HVisitor visitor) => visitor.visitIndexAssign(this); | 2203 accept(HVisitor visitor) => visitor.visitIndexAssign(this); |
| 2187 | 2204 |
| 2188 HInstruction get receiver => inputs[0]; | 2205 HInstruction get receiver => inputs[0]; |
| 2189 HInstruction get index => inputs[1]; | 2206 HInstruction get index => inputs[1]; |
| 2190 HInstruction get value => inputs[2]; | 2207 HInstruction get value => inputs[2]; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 bool dataEquals(HIs other) { | 2249 bool dataEquals(HIs other) { |
| 2233 return typeExpression == other.typeExpression | 2250 return typeExpression == other.typeExpression |
| 2234 && nullOk == other.nullOk | 2251 && nullOk == other.nullOk |
| 2235 && kind == other.kind; | 2252 && kind == other.kind; |
| 2236 } | 2253 } |
| 2237 } | 2254 } |
| 2238 | 2255 |
| 2239 class HTypeConversion extends HCheck { | 2256 class HTypeConversion extends HCheck { |
| 2240 final DartType typeExpression; | 2257 final DartType typeExpression; |
| 2241 final int kind; | 2258 final int kind; |
| 2259 final Selector receiverTypeCheckSelector; |
| 2242 | 2260 |
| 2243 static const int NO_CHECK = 0; | 2261 static const int NO_CHECK = 0; |
| 2244 static const int CHECKED_MODE_CHECK = 1; | 2262 static const int CHECKED_MODE_CHECK = 1; |
| 2245 static const int ARGUMENT_TYPE_CHECK = 2; | 2263 static const int ARGUMENT_TYPE_CHECK = 2; |
| 2246 static const int CAST_TYPE_CHECK = 3; | 2264 static const int CAST_TYPE_CHECK = 3; |
| 2247 static const int BOOLEAN_CONVERSION_CHECK = 4; | 2265 static const int BOOLEAN_CONVERSION_CHECK = 4; |
| 2266 static const int RECEIVER_TYPE_CHECK = 5; |
| 2248 | 2267 |
| 2249 HTypeConversion(this.typeExpression, this.kind, | 2268 HTypeConversion(this.typeExpression, this.kind, |
| 2250 HType type, HInstruction input) | 2269 HType type, HInstruction input, |
| 2270 [this.receiverTypeCheckSelector]) |
| 2251 : super(<HInstruction>[input]) { | 2271 : super(<HInstruction>[input]) { |
| 2272 assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null); |
| 2252 sourceElement = input.sourceElement; | 2273 sourceElement = input.sourceElement; |
| 2253 instructionType = type; | 2274 instructionType = type; |
| 2254 } | 2275 } |
| 2255 | 2276 |
| 2256 bool get isChecked => kind != NO_CHECK; | 2277 bool get isChecked => kind != NO_CHECK; |
| 2257 bool get isCheckedModeCheck { | 2278 bool get isCheckedModeCheck { |
| 2258 return kind == CHECKED_MODE_CHECK | 2279 return kind == CHECKED_MODE_CHECK |
| 2259 || kind == BOOLEAN_CONVERSION_CHECK; | 2280 || kind == BOOLEAN_CONVERSION_CHECK; |
| 2260 } | 2281 } |
| 2261 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; | 2282 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; |
| 2283 bool get isReceiverTypeCheck => kind == RECEIVER_TYPE_CHECK; |
| 2262 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; | 2284 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; |
| 2263 bool get isBooleanConversionCheck => kind == BOOLEAN_CONVERSION_CHECK; | 2285 bool get isBooleanConversionCheck => kind == BOOLEAN_CONVERSION_CHECK; |
| 2264 | 2286 |
| 2265 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2287 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2266 | 2288 |
| 2267 bool isJsStatement() => kind == ARGUMENT_TYPE_CHECK; | 2289 bool isJsStatement() => isControlFlow(); |
| 2268 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; | 2290 bool isControlFlow() => isArgumentTypeCheck || isReceiverTypeCheck; |
| 2269 bool canThrow() => isChecked; | 2291 bool canThrow() => isChecked; |
| 2270 | 2292 |
| 2271 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; | 2293 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; |
| 2272 bool typeEquals(HInstruction other) => other is HTypeConversion; | 2294 bool typeEquals(HInstruction other) => other is HTypeConversion; |
| 2273 | 2295 |
| 2274 bool dataEquals(HTypeConversion other) { | 2296 bool dataEquals(HTypeConversion other) { |
| 2275 return kind == other.kind | 2297 return kind == other.kind |
| 2276 && typeExpression == other.typeExpression | 2298 && typeExpression == other.typeExpression |
| 2277 && instructionType == other.instructionType; | 2299 && instructionType == other.instructionType; |
| 2278 } | 2300 } |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2651 HBasicBlock get start => expression.start; | 2673 HBasicBlock get start => expression.start; |
| 2652 HBasicBlock get end { | 2674 HBasicBlock get end { |
| 2653 // We don't create a switch block if there are no cases. | 2675 // We don't create a switch block if there are no cases. |
| 2654 assert(!statements.isEmpty); | 2676 assert(!statements.isEmpty); |
| 2655 return statements.last.end; | 2677 return statements.last.end; |
| 2656 } | 2678 } |
| 2657 | 2679 |
| 2658 bool accept(HStatementInformationVisitor visitor) => | 2680 bool accept(HStatementInformationVisitor visitor) => |
| 2659 visitor.visitSwitchInfo(this); | 2681 visitor.visitSwitchInfo(this); |
| 2660 } | 2682 } |
| OLD | NEW |