| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 | 583 |
| 584 static void rewriteInput(HInstruction instruction, | 584 static void rewriteInput(HInstruction instruction, |
| 585 HInstruction from, | 585 HInstruction from, |
| 586 HInstruction to) { | 586 HInstruction to) { |
| 587 List inputs = instruction.inputs; | 587 List inputs = instruction.inputs; |
| 588 for (int i = 0; i < inputs.length; i++) { | 588 for (int i = 0; i < inputs.length; i++) { |
| 589 if (inputs[i] === from) inputs[i] = to; | 589 if (inputs[i] === from) inputs[i] = to; |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 | 592 |
| 593 static void removeUser(HInstruction instruction, HInstruction user) { |
| 594 List<HInstruction> users = instruction.usedBy; |
| 595 int length = users.length; |
| 596 if (length == 1) { |
| 597 users.clear(); |
| 598 } else { |
| 599 for (int i = 0; i < length; i++) { |
| 600 if (users[i] === user) { |
| 601 users[i] = users[length - 1]; |
| 602 users.length = length - 1; |
| 603 return; |
| 604 } |
| 605 } |
| 606 } |
| 607 } |
| 608 |
| 593 bool isExitBlock() { | 609 bool isExitBlock() { |
| 594 return first === last && first is HExit; | 610 return first === last && first is HExit; |
| 595 } | 611 } |
| 596 | 612 |
| 597 void addDominatedBlock(HBasicBlock block) { | 613 void addDominatedBlock(HBasicBlock block) { |
| 598 assert(isClosed()); | 614 assert(isClosed()); |
| 599 assert(id !== null && block.id !== null); | 615 assert(id !== null && block.id !== null); |
| 600 assert(dominatedBlocks.indexOf(block) < 0); | 616 assert(dominatedBlocks.indexOf(block) < 0); |
| 601 // Keep the list of dominated blocks sorted such that if there are two | 617 // Keep the list of dominated blocks sorted such that if there are two |
| 602 // succeeding blocks in the list, the predecessor is before the successor. | 618 // succeeding blocks in the list, the predecessor is before the successor. |
| (...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1817 if (logicalOperatorType == IS_AND) return "&&"; | 1833 if (logicalOperatorType == IS_AND) return "&&"; |
| 1818 assert(logicalOperatorType == IS_OR); | 1834 assert(logicalOperatorType == IS_OR); |
| 1819 return "||"; | 1835 return "||"; |
| 1820 } | 1836 } |
| 1821 | 1837 |
| 1822 toString() => 'phi'; | 1838 toString() => 'phi'; |
| 1823 accept(HVisitor visitor) => visitor.visitPhi(this); | 1839 accept(HVisitor visitor) => visitor.visitPhi(this); |
| 1824 } | 1840 } |
| 1825 | 1841 |
| 1826 class HRelational extends HInvokeBinary { | 1842 class HRelational extends HInvokeBinary { |
| 1843 bool usesBoolifiedInterceptor = false; |
| 1827 HRelational(HStatic target, HInstruction left, HInstruction right) | 1844 HRelational(HStatic target, HInstruction left, HInstruction right) |
| 1828 : super(target, left, right); | 1845 : super(target, left, right); |
| 1829 | 1846 |
| 1830 void prepareGvn() { | 1847 void prepareGvn() { |
| 1831 // Relational expressions can take part in global value numbering | 1848 // Relational expressions can take part in global value numbering |
| 1832 // and do not have any side-effects if we know all the inputs are | 1849 // and do not have any side-effects if we know all the inputs are |
| 1833 // numbers. This can be improved for at least equality. | 1850 // numbers. This can be improved for at least equality. |
| 1834 if (builtin) { | 1851 if (builtin) { |
| 1835 clearAllSideEffects(); | 1852 clearAllSideEffects(); |
| 1836 setUseGvn(); | 1853 setUseGvn(); |
| 1837 } else { | 1854 } else { |
| 1838 setAllSideEffects(); | 1855 setAllSideEffects(); |
| 1839 } | 1856 } |
| 1840 } | 1857 } |
| 1841 | 1858 |
| 1842 HType computeTypeFromInputTypes() { | 1859 HType computeTypeFromInputTypes() { |
| 1843 if (left.isNumber()) return HType.BOOLEAN; | 1860 if (left.isNumber() || usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1844 return HType.UNKNOWN; | 1861 return HType.UNKNOWN; |
| 1845 } | 1862 } |
| 1846 | 1863 |
| 1864 HType get guaranteedType() { |
| 1865 if (usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1866 return HType.UNKNOWN; |
| 1867 } |
| 1868 |
| 1847 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1869 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1848 // For all relational operations exept HEquals, we expect to get numbers | 1870 // For all relational operations exept HEquals, we expect to get numbers |
| 1849 // only. With numbers the outgoing type is a boolean. If something else | 1871 // only. With numbers the outgoing type is a boolean. If something else |
| 1850 // is desired, then numbers are incorrect, though. | 1872 // is desired, then numbers are incorrect, though. |
| 1851 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { | 1873 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { |
| 1852 if (left.isTypeUnknown() || left.isNumber()) { | 1874 if (left.isTypeUnknown() || left.isNumber()) { |
| 1853 return HType.NUMBER; | 1875 return HType.NUMBER; |
| 1854 } | 1876 } |
| 1855 } | 1877 } |
| 1856 return HType.UNKNOWN; | 1878 return HType.UNKNOWN; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1869 accept(HVisitor visitor) => visitor.visitEquals(this); | 1891 accept(HVisitor visitor) => visitor.visitEquals(this); |
| 1870 | 1892 |
| 1871 bool get builtin() { | 1893 bool get builtin() { |
| 1872 // All primitive types have === semantics. | 1894 // All primitive types have === semantics. |
| 1873 // Note that this includes all constants except the user-constructed | 1895 // Note that this includes all constants except the user-constructed |
| 1874 // objects. | 1896 // objects. |
| 1875 return left.isConstantNull() || left.propagatedType.isPrimitive(); | 1897 return left.isConstantNull() || left.propagatedType.isPrimitive(); |
| 1876 } | 1898 } |
| 1877 | 1899 |
| 1878 HType computeTypeFromInputTypes() { | 1900 HType computeTypeFromInputTypes() { |
| 1879 if (builtin) return HType.BOOLEAN; | 1901 if (builtin || usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1880 return HType.UNKNOWN; | 1902 return HType.UNKNOWN; |
| 1881 } | 1903 } |
| 1882 | 1904 |
| 1883 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1905 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1884 if (input == left && right.propagatedType.isUseful()) { | 1906 if (input == left && right.propagatedType.isUseful()) { |
| 1885 // All our useful types have === semantics. But we don't want to | 1907 // All our useful types have === semantics. But we don't want to |
| 1886 // speculatively test for all possible types. Therefore we try to match | 1908 // speculatively test for all possible types. Therefore we try to match |
| 1887 // the two types. That is, if we see x == 3, then we speculatively test | 1909 // the two types. That is, if we see x == 3, then we speculatively test |
| 1888 // if x is a number and bailout if it isn't. | 1910 // if x is a number and bailout if it isn't. |
| 1889 // If right is a number we don't need more than a number (no need to match | 1911 // If right is a number we don't need more than a number (no need to match |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 final bool isAnd; | 2255 final bool isAnd; |
| 2234 final SubExpression left; | 2256 final SubExpression left; |
| 2235 final SubExpression right; | 2257 final SubExpression right; |
| 2236 final HBasicBlock joinBlock; | 2258 final HBasicBlock joinBlock; |
| 2237 HAndOrBlockInformation(this.isAnd, | 2259 HAndOrBlockInformation(this.isAnd, |
| 2238 this.left, | 2260 this.left, |
| 2239 this.right, | 2261 this.right, |
| 2240 this.joinBlock); | 2262 this.joinBlock); |
| 2241 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); | 2263 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); |
| 2242 } | 2264 } |
| OLD | NEW |