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 |