Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: lib/compiler/implementation/ssa/nodes.dart

Issue 10825386: Use JavaScript runtime semantics when constant folding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/builder.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698