| 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
| 8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
| 9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
| 10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 HConstant result = constants[constant]; | 173 HConstant result = constants[constant]; |
| 174 if (result === null) { | 174 if (result === null) { |
| 175 HType type = mapConstantTypeToSsaType(constant); | 175 HType type = mapConstantTypeToSsaType(constant); |
| 176 result = new HConstant.internal(constant, type); | 176 result = new HConstant.internal(constant, type); |
| 177 entry.addAtExit(result); | 177 entry.addAtExit(result); |
| 178 constants[constant] = result; | 178 constants[constant] = result; |
| 179 } | 179 } |
| 180 return result; | 180 return result; |
| 181 } | 181 } |
| 182 | 182 |
| 183 HConstant addConstantInt(int i) { | 183 HConstant addConstantInt(int i, ConstantSystem constantSystem) { |
| 184 return addConstant(new IntConstant(i)); | 184 return addConstant(constantSystem.createInt(i)); |
| 185 } | 185 } |
| 186 | 186 |
| 187 HConstant addConstantDouble(double d) { | 187 HConstant addConstantDouble(double d, ConstantSystem constantSystem) { |
| 188 return addConstant(new DoubleConstant(d)); | 188 return addConstant(constantSystem.createDouble(d)); |
| 189 } | 189 } |
| 190 | 190 |
| 191 HConstant addConstantString(DartString str, Node node) { | 191 HConstant addConstantString(DartString str, |
| 192 return addConstant(new StringConstant(str, node)); | 192 Node diagnosticNode, |
| 193 ConstantSystem constantSystem) { |
| 194 return addConstant(constantSystem.createString(str, diagnosticNode)); |
| 193 } | 195 } |
| 194 | 196 |
| 195 HConstant addConstantBool(bool value) { | 197 HConstant addConstantBool(bool value, ConstantSystem constantSystem) { |
| 196 return addConstant(new BoolConstant(value)); | 198 return addConstant(constantSystem.createBool(value)); |
| 197 } | 199 } |
| 198 | 200 |
| 199 HConstant addConstantNull() { | 201 HConstant addConstantNull(ConstantSystem constantSystem) { |
| 200 return addConstant(new NullConstant()); | 202 return addConstant(constantSystem.createNull()); |
| 201 } | 203 } |
| 202 | 204 |
| 203 void finalize() { | 205 void finalize() { |
| 204 addBlock(exit); | 206 addBlock(exit); |
| 205 exit.open(); | 207 exit.open(); |
| 206 exit.close(new HExit()); | 208 exit.close(new HExit()); |
| 207 assignDominators(); | 209 assignDominators(); |
| 208 } | 210 } |
| 209 | 211 |
| 210 void assignDominators() { | 212 void assignDominators() { |
| (...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1511 accept(HVisitor visitor) => visitor.visitForeignNew(this); | 1513 accept(HVisitor visitor) => visitor.visitForeignNew(this); |
| 1512 } | 1514 } |
| 1513 | 1515 |
| 1514 class HInvokeBinary extends HInvokeStatic { | 1516 class HInvokeBinary extends HInvokeStatic { |
| 1515 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) | 1517 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) |
| 1516 : super(<HInstruction>[target, left, right]); | 1518 : super(<HInstruction>[target, left, right]); |
| 1517 | 1519 |
| 1518 HInstruction get left => inputs[1]; | 1520 HInstruction get left => inputs[1]; |
| 1519 HInstruction get right => inputs[2]; | 1521 HInstruction get right => inputs[2]; |
| 1520 | 1522 |
| 1521 abstract BinaryOperation get operation; | 1523 abstract BinaryOperation operation(ConstantSystem constantSystem); |
| 1522 abstract isBuiltin(HTypeMap types); | 1524 abstract isBuiltin(HTypeMap types); |
| 1523 } | 1525 } |
| 1524 | 1526 |
| 1525 class HBinaryArithmetic extends HInvokeBinary { | 1527 class HBinaryArithmetic extends HInvokeBinary { |
| 1526 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) | 1528 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) |
| 1527 : super(target, left, right); | 1529 : super(target, left, right); |
| 1528 | 1530 |
| 1529 void prepareGvn(HTypeMap types) { | 1531 void prepareGvn(HTypeMap types) { |
| 1530 // An arithmetic expression can take part in global value | 1532 // An arithmetic expression can take part in global value |
| 1531 // numbering and do not have any side-effects if we know that all | 1533 // numbering and do not have any side-effects if we know that all |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 if (input == right && left.isNumber(types)) return HType.NUMBER; | 1574 if (input == right && left.isNumber(types)) return HType.NUMBER; |
| 1573 return HType.UNKNOWN; | 1575 return HType.UNKNOWN; |
| 1574 } | 1576 } |
| 1575 | 1577 |
| 1576 HType computeLikelyType(HTypeMap types) { | 1578 HType computeLikelyType(HTypeMap types) { |
| 1577 if (left.isTypeUnknown(types)) return HType.NUMBER; | 1579 if (left.isTypeUnknown(types)) return HType.NUMBER; |
| 1578 return HType.UNKNOWN; | 1580 return HType.UNKNOWN; |
| 1579 } | 1581 } |
| 1580 | 1582 |
| 1581 // TODO(1603): The class should be marked as abstract. | 1583 // TODO(1603): The class should be marked as abstract. |
| 1582 abstract BinaryOperation get operation; | 1584 abstract BinaryOperation operation(ConstantSystem constantSystem); |
| 1583 } | 1585 } |
| 1584 | 1586 |
| 1585 class HAdd extends HBinaryArithmetic { | 1587 class HAdd extends HBinaryArithmetic { |
| 1586 HAdd(HStatic target, HInstruction left, HInstruction right) | 1588 HAdd(HStatic target, HInstruction left, HInstruction right) |
| 1587 : super(target, left, right); | 1589 : super(target, left, right); |
| 1588 accept(HVisitor visitor) => visitor.visitAdd(this); | 1590 accept(HVisitor visitor) => visitor.visitAdd(this); |
| 1589 | 1591 |
| 1590 AddOperation get operation => const AddOperation(); | 1592 BinaryOperation operation(ConstantSystem constantSystem) |
| 1593 => constantSystem.add; |
| 1591 int typeCode() => HInstruction.ADD_TYPECODE; | 1594 int typeCode() => HInstruction.ADD_TYPECODE; |
| 1592 bool typeEquals(other) => other is HAdd; | 1595 bool typeEquals(other) => other is HAdd; |
| 1593 bool dataEquals(HInstruction other) => true; | 1596 bool dataEquals(HInstruction other) => true; |
| 1594 } | 1597 } |
| 1595 | 1598 |
| 1596 class HDivide extends HBinaryArithmetic { | 1599 class HDivide extends HBinaryArithmetic { |
| 1597 HDivide(HStatic target, HInstruction left, HInstruction right) | 1600 HDivide(HStatic target, HInstruction left, HInstruction right) |
| 1598 : super(target, left, right); | 1601 : super(target, left, right); |
| 1599 accept(HVisitor visitor) => visitor.visitDivide(this); | 1602 accept(HVisitor visitor) => visitor.visitDivide(this); |
| 1600 | 1603 |
| 1601 HType computeTypeFromInputTypes(HTypeMap types) { | 1604 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1602 if (left.isNumber(types)) return HType.DOUBLE; | 1605 if (left.isNumber(types)) return HType.DOUBLE; |
| 1603 return HType.UNKNOWN; | 1606 return HType.UNKNOWN; |
| 1604 } | 1607 } |
| 1605 | 1608 |
| 1606 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1609 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
| 1607 HTypeMap types) { | 1610 HTypeMap types) { |
| 1608 // A division can never return an integer. So don't ask for integer inputs. | 1611 // A division can never return an integer. So don't ask for integer inputs. |
| 1609 if (isInteger(types)) return HType.UNKNOWN; | 1612 if (isInteger(types)) return HType.UNKNOWN; |
| 1610 return super.computeDesiredTypeForNonTargetInput(input, types); | 1613 return super.computeDesiredTypeForNonTargetInput(input, types); |
| 1611 } | 1614 } |
| 1612 | 1615 |
| 1613 DivideOperation get operation => const DivideOperation(); | 1616 BinaryOperation operation(ConstantSystem constantSystem) |
| 1617 => constantSystem.divide; |
| 1614 int typeCode() => HInstruction.DIVIDE_TYPECODE; | 1618 int typeCode() => HInstruction.DIVIDE_TYPECODE; |
| 1615 bool typeEquals(other) => other is HDivide; | 1619 bool typeEquals(other) => other is HDivide; |
| 1616 bool dataEquals(HInstruction other) => true; | 1620 bool dataEquals(HInstruction other) => true; |
| 1617 } | 1621 } |
| 1618 | 1622 |
| 1619 class HModulo extends HBinaryArithmetic { | 1623 class HModulo extends HBinaryArithmetic { |
| 1620 HModulo(HStatic target, HInstruction left, HInstruction right) | 1624 HModulo(HStatic target, HInstruction left, HInstruction right) |
| 1621 : super(target, left, right); | 1625 : super(target, left, right); |
| 1622 accept(HVisitor visitor) => visitor.visitModulo(this); | 1626 accept(HVisitor visitor) => visitor.visitModulo(this); |
| 1623 | 1627 |
| 1624 ModuloOperation get operation => const ModuloOperation(); | 1628 BinaryOperation operation(ConstantSystem constantSystem) |
| 1629 => constantSystem.modulo; |
| 1625 int typeCode() => HInstruction.MODULO_TYPECODE; | 1630 int typeCode() => HInstruction.MODULO_TYPECODE; |
| 1626 bool typeEquals(other) => other is HModulo; | 1631 bool typeEquals(other) => other is HModulo; |
| 1627 bool dataEquals(HInstruction other) => true; | 1632 bool dataEquals(HInstruction other) => true; |
| 1628 } | 1633 } |
| 1629 | 1634 |
| 1630 class HMultiply extends HBinaryArithmetic { | 1635 class HMultiply extends HBinaryArithmetic { |
| 1631 HMultiply(HStatic target, HInstruction left, HInstruction right) | 1636 HMultiply(HStatic target, HInstruction left, HInstruction right) |
| 1632 : super(target, left, right); | 1637 : super(target, left, right); |
| 1633 accept(HVisitor visitor) => visitor.visitMultiply(this); | 1638 accept(HVisitor visitor) => visitor.visitMultiply(this); |
| 1634 | 1639 |
| 1635 MultiplyOperation get operation => const MultiplyOperation(); | 1640 BinaryOperation operation(ConstantSystem operations) |
| 1641 => operations.multiply; |
| 1636 int typeCode() => HInstruction.MULTIPLY_TYPECODE; | 1642 int typeCode() => HInstruction.MULTIPLY_TYPECODE; |
| 1637 bool typeEquals(other) => other is HMultiply; | 1643 bool typeEquals(other) => other is HMultiply; |
| 1638 bool dataEquals(HInstruction other) => true; | 1644 bool dataEquals(HInstruction other) => true; |
| 1639 } | 1645 } |
| 1640 | 1646 |
| 1641 class HSubtract extends HBinaryArithmetic { | 1647 class HSubtract extends HBinaryArithmetic { |
| 1642 HSubtract(HStatic target, HInstruction left, HInstruction right) | 1648 HSubtract(HStatic target, HInstruction left, HInstruction right) |
| 1643 : super(target, left, right); | 1649 : super(target, left, right); |
| 1644 accept(HVisitor visitor) => visitor.visitSubtract(this); | 1650 accept(HVisitor visitor) => visitor.visitSubtract(this); |
| 1645 | 1651 |
| 1646 SubtractOperation get operation => const SubtractOperation(); | 1652 BinaryOperation operation(ConstantSystem constantSystem) |
| 1653 => constantSystem.subtract; |
| 1647 int typeCode() => HInstruction.SUBTRACT_TYPECODE; | 1654 int typeCode() => HInstruction.SUBTRACT_TYPECODE; |
| 1648 bool typeEquals(other) => other is HSubtract; | 1655 bool typeEquals(other) => other is HSubtract; |
| 1649 bool dataEquals(HInstruction other) => true; | 1656 bool dataEquals(HInstruction other) => true; |
| 1650 } | 1657 } |
| 1651 | 1658 |
| 1652 /** | 1659 /** |
| 1653 * An [HSwitch] instruction has one input for the incoming | 1660 * An [HSwitch] instruction has one input for the incoming |
| 1654 * value, and one input per constant that it can switch on. | 1661 * value, and one input per constant that it can switch on. |
| 1655 * Its block has one successor per constant, and one for the default. | 1662 * Its block has one successor per constant, and one for the default. |
| 1656 */ | 1663 */ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1670 accept(HVisitor visitor) => visitor.visitSwitch(this); | 1677 accept(HVisitor visitor) => visitor.visitSwitch(this); |
| 1671 | 1678 |
| 1672 String toString() => "HSwitch cases = $inputs"; | 1679 String toString() => "HSwitch cases = $inputs"; |
| 1673 } | 1680 } |
| 1674 | 1681 |
| 1675 class HTruncatingDivide extends HBinaryArithmetic { | 1682 class HTruncatingDivide extends HBinaryArithmetic { |
| 1676 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) | 1683 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) |
| 1677 : super(target, left, right); | 1684 : super(target, left, right); |
| 1678 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); | 1685 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); |
| 1679 | 1686 |
| 1680 TruncatingDivideOperation get operation | 1687 BinaryOperation operation(ConstantSystem constantSystem) |
| 1681 => const TruncatingDivideOperation(); | 1688 => constantSystem.truncatingDivide; |
| 1682 int typeCode() => HInstruction.TRUNCATING_DIVIDE_TYPECODE; | 1689 int typeCode() => HInstruction.TRUNCATING_DIVIDE_TYPECODE; |
| 1683 bool typeEquals(other) => other is HTruncatingDivide; | 1690 bool typeEquals(other) => other is HTruncatingDivide; |
| 1684 bool dataEquals(HInstruction other) => true; | 1691 bool dataEquals(HInstruction other) => true; |
| 1685 } | 1692 } |
| 1686 | 1693 |
| 1687 | 1694 |
| 1688 // TODO(floitsch): Should HBinaryArithmetic really be the super class of | 1695 // TODO(floitsch): Should HBinaryArithmetic really be the super class of |
| 1689 // HBinaryBitOp? | 1696 // HBinaryBitOp? |
| 1690 class HBinaryBitOp extends HBinaryArithmetic { | 1697 class HBinaryBitOp extends HBinaryArithmetic { |
| 1691 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) | 1698 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 // Shift left cannot be mapped to the native operator unless the | 1734 // Shift left cannot be mapped to the native operator unless the |
| 1728 // shift count is guaranteed to be an integer in the [0,31] range. | 1735 // shift count is guaranteed to be an integer in the [0,31] range. |
| 1729 bool isBuiltin(HTypeMap types) { | 1736 bool isBuiltin(HTypeMap types) { |
| 1730 if (!left.isNumber(types) || !right.isConstantInteger()) return false; | 1737 if (!left.isNumber(types) || !right.isConstantInteger()) return false; |
| 1731 HConstant rightConstant = right; | 1738 HConstant rightConstant = right; |
| 1732 IntConstant intConstant = rightConstant.constant; | 1739 IntConstant intConstant = rightConstant.constant; |
| 1733 int count = intConstant.value; | 1740 int count = intConstant.value; |
| 1734 return count >= 0 && count <= 31; | 1741 return count >= 0 && count <= 31; |
| 1735 } | 1742 } |
| 1736 | 1743 |
| 1737 ShiftLeftOperation get operation => const ShiftLeftOperation(); | 1744 BinaryOperation operation(ConstantSystem constantSystem) |
| 1745 => constantSystem.shiftLeft; |
| 1738 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; | 1746 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; |
| 1739 bool typeEquals(other) => other is HShiftLeft; | 1747 bool typeEquals(other) => other is HShiftLeft; |
| 1740 bool dataEquals(HInstruction other) => true; | 1748 bool dataEquals(HInstruction other) => true; |
| 1741 } | 1749 } |
| 1742 | 1750 |
| 1743 class HShiftRight extends HBinaryBitOp { | 1751 class HShiftRight extends HBinaryBitOp { |
| 1744 HShiftRight(HStatic target, HInstruction left, HInstruction right) | 1752 HShiftRight(HStatic target, HInstruction left, HInstruction right) |
| 1745 : super(target, left, right); | 1753 : super(target, left, right); |
| 1746 accept(HVisitor visitor) => visitor.visitShiftRight(this); | 1754 accept(HVisitor visitor) => visitor.visitShiftRight(this); |
| 1747 | 1755 |
| 1748 // Shift right cannot be mapped to the native operator easily. | 1756 // Shift right cannot be mapped to the native operator easily. |
| 1749 bool isBuiltin(HTypeMap types) => false; | 1757 bool isBuiltin(HTypeMap types) => false; |
| 1750 | 1758 |
| 1751 ShiftRightOperation get operation => const ShiftRightOperation(); | 1759 BinaryOperation operation(ConstantSystem constantSystem) |
| 1760 => constantSystem.shiftRight; |
| 1752 int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE; | 1761 int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE; |
| 1753 bool typeEquals(other) => other is HShiftRight; | 1762 bool typeEquals(other) => other is HShiftRight; |
| 1754 bool dataEquals(HInstruction other) => true; | 1763 bool dataEquals(HInstruction other) => true; |
| 1755 } | 1764 } |
| 1756 | 1765 |
| 1757 class HBitOr extends HBinaryBitOp { | 1766 class HBitOr extends HBinaryBitOp { |
| 1758 HBitOr(HStatic target, HInstruction left, HInstruction right) | 1767 HBitOr(HStatic target, HInstruction left, HInstruction right) |
| 1759 : super(target, left, right); | 1768 : super(target, left, right); |
| 1760 accept(HVisitor visitor) => visitor.visitBitOr(this); | 1769 accept(HVisitor visitor) => visitor.visitBitOr(this); |
| 1761 | 1770 |
| 1762 BitOrOperation get operation => const BitOrOperation(); | 1771 BinaryOperation operation(ConstantSystem constantSystem) |
| 1772 => constantSystem.bitOr; |
| 1763 int typeCode() => HInstruction.BIT_OR_TYPECODE; | 1773 int typeCode() => HInstruction.BIT_OR_TYPECODE; |
| 1764 bool typeEquals(other) => other is HBitOr; | 1774 bool typeEquals(other) => other is HBitOr; |
| 1765 bool dataEquals(HInstruction other) => true; | 1775 bool dataEquals(HInstruction other) => true; |
| 1766 } | 1776 } |
| 1767 | 1777 |
| 1768 class HBitAnd extends HBinaryBitOp { | 1778 class HBitAnd extends HBinaryBitOp { |
| 1769 HBitAnd(HStatic target, HInstruction left, HInstruction right) | 1779 HBitAnd(HStatic target, HInstruction left, HInstruction right) |
| 1770 : super(target, left, right); | 1780 : super(target, left, right); |
| 1771 accept(HVisitor visitor) => visitor.visitBitAnd(this); | 1781 accept(HVisitor visitor) => visitor.visitBitAnd(this); |
| 1772 | 1782 |
| 1773 BitAndOperation get operation => const BitAndOperation(); | 1783 BinaryOperation operation(ConstantSystem constantSystem) |
| 1784 => constantSystem.bitAnd; |
| 1774 int typeCode() => HInstruction.BIT_AND_TYPECODE; | 1785 int typeCode() => HInstruction.BIT_AND_TYPECODE; |
| 1775 bool typeEquals(other) => other is HBitAnd; | 1786 bool typeEquals(other) => other is HBitAnd; |
| 1776 bool dataEquals(HInstruction other) => true; | 1787 bool dataEquals(HInstruction other) => true; |
| 1777 } | 1788 } |
| 1778 | 1789 |
| 1779 class HBitXor extends HBinaryBitOp { | 1790 class HBitXor extends HBinaryBitOp { |
| 1780 HBitXor(HStatic target, HInstruction left, HInstruction right) | 1791 HBitXor(HStatic target, HInstruction left, HInstruction right) |
| 1781 : super(target, left, right); | 1792 : super(target, left, right); |
| 1782 accept(HVisitor visitor) => visitor.visitBitXor(this); | 1793 accept(HVisitor visitor) => visitor.visitBitXor(this); |
| 1783 | 1794 |
| 1784 BitXorOperation get operation => const BitXorOperation(); | 1795 BinaryOperation operation(ConstantSystem constantSystem) |
| 1796 => constantSystem.bitXor; |
| 1785 int typeCode() => HInstruction.BIT_XOR_TYPECODE; | 1797 int typeCode() => HInstruction.BIT_XOR_TYPECODE; |
| 1786 bool typeEquals(other) => other is HBitXor; | 1798 bool typeEquals(other) => other is HBitXor; |
| 1787 bool dataEquals(HInstruction other) => true; | 1799 bool dataEquals(HInstruction other) => true; |
| 1788 } | 1800 } |
| 1789 | 1801 |
| 1790 class HInvokeUnary extends HInvokeStatic { | 1802 class HInvokeUnary extends HInvokeStatic { |
| 1791 HInvokeUnary(HStatic target, HInstruction input) | 1803 HInvokeUnary(HStatic target, HInstruction input) |
| 1792 : super(<HInstruction>[target, input]); | 1804 : super(<HInstruction>[target, input]); |
| 1793 | 1805 |
| 1794 HInstruction get operand => inputs[1]; | 1806 HInstruction get operand => inputs[1]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1819 // If the outgoing type should be a number (integer, double or both) we | 1831 // If the outgoing type should be a number (integer, double or both) we |
| 1820 // want the outgoing type to be the input too. | 1832 // want the outgoing type to be the input too. |
| 1821 // If we don't know the outgoing type we try to make it a number. | 1833 // If we don't know the outgoing type we try to make it a number. |
| 1822 if (propagatedType.isNumber()) return propagatedType; | 1834 if (propagatedType.isNumber()) return propagatedType; |
| 1823 if (propagatedType.isUnknown()) return HType.NUMBER; | 1835 if (propagatedType.isUnknown()) return HType.NUMBER; |
| 1824 return HType.UNKNOWN; | 1836 return HType.UNKNOWN; |
| 1825 } | 1837 } |
| 1826 | 1838 |
| 1827 HType computeLikelyType(HTypeMap types) => HType.NUMBER; | 1839 HType computeLikelyType(HTypeMap types) => HType.NUMBER; |
| 1828 | 1840 |
| 1829 abstract UnaryOperation get operation; | 1841 abstract UnaryOperation operation(ConstantSystem constantSystem); |
| 1830 } | 1842 } |
| 1831 | 1843 |
| 1832 class HNegate extends HInvokeUnary { | 1844 class HNegate extends HInvokeUnary { |
| 1833 HNegate(HStatic target, HInstruction input) : super(target, input); | 1845 HNegate(HStatic target, HInstruction input) : super(target, input); |
| 1834 accept(HVisitor visitor) => visitor.visitNegate(this); | 1846 accept(HVisitor visitor) => visitor.visitNegate(this); |
| 1835 | 1847 |
| 1836 NegateOperation get operation => const NegateOperation(); | 1848 UnaryOperation operation(ConstantSystem constantSystem) |
| 1849 => constantSystem.negate; |
| 1837 int typeCode() => HInstruction.NEGATE_TYPECODE; | 1850 int typeCode() => HInstruction.NEGATE_TYPECODE; |
| 1838 bool typeEquals(other) => other is HNegate; | 1851 bool typeEquals(other) => other is HNegate; |
| 1839 bool dataEquals(HInstruction other) => true; | 1852 bool dataEquals(HInstruction other) => true; |
| 1840 } | 1853 } |
| 1841 | 1854 |
| 1842 class HBitNot extends HInvokeUnary { | 1855 class HBitNot extends HInvokeUnary { |
| 1843 HBitNot(HStatic target, HInstruction input) : super(target, input); | 1856 HBitNot(HStatic target, HInstruction input) : super(target, input); |
| 1844 accept(HVisitor visitor) => visitor.visitBitNot(this); | 1857 accept(HVisitor visitor) => visitor.visitBitNot(this); |
| 1845 | 1858 |
| 1846 HType computeTypeFromInputTypes(HTypeMap types) { | 1859 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1847 // All bitwise operations on primitive types either produce an | 1860 // All bitwise operations on primitive types either produce an |
| 1848 // integer or throw an error. | 1861 // integer or throw an error. |
| 1849 if (operand.isPrimitive(types)) return HType.INTEGER; | 1862 if (operand.isPrimitive(types)) return HType.INTEGER; |
| 1850 return HType.UNKNOWN; | 1863 return HType.UNKNOWN; |
| 1851 } | 1864 } |
| 1852 | 1865 |
| 1853 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1866 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
| 1854 HTypeMap types) { | 1867 HTypeMap types) { |
| 1855 HType propagatedType = types[this]; | 1868 HType propagatedType = types[this]; |
| 1856 // Bit operations only work on integers. If there is no desired output | 1869 // Bit operations only work on integers. If there is no desired output |
| 1857 // type or if it as a number we want to get an integer as input. | 1870 // type or if it as a number we want to get an integer as input. |
| 1858 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 1871 if (propagatedType.isUnknown() || propagatedType.isNumber()) { |
| 1859 return HType.INTEGER; | 1872 return HType.INTEGER; |
| 1860 } | 1873 } |
| 1861 return HType.UNKNOWN; | 1874 return HType.UNKNOWN; |
| 1862 } | 1875 } |
| 1863 | 1876 |
| 1864 BitNotOperation get operation => const BitNotOperation(); | 1877 UnaryOperation operation(ConstantSystem constantSystem) |
| 1878 => constantSystem.bitNot; |
| 1865 int typeCode() => HInstruction.BIT_NOT_TYPECODE; | 1879 int typeCode() => HInstruction.BIT_NOT_TYPECODE; |
| 1866 bool typeEquals(other) => other is HBitNot; | 1880 bool typeEquals(other) => other is HBitNot; |
| 1867 bool dataEquals(HInstruction other) => true; | 1881 bool dataEquals(HInstruction other) => true; |
| 1868 } | 1882 } |
| 1869 | 1883 |
| 1870 class HExit extends HControlFlow { | 1884 class HExit extends HControlFlow { |
| 1871 HExit() : super(const <HInstruction>[]); | 1885 HExit() : super(const <HInstruction>[]); |
| 1872 toString() => 'exit'; | 1886 toString() => 'exit'; |
| 1873 accept(HVisitor visitor) => visitor.visitExit(this); | 1887 accept(HVisitor visitor) => visitor.visitExit(this); |
| 1874 } | 1888 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 } | 2168 } |
| 2155 } | 2169 } |
| 2156 return HType.UNKNOWN; | 2170 return HType.UNKNOWN; |
| 2157 } | 2171 } |
| 2158 | 2172 |
| 2159 HType computeLikelyType(HTypeMap types) => HType.BOOLEAN; | 2173 HType computeLikelyType(HTypeMap types) => HType.BOOLEAN; |
| 2160 | 2174 |
| 2161 bool isBuiltin(HTypeMap types) | 2175 bool isBuiltin(HTypeMap types) |
| 2162 => left.isNumber(types) && right.isNumber(types); | 2176 => left.isNumber(types) && right.isNumber(types); |
| 2163 // TODO(1603): the class should be marked as abstract. | 2177 // TODO(1603): the class should be marked as abstract. |
| 2164 abstract BinaryOperation get operation; | 2178 abstract BinaryOperation operation(ConstantSystem constantSystem); |
| 2165 } | 2179 } |
| 2166 | 2180 |
| 2167 class HEquals extends HRelational { | 2181 class HEquals extends HRelational { |
| 2168 HEquals(HStatic target, HInstruction left, HInstruction right) | 2182 HEquals(HStatic target, HInstruction left, HInstruction right) |
| 2169 : super(target, left, right); | 2183 : super(target, left, right); |
| 2170 accept(HVisitor visitor) => visitor.visitEquals(this); | 2184 accept(HVisitor visitor) => visitor.visitEquals(this); |
| 2171 | 2185 |
| 2172 bool isBuiltin(HTypeMap types) { | 2186 bool isBuiltin(HTypeMap types) { |
| 2173 // All primitive types have === semantics. | 2187 // All primitive types have === semantics. |
| 2174 // Note that this includes all constants except the user-constructed | 2188 // Note that this includes all constants except the user-constructed |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2201 if (input == left && left.isIndexablePrimitive(types)) { | 2215 if (input == left && left.isIndexablePrimitive(types)) { |
| 2202 return HType.READABLE_ARRAY; | 2216 return HType.READABLE_ARRAY; |
| 2203 } | 2217 } |
| 2204 // String equality testing is much more common than array equality testing. | 2218 // String equality testing is much more common than array equality testing. |
| 2205 if (input == right && right.isIndexablePrimitive(types)) { | 2219 if (input == right && right.isIndexablePrimitive(types)) { |
| 2206 return HType.STRING; | 2220 return HType.STRING; |
| 2207 } | 2221 } |
| 2208 return HType.UNKNOWN; | 2222 return HType.UNKNOWN; |
| 2209 } | 2223 } |
| 2210 | 2224 |
| 2211 EqualsOperation get operation => const EqualsOperation(); | 2225 BinaryOperation operation(ConstantSystem constantSystem) |
| 2226 => constantSystem.equal; |
| 2212 int typeCode() => HInstruction.EQUALS_TYPECODE; | 2227 int typeCode() => HInstruction.EQUALS_TYPECODE; |
| 2213 bool typeEquals(other) => other is HEquals; | 2228 bool typeEquals(other) => other is HEquals; |
| 2214 bool dataEquals(HInstruction other) => true; | 2229 bool dataEquals(HInstruction other) => true; |
| 2215 } | 2230 } |
| 2216 | 2231 |
| 2217 class HIdentity extends HRelational { | 2232 class HIdentity extends HRelational { |
| 2218 HIdentity(HStatic target, HInstruction left, HInstruction right) | 2233 HIdentity(HStatic target, HInstruction left, HInstruction right) |
| 2219 : super(target, left, right); | 2234 : super(target, left, right); |
| 2220 accept(HVisitor visitor) => visitor.visitIdentity(this); | 2235 accept(HVisitor visitor) => visitor.visitIdentity(this); |
| 2221 | 2236 |
| 2222 bool isBuiltin(HTypeMap types) => true; | 2237 bool isBuiltin(HTypeMap types) => true; |
| 2223 | 2238 |
| 2224 HType get guaranteedType => HType.BOOLEAN; | 2239 HType get guaranteedType => HType.BOOLEAN; |
| 2225 HType computeTypeFromInputTypes(HTypeMap types) | 2240 HType computeTypeFromInputTypes(HTypeMap types) |
| 2226 => HType.BOOLEAN; | 2241 => HType.BOOLEAN; |
| 2227 // Note that the identity operator really does not care for its input types. | 2242 // Note that the identity operator really does not care for its input types. |
| 2228 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) | 2243 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) |
| 2229 => HType.UNKNOWN; | 2244 => HType.UNKNOWN; |
| 2230 | 2245 |
| 2231 IdentityOperation get operation => const IdentityOperation(); | 2246 BinaryOperation operation(ConstantSystem constantSystem) |
| 2247 => constantSystem.identity; |
| 2232 int typeCode() => HInstruction.IDENTITY_TYPECODE; | 2248 int typeCode() => HInstruction.IDENTITY_TYPECODE; |
| 2233 bool typeEquals(other) => other is HIdentity; | 2249 bool typeEquals(other) => other is HIdentity; |
| 2234 bool dataEquals(HInstruction other) => true; | 2250 bool dataEquals(HInstruction other) => true; |
| 2235 } | 2251 } |
| 2236 | 2252 |
| 2237 class HGreater extends HRelational { | 2253 class HGreater extends HRelational { |
| 2238 HGreater(HStatic target, HInstruction left, HInstruction right) | 2254 HGreater(HStatic target, HInstruction left, HInstruction right) |
| 2239 : super(target, left, right); | 2255 : super(target, left, right); |
| 2240 accept(HVisitor visitor) => visitor.visitGreater(this); | 2256 accept(HVisitor visitor) => visitor.visitGreater(this); |
| 2241 | 2257 |
| 2242 GreaterOperation get operation => const GreaterOperation(); | 2258 BinaryOperation operation(ConstantSystem constantSystem) |
| 2259 => constantSystem.greater; |
| 2243 int typeCode() => HInstruction.GREATER_TYPECODE; | 2260 int typeCode() => HInstruction.GREATER_TYPECODE; |
| 2244 bool typeEquals(other) => other is HGreater; | 2261 bool typeEquals(other) => other is HGreater; |
| 2245 bool dataEquals(HInstruction other) => true; | 2262 bool dataEquals(HInstruction other) => true; |
| 2246 } | 2263 } |
| 2247 | 2264 |
| 2248 class HGreaterEqual extends HRelational { | 2265 class HGreaterEqual extends HRelational { |
| 2249 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) | 2266 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) |
| 2250 : super(target, left, right); | 2267 : super(target, left, right); |
| 2251 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); | 2268 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); |
| 2252 | 2269 |
| 2253 GreaterEqualOperation get operation => const GreaterEqualOperation(); | 2270 BinaryOperation operation(ConstantSystem constantSystem) |
| 2271 => constantSystem.greaterEqual; |
| 2254 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; | 2272 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; |
| 2255 bool typeEquals(other) => other is HGreaterEqual; | 2273 bool typeEquals(other) => other is HGreaterEqual; |
| 2256 bool dataEquals(HInstruction other) => true; | 2274 bool dataEquals(HInstruction other) => true; |
| 2257 } | 2275 } |
| 2258 | 2276 |
| 2259 class HLess extends HRelational { | 2277 class HLess extends HRelational { |
| 2260 HLess(HStatic target, HInstruction left, HInstruction right) | 2278 HLess(HStatic target, HInstruction left, HInstruction right) |
| 2261 : super(target, left, right); | 2279 : super(target, left, right); |
| 2262 accept(HVisitor visitor) => visitor.visitLess(this); | 2280 accept(HVisitor visitor) => visitor.visitLess(this); |
| 2263 | 2281 |
| 2264 LessOperation get operation => const LessOperation(); | 2282 BinaryOperation operation(ConstantSystem constantSystem) |
| 2283 => constantSystem.less; |
| 2265 int typeCode() => HInstruction.LESS_TYPECODE; | 2284 int typeCode() => HInstruction.LESS_TYPECODE; |
| 2266 bool typeEquals(other) => other is HLess; | 2285 bool typeEquals(other) => other is HLess; |
| 2267 bool dataEquals(HInstruction other) => true; | 2286 bool dataEquals(HInstruction other) => true; |
| 2268 } | 2287 } |
| 2269 | 2288 |
| 2270 class HLessEqual extends HRelational { | 2289 class HLessEqual extends HRelational { |
| 2271 HLessEqual(HStatic target, HInstruction left, HInstruction right) | 2290 HLessEqual(HStatic target, HInstruction left, HInstruction right) |
| 2272 : super(target, left, right); | 2291 : super(target, left, right); |
| 2273 accept(HVisitor visitor) => visitor.visitLessEqual(this); | 2292 accept(HVisitor visitor) => visitor.visitLessEqual(this); |
| 2274 | 2293 |
| 2275 LessEqualOperation get operation => const LessEqualOperation(); | 2294 BinaryOperation operation(ConstantSystem constantSystem) |
| 2295 => constantSystem.lessEqual; |
| 2276 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; | 2296 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; |
| 2277 bool typeEquals(other) => other is HLessEqual; | 2297 bool typeEquals(other) => other is HLessEqual; |
| 2278 bool dataEquals(HInstruction other) => true; | 2298 bool dataEquals(HInstruction other) => true; |
| 2279 } | 2299 } |
| 2280 | 2300 |
| 2281 class HReturn extends HControlFlow { | 2301 class HReturn extends HControlFlow { |
| 2282 HReturn(value) : super(<HInstruction>[value]); | 2302 HReturn(value) : super(<HInstruction>[value]); |
| 2283 toString() => 'return'; | 2303 toString() => 'return'; |
| 2284 accept(HVisitor visitor) => visitor.visitReturn(this); | 2304 accept(HVisitor visitor) => visitor.visitReturn(this); |
| 2285 } | 2305 } |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2821 HBasicBlock get start => expression.start; | 2841 HBasicBlock get start => expression.start; |
| 2822 HBasicBlock get end { | 2842 HBasicBlock get end { |
| 2823 // We don't create a switch block if there are no cases. | 2843 // We don't create a switch block if there are no cases. |
| 2824 assert(!statements.isEmpty()); | 2844 assert(!statements.isEmpty()); |
| 2825 return statements.last().end; | 2845 return statements.last().end; |
| 2826 } | 2846 } |
| 2827 | 2847 |
| 2828 bool accept(HStatementInformationVisitor visitor) => | 2848 bool accept(HStatementInformationVisitor visitor) => |
| 2829 visitor.visitSwitchInfo(this); | 2849 visitor.visitSwitchInfo(this); |
| 2830 } | 2850 } |
| OLD | NEW |