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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 HConstant result = constants[constant]; | 171 HConstant result = constants[constant]; |
172 if (result === null) { | 172 if (result === null) { |
173 HType type = mapConstantTypeToSsaType(constant); | 173 HType type = mapConstantTypeToSsaType(constant); |
174 result = new HConstant.internal(constant, type); | 174 result = new HConstant.internal(constant, type); |
175 entry.addAtExit(result); | 175 entry.addAtExit(result); |
176 constants[constant] = result; | 176 constants[constant] = result; |
177 } | 177 } |
178 return result; | 178 return result; |
179 } | 179 } |
180 | 180 |
181 HConstant addConstantInt(int i) { | |
ngeoffray
2012/09/05 11:20:36
I would keep these helpers, and pass the backend o
floitsch
2012/09/05 16:12:01
Kept them, but they want the constantSystem.
| |
182 return addConstant(new IntConstant(i)); | |
183 } | |
184 | |
185 HConstant addConstantDouble(double d) { | |
186 return addConstant(new DoubleConstant(d)); | |
187 } | |
188 | |
189 HConstant addConstantString(DartString str, Node node) { | |
190 return addConstant(new StringConstant(str, node)); | |
191 } | |
192 | |
193 HConstant addConstantBool(bool value) { | |
194 return addConstant(new BoolConstant(value)); | |
195 } | |
196 | |
197 HConstant addConstantNull() { | |
198 return addConstant(new NullConstant()); | |
199 } | |
200 | |
201 void finalize() { | 181 void finalize() { |
202 addBlock(exit); | 182 addBlock(exit); |
203 exit.open(); | 183 exit.open(); |
204 exit.close(new HExit()); | 184 exit.close(new HExit()); |
205 assignDominators(); | 185 assignDominators(); |
206 } | 186 } |
207 | 187 |
208 void assignDominators() { | 188 void assignDominators() { |
209 // Run through the blocks in order of increasing ids so we are | 189 // Run through the blocks in order of increasing ids so we are |
210 // guaranteed that we have computed dominators for all blocks | 190 // guaranteed that we have computed dominators for all blocks |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1508 accept(HVisitor visitor) => visitor.visitForeignNew(this); | 1488 accept(HVisitor visitor) => visitor.visitForeignNew(this); |
1509 } | 1489 } |
1510 | 1490 |
1511 class HInvokeBinary extends HInvokeStatic { | 1491 class HInvokeBinary extends HInvokeStatic { |
1512 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) | 1492 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) |
1513 : super(<HInstruction>[target, left, right]); | 1493 : super(<HInstruction>[target, left, right]); |
1514 | 1494 |
1515 HInstruction get left => inputs[1]; | 1495 HInstruction get left => inputs[1]; |
1516 HInstruction get right => inputs[2]; | 1496 HInstruction get right => inputs[2]; |
1517 | 1497 |
1518 abstract BinaryOperation get operation; | 1498 abstract BinaryOperation operation(ConstantSystem constantSystem); |
1519 abstract isBuiltin(HTypeMap types); | 1499 abstract isBuiltin(HTypeMap types); |
1520 } | 1500 } |
1521 | 1501 |
1522 class HBinaryArithmetic extends HInvokeBinary { | 1502 class HBinaryArithmetic extends HInvokeBinary { |
1523 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) | 1503 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) |
1524 : super(target, left, right); | 1504 : super(target, left, right); |
1525 | 1505 |
1526 void prepareGvn(HTypeMap types) { | 1506 void prepareGvn(HTypeMap types) { |
1527 // An arithmetic expression can take part in global value | 1507 // An arithmetic expression can take part in global value |
1528 // numbering and do not have any side-effects if we know that all | 1508 // 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... | |
1569 if (input == right && left.isNumber(types)) return HType.NUMBER; | 1549 if (input == right && left.isNumber(types)) return HType.NUMBER; |
1570 return HType.UNKNOWN; | 1550 return HType.UNKNOWN; |
1571 } | 1551 } |
1572 | 1552 |
1573 HType computeLikelyType(HTypeMap types) { | 1553 HType computeLikelyType(HTypeMap types) { |
1574 if (left.isTypeUnknown(types)) return HType.NUMBER; | 1554 if (left.isTypeUnknown(types)) return HType.NUMBER; |
1575 return HType.UNKNOWN; | 1555 return HType.UNKNOWN; |
1576 } | 1556 } |
1577 | 1557 |
1578 // TODO(1603): The class should be marked as abstract. | 1558 // TODO(1603): The class should be marked as abstract. |
1579 abstract BinaryOperation get operation; | 1559 abstract BinaryOperation operation(ConstantSystem constantSystem); |
1580 } | 1560 } |
1581 | 1561 |
1582 class HAdd extends HBinaryArithmetic { | 1562 class HAdd extends HBinaryArithmetic { |
1583 HAdd(HStatic target, HInstruction left, HInstruction right) | 1563 HAdd(HStatic target, HInstruction left, HInstruction right) |
1584 : super(target, left, right); | 1564 : super(target, left, right); |
1585 accept(HVisitor visitor) => visitor.visitAdd(this); | 1565 accept(HVisitor visitor) => visitor.visitAdd(this); |
1586 | 1566 |
1587 AddOperation get operation => const AddOperation(); | 1567 BinaryOperation operation(ConstantSystem constantSystem) |
1568 => constantSystem.add; | |
1588 int typeCode() => HInstruction.ADD_TYPECODE; | 1569 int typeCode() => HInstruction.ADD_TYPECODE; |
1589 bool typeEquals(other) => other is HAdd; | 1570 bool typeEquals(other) => other is HAdd; |
1590 bool dataEquals(HInstruction other) => true; | 1571 bool dataEquals(HInstruction other) => true; |
1591 } | 1572 } |
1592 | 1573 |
1593 class HDivide extends HBinaryArithmetic { | 1574 class HDivide extends HBinaryArithmetic { |
1594 HDivide(HStatic target, HInstruction left, HInstruction right) | 1575 HDivide(HStatic target, HInstruction left, HInstruction right) |
1595 : super(target, left, right); | 1576 : super(target, left, right); |
1596 accept(HVisitor visitor) => visitor.visitDivide(this); | 1577 accept(HVisitor visitor) => visitor.visitDivide(this); |
1597 | 1578 |
1598 HType computeTypeFromInputTypes(HTypeMap types) { | 1579 HType computeTypeFromInputTypes(HTypeMap types) { |
1599 if (left.isNumber(types)) return HType.DOUBLE; | 1580 if (left.isNumber(types)) return HType.DOUBLE; |
1600 return HType.UNKNOWN; | 1581 return HType.UNKNOWN; |
1601 } | 1582 } |
1602 | 1583 |
1603 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1584 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
1604 HTypeMap types) { | 1585 HTypeMap types) { |
1605 // A division can never return an integer. So don't ask for integer inputs. | 1586 // A division can never return an integer. So don't ask for integer inputs. |
1606 if (isInteger(types)) return HType.UNKNOWN; | 1587 if (isInteger(types)) return HType.UNKNOWN; |
1607 return super.computeDesiredTypeForNonTargetInput(input, types); | 1588 return super.computeDesiredTypeForNonTargetInput(input, types); |
1608 } | 1589 } |
1609 | 1590 |
1610 DivideOperation get operation => const DivideOperation(); | 1591 BinaryOperation operation(ConstantSystem constantSystem) |
1592 => constantSystem.divide; | |
1611 int typeCode() => HInstruction.DIVIDE_TYPECODE; | 1593 int typeCode() => HInstruction.DIVIDE_TYPECODE; |
1612 bool typeEquals(other) => other is HDivide; | 1594 bool typeEquals(other) => other is HDivide; |
1613 bool dataEquals(HInstruction other) => true; | 1595 bool dataEquals(HInstruction other) => true; |
1614 } | 1596 } |
1615 | 1597 |
1616 class HModulo extends HBinaryArithmetic { | 1598 class HModulo extends HBinaryArithmetic { |
1617 HModulo(HStatic target, HInstruction left, HInstruction right) | 1599 HModulo(HStatic target, HInstruction left, HInstruction right) |
1618 : super(target, left, right); | 1600 : super(target, left, right); |
1619 accept(HVisitor visitor) => visitor.visitModulo(this); | 1601 accept(HVisitor visitor) => visitor.visitModulo(this); |
1620 | 1602 |
1621 ModuloOperation get operation => const ModuloOperation(); | 1603 BinaryOperation operation(ConstantSystem constantSystem) |
1604 => constantSystem.modulo; | |
1622 int typeCode() => HInstruction.MODULO_TYPECODE; | 1605 int typeCode() => HInstruction.MODULO_TYPECODE; |
1623 bool typeEquals(other) => other is HModulo; | 1606 bool typeEquals(other) => other is HModulo; |
1624 bool dataEquals(HInstruction other) => true; | 1607 bool dataEquals(HInstruction other) => true; |
1625 } | 1608 } |
1626 | 1609 |
1627 class HMultiply extends HBinaryArithmetic { | 1610 class HMultiply extends HBinaryArithmetic { |
1628 HMultiply(HStatic target, HInstruction left, HInstruction right) | 1611 HMultiply(HStatic target, HInstruction left, HInstruction right) |
1629 : super(target, left, right); | 1612 : super(target, left, right); |
1630 accept(HVisitor visitor) => visitor.visitMultiply(this); | 1613 accept(HVisitor visitor) => visitor.visitMultiply(this); |
1631 | 1614 |
1632 MultiplyOperation get operation => const MultiplyOperation(); | 1615 BinaryOperation operation(ConstantSystem operations) |
1616 => operations.multiply; | |
1633 int typeCode() => HInstruction.MULTIPLY_TYPECODE; | 1617 int typeCode() => HInstruction.MULTIPLY_TYPECODE; |
1634 bool typeEquals(other) => other is HMultiply; | 1618 bool typeEquals(other) => other is HMultiply; |
1635 bool dataEquals(HInstruction other) => true; | 1619 bool dataEquals(HInstruction other) => true; |
1636 } | 1620 } |
1637 | 1621 |
1638 class HSubtract extends HBinaryArithmetic { | 1622 class HSubtract extends HBinaryArithmetic { |
1639 HSubtract(HStatic target, HInstruction left, HInstruction right) | 1623 HSubtract(HStatic target, HInstruction left, HInstruction right) |
1640 : super(target, left, right); | 1624 : super(target, left, right); |
1641 accept(HVisitor visitor) => visitor.visitSubtract(this); | 1625 accept(HVisitor visitor) => visitor.visitSubtract(this); |
1642 | 1626 |
1643 SubtractOperation get operation => const SubtractOperation(); | 1627 BinaryOperation operation(ConstantSystem constantSystem) |
1628 => constantSystem.subtract; | |
1644 int typeCode() => HInstruction.SUBTRACT_TYPECODE; | 1629 int typeCode() => HInstruction.SUBTRACT_TYPECODE; |
1645 bool typeEquals(other) => other is HSubtract; | 1630 bool typeEquals(other) => other is HSubtract; |
1646 bool dataEquals(HInstruction other) => true; | 1631 bool dataEquals(HInstruction other) => true; |
1647 } | 1632 } |
1648 | 1633 |
1649 /** | 1634 /** |
1650 * An [HSwitch] instruction has one input for the incoming | 1635 * An [HSwitch] instruction has one input for the incoming |
1651 * value, and one input per constant that it can switch on. | 1636 * value, and one input per constant that it can switch on. |
1652 * Its block has one successor per constant, and one for the default. | 1637 * Its block has one successor per constant, and one for the default. |
1653 */ | 1638 */ |
(...skipping 13 matching lines...) Expand all Loading... | |
1667 accept(HVisitor visitor) => visitor.visitSwitch(this); | 1652 accept(HVisitor visitor) => visitor.visitSwitch(this); |
1668 | 1653 |
1669 String toString() => "HSwitch cases = $inputs"; | 1654 String toString() => "HSwitch cases = $inputs"; |
1670 } | 1655 } |
1671 | 1656 |
1672 class HTruncatingDivide extends HBinaryArithmetic { | 1657 class HTruncatingDivide extends HBinaryArithmetic { |
1673 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) | 1658 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) |
1674 : super(target, left, right); | 1659 : super(target, left, right); |
1675 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); | 1660 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); |
1676 | 1661 |
1677 TruncatingDivideOperation get operation | 1662 BinaryOperation operation(ConstantSystem constantSystem) |
1678 => const TruncatingDivideOperation(); | 1663 => constantSystem.truncatingDivide; |
1679 int typeCode() => HInstruction.TRUNCATING_DIVIDE_TYPECODE; | 1664 int typeCode() => HInstruction.TRUNCATING_DIVIDE_TYPECODE; |
1680 bool typeEquals(other) => other is HTruncatingDivide; | 1665 bool typeEquals(other) => other is HTruncatingDivide; |
1681 bool dataEquals(HInstruction other) => true; | 1666 bool dataEquals(HInstruction other) => true; |
1682 } | 1667 } |
1683 | 1668 |
1684 | 1669 |
1685 // TODO(floitsch): Should HBinaryArithmetic really be the super class of | 1670 // TODO(floitsch): Should HBinaryArithmetic really be the super class of |
1686 // HBinaryBitOp? | 1671 // HBinaryBitOp? |
1687 class HBinaryBitOp extends HBinaryArithmetic { | 1672 class HBinaryBitOp extends HBinaryArithmetic { |
1688 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) | 1673 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1724 // Shift left cannot be mapped to the native operator unless the | 1709 // Shift left cannot be mapped to the native operator unless the |
1725 // shift count is guaranteed to be an integer in the [0,31] range. | 1710 // shift count is guaranteed to be an integer in the [0,31] range. |
1726 bool isBuiltin(HTypeMap types) { | 1711 bool isBuiltin(HTypeMap types) { |
1727 if (!left.isNumber(types) || !right.isConstantInteger()) return false; | 1712 if (!left.isNumber(types) || !right.isConstantInteger()) return false; |
1728 HConstant rightConstant = right; | 1713 HConstant rightConstant = right; |
1729 IntConstant intConstant = rightConstant.constant; | 1714 IntConstant intConstant = rightConstant.constant; |
1730 int count = intConstant.value; | 1715 int count = intConstant.value; |
1731 return count >= 0 && count <= 31; | 1716 return count >= 0 && count <= 31; |
1732 } | 1717 } |
1733 | 1718 |
1734 ShiftLeftOperation get operation => const ShiftLeftOperation(); | 1719 BinaryOperation operation(ConstantSystem constantSystem) |
1720 => constantSystem.shiftLeft; | |
1735 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; | 1721 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; |
1736 bool typeEquals(other) => other is HShiftLeft; | 1722 bool typeEquals(other) => other is HShiftLeft; |
1737 bool dataEquals(HInstruction other) => true; | 1723 bool dataEquals(HInstruction other) => true; |
1738 } | 1724 } |
1739 | 1725 |
1740 class HShiftRight extends HBinaryBitOp { | 1726 class HShiftRight extends HBinaryBitOp { |
1741 HShiftRight(HStatic target, HInstruction left, HInstruction right) | 1727 HShiftRight(HStatic target, HInstruction left, HInstruction right) |
1742 : super(target, left, right); | 1728 : super(target, left, right); |
1743 accept(HVisitor visitor) => visitor.visitShiftRight(this); | 1729 accept(HVisitor visitor) => visitor.visitShiftRight(this); |
1744 | 1730 |
1745 // Shift right cannot be mapped to the native operator easily. | 1731 // Shift right cannot be mapped to the native operator easily. |
1746 bool isBuiltin(HTypeMap types) => false; | 1732 bool isBuiltin(HTypeMap types) => false; |
1747 | 1733 |
1748 ShiftRightOperation get operation => const ShiftRightOperation(); | 1734 BinaryOperation operation(ConstantSystem constantSystem) |
1735 => constantSystem.shiftRight; | |
1749 int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE; | 1736 int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE; |
1750 bool typeEquals(other) => other is HShiftRight; | 1737 bool typeEquals(other) => other is HShiftRight; |
1751 bool dataEquals(HInstruction other) => true; | 1738 bool dataEquals(HInstruction other) => true; |
1752 } | 1739 } |
1753 | 1740 |
1754 class HBitOr extends HBinaryBitOp { | 1741 class HBitOr extends HBinaryBitOp { |
1755 HBitOr(HStatic target, HInstruction left, HInstruction right) | 1742 HBitOr(HStatic target, HInstruction left, HInstruction right) |
1756 : super(target, left, right); | 1743 : super(target, left, right); |
1757 accept(HVisitor visitor) => visitor.visitBitOr(this); | 1744 accept(HVisitor visitor) => visitor.visitBitOr(this); |
1758 | 1745 |
1759 BitOrOperation get operation => const BitOrOperation(); | 1746 BinaryOperation operation(ConstantSystem constantSystem) |
1747 => constantSystem.bitOr; | |
1760 int typeCode() => HInstruction.BIT_OR_TYPECODE; | 1748 int typeCode() => HInstruction.BIT_OR_TYPECODE; |
1761 bool typeEquals(other) => other is HBitOr; | 1749 bool typeEquals(other) => other is HBitOr; |
1762 bool dataEquals(HInstruction other) => true; | 1750 bool dataEquals(HInstruction other) => true; |
1763 } | 1751 } |
1764 | 1752 |
1765 class HBitAnd extends HBinaryBitOp { | 1753 class HBitAnd extends HBinaryBitOp { |
1766 HBitAnd(HStatic target, HInstruction left, HInstruction right) | 1754 HBitAnd(HStatic target, HInstruction left, HInstruction right) |
1767 : super(target, left, right); | 1755 : super(target, left, right); |
1768 accept(HVisitor visitor) => visitor.visitBitAnd(this); | 1756 accept(HVisitor visitor) => visitor.visitBitAnd(this); |
1769 | 1757 |
1770 BitAndOperation get operation => const BitAndOperation(); | 1758 BinaryOperation operation(ConstantSystem constantSystem) |
1759 => constantSystem.bitAnd; | |
1771 int typeCode() => HInstruction.BIT_AND_TYPECODE; | 1760 int typeCode() => HInstruction.BIT_AND_TYPECODE; |
1772 bool typeEquals(other) => other is HBitAnd; | 1761 bool typeEquals(other) => other is HBitAnd; |
1773 bool dataEquals(HInstruction other) => true; | 1762 bool dataEquals(HInstruction other) => true; |
1774 } | 1763 } |
1775 | 1764 |
1776 class HBitXor extends HBinaryBitOp { | 1765 class HBitXor extends HBinaryBitOp { |
1777 HBitXor(HStatic target, HInstruction left, HInstruction right) | 1766 HBitXor(HStatic target, HInstruction left, HInstruction right) |
1778 : super(target, left, right); | 1767 : super(target, left, right); |
1779 accept(HVisitor visitor) => visitor.visitBitXor(this); | 1768 accept(HVisitor visitor) => visitor.visitBitXor(this); |
1780 | 1769 |
1781 BitXorOperation get operation => const BitXorOperation(); | 1770 BinaryOperation operation(ConstantSystem constantSystem) |
1771 => constantSystem.bitXor; | |
1782 int typeCode() => HInstruction.BIT_XOR_TYPECODE; | 1772 int typeCode() => HInstruction.BIT_XOR_TYPECODE; |
1783 bool typeEquals(other) => other is HBitXor; | 1773 bool typeEquals(other) => other is HBitXor; |
1784 bool dataEquals(HInstruction other) => true; | 1774 bool dataEquals(HInstruction other) => true; |
1785 } | 1775 } |
1786 | 1776 |
1787 class HInvokeUnary extends HInvokeStatic { | 1777 class HInvokeUnary extends HInvokeStatic { |
1788 HInvokeUnary(HStatic target, HInstruction input) | 1778 HInvokeUnary(HStatic target, HInstruction input) |
1789 : super(<HInstruction>[target, input]); | 1779 : super(<HInstruction>[target, input]); |
1790 | 1780 |
1791 HInstruction get operand => inputs[1]; | 1781 HInstruction get operand => inputs[1]; |
(...skipping 24 matching lines...) Expand all Loading... | |
1816 // If the outgoing type should be a number (integer, double or both) we | 1806 // If the outgoing type should be a number (integer, double or both) we |
1817 // want the outgoing type to be the input too. | 1807 // want the outgoing type to be the input too. |
1818 // If we don't know the outgoing type we try to make it a number. | 1808 // If we don't know the outgoing type we try to make it a number. |
1819 if (propagatedType.isNumber()) return propagatedType; | 1809 if (propagatedType.isNumber()) return propagatedType; |
1820 if (propagatedType.isUnknown()) return HType.NUMBER; | 1810 if (propagatedType.isUnknown()) return HType.NUMBER; |
1821 return HType.UNKNOWN; | 1811 return HType.UNKNOWN; |
1822 } | 1812 } |
1823 | 1813 |
1824 HType computeLikelyType(HTypeMap types) => HType.NUMBER; | 1814 HType computeLikelyType(HTypeMap types) => HType.NUMBER; |
1825 | 1815 |
1826 abstract UnaryOperation get operation; | 1816 abstract UnaryOperation operation(ConstantSystem constantSystem); |
1827 } | 1817 } |
1828 | 1818 |
1829 class HNegate extends HInvokeUnary { | 1819 class HNegate extends HInvokeUnary { |
1830 HNegate(HStatic target, HInstruction input) : super(target, input); | 1820 HNegate(HStatic target, HInstruction input) : super(target, input); |
1831 accept(HVisitor visitor) => visitor.visitNegate(this); | 1821 accept(HVisitor visitor) => visitor.visitNegate(this); |
1832 | 1822 |
1833 NegateOperation get operation => const NegateOperation(); | 1823 UnaryOperation operation(ConstantSystem constantSystem) |
1824 => constantSystem.negate; | |
1834 int typeCode() => HInstruction.NEGATE_TYPECODE; | 1825 int typeCode() => HInstruction.NEGATE_TYPECODE; |
1835 bool typeEquals(other) => other is HNegate; | 1826 bool typeEquals(other) => other is HNegate; |
1836 bool dataEquals(HInstruction other) => true; | 1827 bool dataEquals(HInstruction other) => true; |
1837 } | 1828 } |
1838 | 1829 |
1839 class HBitNot extends HInvokeUnary { | 1830 class HBitNot extends HInvokeUnary { |
1840 HBitNot(HStatic target, HInstruction input) : super(target, input); | 1831 HBitNot(HStatic target, HInstruction input) : super(target, input); |
1841 accept(HVisitor visitor) => visitor.visitBitNot(this); | 1832 accept(HVisitor visitor) => visitor.visitBitNot(this); |
1842 | 1833 |
1843 HType computeTypeFromInputTypes(HTypeMap types) { | 1834 HType computeTypeFromInputTypes(HTypeMap types) { |
1844 // All bitwise operations on primitive types either produce an | 1835 // All bitwise operations on primitive types either produce an |
1845 // integer or throw an error. | 1836 // integer or throw an error. |
1846 if (operand.isPrimitive(types)) return HType.INTEGER; | 1837 if (operand.isPrimitive(types)) return HType.INTEGER; |
1847 return HType.UNKNOWN; | 1838 return HType.UNKNOWN; |
1848 } | 1839 } |
1849 | 1840 |
1850 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1841 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
1851 HTypeMap types) { | 1842 HTypeMap types) { |
1852 HType propagatedType = types[this]; | 1843 HType propagatedType = types[this]; |
1853 // Bit operations only work on integers. If there is no desired output | 1844 // Bit operations only work on integers. If there is no desired output |
1854 // type or if it as a number we want to get an integer as input. | 1845 // type or if it as a number we want to get an integer as input. |
1855 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 1846 if (propagatedType.isUnknown() || propagatedType.isNumber()) { |
1856 return HType.INTEGER; | 1847 return HType.INTEGER; |
1857 } | 1848 } |
1858 return HType.UNKNOWN; | 1849 return HType.UNKNOWN; |
1859 } | 1850 } |
1860 | 1851 |
1861 BitNotOperation get operation => const BitNotOperation(); | 1852 UnaryOperation operation(ConstantSystem constantSystem) |
1853 => constantSystem.bitNot; | |
1862 int typeCode() => HInstruction.BIT_NOT_TYPECODE; | 1854 int typeCode() => HInstruction.BIT_NOT_TYPECODE; |
1863 bool typeEquals(other) => other is HBitNot; | 1855 bool typeEquals(other) => other is HBitNot; |
1864 bool dataEquals(HInstruction other) => true; | 1856 bool dataEquals(HInstruction other) => true; |
1865 } | 1857 } |
1866 | 1858 |
1867 class HExit extends HControlFlow { | 1859 class HExit extends HControlFlow { |
1868 HExit() : super(const <HInstruction>[]); | 1860 HExit() : super(const <HInstruction>[]); |
1869 toString() => 'exit'; | 1861 toString() => 'exit'; |
1870 accept(HVisitor visitor) => visitor.visitExit(this); | 1862 accept(HVisitor visitor) => visitor.visitExit(this); |
1871 } | 1863 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2150 } | 2142 } |
2151 } | 2143 } |
2152 return HType.UNKNOWN; | 2144 return HType.UNKNOWN; |
2153 } | 2145 } |
2154 | 2146 |
2155 HType computeLikelyType(HTypeMap types) => HType.BOOLEAN; | 2147 HType computeLikelyType(HTypeMap types) => HType.BOOLEAN; |
2156 | 2148 |
2157 bool isBuiltin(HTypeMap types) | 2149 bool isBuiltin(HTypeMap types) |
2158 => left.isNumber(types) && right.isNumber(types); | 2150 => left.isNumber(types) && right.isNumber(types); |
2159 // TODO(1603): the class should be marked as abstract. | 2151 // TODO(1603): the class should be marked as abstract. |
2160 abstract BinaryOperation get operation; | 2152 abstract BinaryOperation operation(ConstantSystem constantSystem); |
2161 } | 2153 } |
2162 | 2154 |
2163 class HEquals extends HRelational { | 2155 class HEquals extends HRelational { |
2164 HEquals(HStatic target, HInstruction left, HInstruction right) | 2156 HEquals(HStatic target, HInstruction left, HInstruction right) |
2165 : super(target, left, right); | 2157 : super(target, left, right); |
2166 accept(HVisitor visitor) => visitor.visitEquals(this); | 2158 accept(HVisitor visitor) => visitor.visitEquals(this); |
2167 | 2159 |
2168 bool isBuiltin(HTypeMap types) { | 2160 bool isBuiltin(HTypeMap types) { |
2169 // All primitive types have === semantics. | 2161 // All primitive types have === semantics. |
2170 // Note that this includes all constants except the user-constructed | 2162 // Note that this includes all constants except the user-constructed |
(...skipping 28 matching lines...) Expand all Loading... | |
2199 if (input == left && left.isIndexablePrimitive(types)) { | 2191 if (input == left && left.isIndexablePrimitive(types)) { |
2200 return HType.READABLE_ARRAY; | 2192 return HType.READABLE_ARRAY; |
2201 } | 2193 } |
2202 // String equality testing is much more common than array equality testing. | 2194 // String equality testing is much more common than array equality testing. |
2203 if (input == right && right.isIndexablePrimitive(types)) { | 2195 if (input == right && right.isIndexablePrimitive(types)) { |
2204 return HType.STRING; | 2196 return HType.STRING; |
2205 } | 2197 } |
2206 return HType.UNKNOWN; | 2198 return HType.UNKNOWN; |
2207 } | 2199 } |
2208 | 2200 |
2209 EqualsOperation get operation => const EqualsOperation(); | 2201 BinaryOperation operation(ConstantSystem constantSystem) |
2202 => constantSystem.equal; | |
2210 int typeCode() => HInstruction.EQUALS_TYPECODE; | 2203 int typeCode() => HInstruction.EQUALS_TYPECODE; |
2211 bool typeEquals(other) => other is HEquals; | 2204 bool typeEquals(other) => other is HEquals; |
2212 bool dataEquals(HInstruction other) => true; | 2205 bool dataEquals(HInstruction other) => true; |
2213 } | 2206 } |
2214 | 2207 |
2215 class HIdentity extends HRelational { | 2208 class HIdentity extends HRelational { |
2216 HIdentity(HStatic target, HInstruction left, HInstruction right) | 2209 HIdentity(HStatic target, HInstruction left, HInstruction right) |
2217 : super(target, left, right); | 2210 : super(target, left, right); |
2218 accept(HVisitor visitor) => visitor.visitIdentity(this); | 2211 accept(HVisitor visitor) => visitor.visitIdentity(this); |
2219 | 2212 |
2220 bool isBuiltin(HTypeMap types) => true; | 2213 bool isBuiltin(HTypeMap types) => true; |
2221 | 2214 |
2222 HType get guaranteedType => HType.BOOLEAN; | 2215 HType get guaranteedType => HType.BOOLEAN; |
2223 HType computeTypeFromInputTypes(HTypeMap types) | 2216 HType computeTypeFromInputTypes(HTypeMap types) |
2224 => HType.BOOLEAN; | 2217 => HType.BOOLEAN; |
2225 // Note that the identity operator really does not care for its input types. | 2218 // Note that the identity operator really does not care for its input types. |
2226 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) | 2219 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) |
2227 => HType.UNKNOWN; | 2220 => HType.UNKNOWN; |
2228 | 2221 |
2229 IdentityOperation get operation => const IdentityOperation(); | 2222 BinaryOperation operation(ConstantSystem constantSystem) |
2223 => constantSystem.identity; | |
2230 int typeCode() => HInstruction.IDENTITY_TYPECODE; | 2224 int typeCode() => HInstruction.IDENTITY_TYPECODE; |
2231 bool typeEquals(other) => other is HIdentity; | 2225 bool typeEquals(other) => other is HIdentity; |
2232 bool dataEquals(HInstruction other) => true; | 2226 bool dataEquals(HInstruction other) => true; |
2233 } | 2227 } |
2234 | 2228 |
2235 class HGreater extends HRelational { | 2229 class HGreater extends HRelational { |
2236 HGreater(HStatic target, HInstruction left, HInstruction right) | 2230 HGreater(HStatic target, HInstruction left, HInstruction right) |
2237 : super(target, left, right); | 2231 : super(target, left, right); |
2238 accept(HVisitor visitor) => visitor.visitGreater(this); | 2232 accept(HVisitor visitor) => visitor.visitGreater(this); |
2239 | 2233 |
2240 GreaterOperation get operation => const GreaterOperation(); | 2234 BinaryOperation operation(ConstantSystem constantSystem) |
2235 => constantSystem.greater; | |
2241 int typeCode() => HInstruction.GREATER_TYPECODE; | 2236 int typeCode() => HInstruction.GREATER_TYPECODE; |
2242 bool typeEquals(other) => other is HGreater; | 2237 bool typeEquals(other) => other is HGreater; |
2243 bool dataEquals(HInstruction other) => true; | 2238 bool dataEquals(HInstruction other) => true; |
2244 } | 2239 } |
2245 | 2240 |
2246 class HGreaterEqual extends HRelational { | 2241 class HGreaterEqual extends HRelational { |
2247 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) | 2242 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) |
2248 : super(target, left, right); | 2243 : super(target, left, right); |
2249 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); | 2244 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); |
2250 | 2245 |
2251 GreaterEqualOperation get operation => const GreaterEqualOperation(); | 2246 BinaryOperation operation(ConstantSystem constantSystem) |
2247 => constantSystem.greaterEqual; | |
2252 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; | 2248 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; |
2253 bool typeEquals(other) => other is HGreaterEqual; | 2249 bool typeEquals(other) => other is HGreaterEqual; |
2254 bool dataEquals(HInstruction other) => true; | 2250 bool dataEquals(HInstruction other) => true; |
2255 } | 2251 } |
2256 | 2252 |
2257 class HLess extends HRelational { | 2253 class HLess extends HRelational { |
2258 HLess(HStatic target, HInstruction left, HInstruction right) | 2254 HLess(HStatic target, HInstruction left, HInstruction right) |
2259 : super(target, left, right); | 2255 : super(target, left, right); |
2260 accept(HVisitor visitor) => visitor.visitLess(this); | 2256 accept(HVisitor visitor) => visitor.visitLess(this); |
2261 | 2257 |
2262 LessOperation get operation => const LessOperation(); | 2258 BinaryOperation operation(ConstantSystem constantSystem) |
2259 => constantSystem.less; | |
2263 int typeCode() => HInstruction.LESS_TYPECODE; | 2260 int typeCode() => HInstruction.LESS_TYPECODE; |
2264 bool typeEquals(other) => other is HLess; | 2261 bool typeEquals(other) => other is HLess; |
2265 bool dataEquals(HInstruction other) => true; | 2262 bool dataEquals(HInstruction other) => true; |
2266 } | 2263 } |
2267 | 2264 |
2268 class HLessEqual extends HRelational { | 2265 class HLessEqual extends HRelational { |
2269 HLessEqual(HStatic target, HInstruction left, HInstruction right) | 2266 HLessEqual(HStatic target, HInstruction left, HInstruction right) |
2270 : super(target, left, right); | 2267 : super(target, left, right); |
2271 accept(HVisitor visitor) => visitor.visitLessEqual(this); | 2268 accept(HVisitor visitor) => visitor.visitLessEqual(this); |
2272 | 2269 |
2273 LessEqualOperation get operation => const LessEqualOperation(); | 2270 BinaryOperation operation(ConstantSystem constantSystem) |
2271 => constantSystem.lessEqual; | |
2274 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; | 2272 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; |
2275 bool typeEquals(other) => other is HLessEqual; | 2273 bool typeEquals(other) => other is HLessEqual; |
2276 bool dataEquals(HInstruction other) => true; | 2274 bool dataEquals(HInstruction other) => true; |
2277 } | 2275 } |
2278 | 2276 |
2279 class HReturn extends HControlFlow { | 2277 class HReturn extends HControlFlow { |
2280 HReturn(value) : super(<HInstruction>[value]); | 2278 HReturn(value) : super(<HInstruction>[value]); |
2281 toString() => 'return'; | 2279 toString() => 'return'; |
2282 accept(HVisitor visitor) => visitor.visitReturn(this); | 2280 accept(HVisitor visitor) => visitor.visitReturn(this); |
2283 } | 2281 } |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2801 HBasicBlock get start => expression.start; | 2799 HBasicBlock get start => expression.start; |
2802 HBasicBlock get end { | 2800 HBasicBlock get end { |
2803 // We don't create a switch block if there are no cases. | 2801 // We don't create a switch block if there are no cases. |
2804 assert(!statements.isEmpty()); | 2802 assert(!statements.isEmpty()); |
2805 return statements.last().end; | 2803 return statements.last().end; |
2806 } | 2804 } |
2807 | 2805 |
2808 bool accept(HStatementInformationVisitor visitor) => | 2806 bool accept(HStatementInformationVisitor visitor) => |
2809 visitor.visitSwitchInfo(this); | 2807 visitor.visitSwitchInfo(this); |
2810 } | 2808 } |
OLD | NEW |