| 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 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 if (logicalOperatorType == IS_AND) return "&&"; | 1926 if (logicalOperatorType == IS_AND) return "&&"; |
| 1911 assert(logicalOperatorType == IS_OR); | 1927 assert(logicalOperatorType == IS_OR); |
| 1912 return "||"; | 1928 return "||"; |
| 1913 } | 1929 } |
| 1914 | 1930 |
| 1915 toString() => 'phi'; | 1931 toString() => 'phi'; |
| 1916 accept(HVisitor visitor) => visitor.visitPhi(this); | 1932 accept(HVisitor visitor) => visitor.visitPhi(this); |
| 1917 } | 1933 } |
| 1918 | 1934 |
| 1919 class HRelational extends HInvokeBinary { | 1935 class HRelational extends HInvokeBinary { |
| 1936 bool usesBoolifiedInterceptor = false; |
| 1920 HRelational(HStatic target, HInstruction left, HInstruction right) | 1937 HRelational(HStatic target, HInstruction left, HInstruction right) |
| 1921 : super(target, left, right); | 1938 : super(target, left, right); |
| 1922 | 1939 |
| 1923 void prepareGvn() { | 1940 void prepareGvn() { |
| 1924 // Relational expressions can take part in global value numbering | 1941 // Relational expressions can take part in global value numbering |
| 1925 // and do not have any side-effects if we know all the inputs are | 1942 // and do not have any side-effects if we know all the inputs are |
| 1926 // numbers. This can be improved for at least equality. | 1943 // numbers. This can be improved for at least equality. |
| 1927 if (builtin) { | 1944 if (builtin) { |
| 1928 clearAllSideEffects(); | 1945 clearAllSideEffects(); |
| 1929 setUseGvn(); | 1946 setUseGvn(); |
| 1930 } else { | 1947 } else { |
| 1931 setAllSideEffects(); | 1948 setAllSideEffects(); |
| 1932 } | 1949 } |
| 1933 } | 1950 } |
| 1934 | 1951 |
| 1935 HType computeTypeFromInputTypes() { | 1952 HType computeTypeFromInputTypes() { |
| 1936 if (left.isNumber()) return HType.BOOLEAN; | 1953 if (left.isNumber() || usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1937 return HType.UNKNOWN; | 1954 return HType.UNKNOWN; |
| 1938 } | 1955 } |
| 1939 | 1956 |
| 1957 HType get guaranteedType() { |
| 1958 if (usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1959 return HType.UNKNOWN; |
| 1960 } |
| 1961 |
| 1940 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1962 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1941 // For all relational operations exept HEquals, we expect to get numbers | 1963 // For all relational operations exept HEquals, we expect to get numbers |
| 1942 // only. With numbers the outgoing type is a boolean. If something else | 1964 // only. With numbers the outgoing type is a boolean. If something else |
| 1943 // is desired, then numbers are incorrect, though. | 1965 // is desired, then numbers are incorrect, though. |
| 1944 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { | 1966 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { |
| 1945 if (left.isTypeUnknown() || left.isNumber()) return HType.NUMBER; | 1967 if (left.isTypeUnknown() || left.isNumber()) return HType.NUMBER; |
| 1946 } | 1968 } |
| 1947 return HType.UNKNOWN; | 1969 return HType.UNKNOWN; |
| 1948 } | 1970 } |
| 1949 | 1971 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1960 accept(HVisitor visitor) => visitor.visitEquals(this); | 1982 accept(HVisitor visitor) => visitor.visitEquals(this); |
| 1961 | 1983 |
| 1962 bool get builtin() { | 1984 bool get builtin() { |
| 1963 // All useful types have === semantics. | 1985 // All useful types have === semantics. |
| 1964 // Note that this includes all constants except the user-constructed | 1986 // Note that this includes all constants except the user-constructed |
| 1965 // objects. | 1987 // objects. |
| 1966 return left.isConstantNull() || left.propagatedType.isUseful(); | 1988 return left.isConstantNull() || left.propagatedType.isUseful(); |
| 1967 } | 1989 } |
| 1968 | 1990 |
| 1969 HType computeTypeFromInputTypes() { | 1991 HType computeTypeFromInputTypes() { |
| 1970 if (builtin) return HType.BOOLEAN; | 1992 if (builtin || usesBoolifiedInterceptor) return HType.BOOLEAN; |
| 1971 return HType.UNKNOWN; | 1993 return HType.UNKNOWN; |
| 1972 } | 1994 } |
| 1973 | 1995 |
| 1974 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1996 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1975 if (input == left && right.propagatedType.isUseful()) { | 1997 if (input == left && right.propagatedType.isUseful()) { |
| 1976 // All our useful types have === semantics. But we don't want to | 1998 // All our useful types have === semantics. But we don't want to |
| 1977 // speculatively test for all possible types. Therefore we try to match | 1999 // speculatively test for all possible types. Therefore we try to match |
| 1978 // the two types. That is, if we see x == 3, then we speculatively test | 2000 // the two types. That is, if we see x == 3, then we speculatively test |
| 1979 // if x is a number and bailout if it isn't. | 2001 // if x is a number and bailout if it isn't. |
| 1980 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. | 2002 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2322 final bool isAnd; | 2344 final bool isAnd; |
| 2323 final SubExpression left; | 2345 final SubExpression left; |
| 2324 final SubExpression right; | 2346 final SubExpression right; |
| 2325 final HBasicBlock joinBlock; | 2347 final HBasicBlock joinBlock; |
| 2326 HAndOrBlockInformation(this.isAnd, | 2348 HAndOrBlockInformation(this.isAnd, |
| 2327 this.left, | 2349 this.left, |
| 2328 this.right, | 2350 this.right, |
| 2329 this.joinBlock); | 2351 this.joinBlock); |
| 2330 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); | 2352 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); |
| 2331 } | 2353 } |
| OLD | NEW |