| 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 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 * | 902 * |
| 903 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with | 903 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with |
| 904 * speculative types (as otherwise the instruction either sets the output | 904 * speculative types (as otherwise the instruction either sets the output |
| 905 * type to [HType.UNKNOWN] or a specific type. | 905 * type to [HType.UNKNOWN] or a specific type. |
| 906 */ | 906 */ |
| 907 HType propagatedType = HType.UNKNOWN; | 907 HType propagatedType = HType.UNKNOWN; |
| 908 | 908 |
| 909 /** | 909 /** |
| 910 * Some instructions have a good idea of their return type, but cannot | 910 * Some instructions have a good idea of their return type, but cannot |
| 911 * guarantee the type. The [likelyType] does not need to be more specialized | 911 * guarantee the type. The [likelyType] does not need to be more specialized |
| 912 * than the [propagatedType]. | 912 * than the [propagatedType]. |
| 913 * | 913 * |
| 914 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this | 914 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this |
| 915 * cannot be guaranteed, but when merging types we still want to use this | 915 * cannot be guaranteed, but when merging types we still want to use this |
| 916 * information. | 916 * information. |
| 917 * | 917 * |
| 918 * Similarily the [HAdd] instruction is likely a number. Note that, even if | 918 * Similarily the [HAdd] instruction is likely a number. Note that, even if |
| 919 * the [propagatedType] is already set to integer, the [likelyType] still | 919 * the [propagatedType] is already set to integer, the [likelyType] still |
| 920 * might just return the number type. | 920 * might just return the number type. |
| 921 */ | 921 */ |
| 922 HType get likelyType() => propagatedType; | 922 HType get likelyType() => propagatedType; |
| 923 | 923 |
| 924 /** | 924 /** |
| 925 * Compute the type of the instruction by propagating the input types through | 925 * Compute the type of the instruction by propagating the input types through |
| 926 * the instruction. | 926 * the instruction. |
| 927 * | 927 * |
| 928 * By default just copy the guaranteed type. | 928 * By default just copy the guaranteed type. |
| 929 */ | 929 */ |
| 930 HType computeTypeFromInputTypes() => guaranteedType; | 930 HType computeTypeFromInputTypes() => guaranteedType; |
| 931 | 931 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 class HCheck extends HInstruction { | 1060 class HCheck extends HInstruction { |
| 1061 HCheck(inputs) : super(inputs); | 1061 HCheck(inputs) : super(inputs); |
| 1062 | 1062 |
| 1063 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1063 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1064 abstract accept(HVisitor visitor); | 1064 abstract accept(HVisitor visitor); |
| 1065 | 1065 |
| 1066 bool isControlFlow() => true; | 1066 bool isControlFlow() => true; |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 class HTypeGuard extends HInstruction { | 1069 class HTypeGuard extends HInstruction { |
| 1070 int state; | 1070 final int state; |
| 1071 HTypeGuard(int this.state, List<HInstruction> env) : super(env); | 1071 final HType guardedType; |
| 1072 bool isOn = false; |
| 1073 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env); |
| 1072 | 1074 |
| 1073 void prepareGvn() { | 1075 void prepareGvn() { |
| 1074 assert(!hasSideEffects()); | 1076 assert(!hasSideEffects()); |
| 1075 setUseGvn(); | 1077 setUseGvn(); |
| 1076 } | 1078 } |
| 1077 | 1079 |
| 1078 HInstruction get guarded() => inputs.last(); | 1080 HInstruction get guarded() => inputs.last(); |
| 1079 | 1081 |
| 1082 HType computeTypeFromInputTypes() { |
| 1083 return isOn ? guardedType : guarded.propagatedType; |
| 1084 } |
| 1085 |
| 1086 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN; |
| 1087 |
| 1080 bool isControlFlow() => true; | 1088 bool isControlFlow() => true; |
| 1081 | 1089 |
| 1082 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1090 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1083 int typeCode() => 1; | 1091 int typeCode() => 1; |
| 1084 bool typeEquals(other) => other is HTypeGuard; | 1092 bool typeEquals(other) => other is HTypeGuard; |
| 1085 bool dataEquals(HTypeGuard other) => propagatedType == other.propagatedType; | 1093 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 1086 } | 1094 } |
| 1087 | 1095 |
| 1088 class HBoundsCheck extends HCheck { | 1096 class HBoundsCheck extends HCheck { |
| 1089 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); | 1097 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); |
| 1090 | 1098 |
| 1091 HInstruction get length() => inputs[0]; | 1099 HInstruction get length() => inputs[0]; |
| 1092 HInstruction get index() => inputs[1]; | 1100 HInstruction get index() => inputs[1]; |
| 1093 | 1101 |
| 1094 void prepareGvn() { | 1102 void prepareGvn() { |
| 1095 assert(!hasSideEffects()); | 1103 assert(!hasSideEffects()); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1419 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1412 // If the desired output type should be an integer we want to get two | 1420 // If the desired output type should be an integer we want to get two |
| 1413 // integers as arguments. | 1421 // integers as arguments. |
| 1414 if (propagatedType.isInteger()) return HType.INTEGER; | 1422 if (propagatedType.isInteger()) return HType.INTEGER; |
| 1415 // If the outgoing type should be a number we can get that if both inputs | 1423 // If the outgoing type should be a number we can get that if both inputs |
| 1416 // are numbers. If we don't know the outgoing type we try to make it a | 1424 // are numbers. If we don't know the outgoing type we try to make it a |
| 1417 // number. | 1425 // number. |
| 1418 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 1426 if (propagatedType.isUnknown() || propagatedType.isNumber()) { |
| 1419 return HType.NUMBER; | 1427 return HType.NUMBER; |
| 1420 } | 1428 } |
| 1429 // Even if the desired outgoing type is not a number we still want the |
| 1430 // second argument to be a number if the first one is a number. This will |
| 1431 // not help for the outgoing type, but at least the binary arithmetic |
| 1432 // operation will not have type problems. |
| 1433 // TODO(floitsch): normally we shouldn't request a number, but simply |
| 1434 // throw an IllegalArgumentException if it isn't. This would be similar |
| 1435 // to the array case. |
| 1436 if (input == right && left.isNumber()) return HType.NUMBER; |
| 1421 return HType.UNKNOWN; | 1437 return HType.UNKNOWN; |
| 1422 } | 1438 } |
| 1423 | 1439 |
| 1424 HType get likelyType() { | 1440 HType get likelyType() { |
| 1425 if (left.isTypeUnknown()) return HType.NUMBER; | 1441 if (left.isTypeUnknown()) return HType.NUMBER; |
| 1426 return HType.UNKNOWN; | 1442 return HType.UNKNOWN; |
| 1427 } | 1443 } |
| 1428 | 1444 |
| 1429 // TODO(1603): The class should be marked as abstract. | 1445 // TODO(1603): The class should be marked as abstract. |
| 1430 abstract BinaryOperation get operation(); | 1446 abstract BinaryOperation get operation(); |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 | 2016 |
| 2001 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 2017 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 2002 if (input == left && right.propagatedType.isUseful()) { | 2018 if (input == left && right.propagatedType.isUseful()) { |
| 2003 // All our useful types have === semantics. But we don't want to | 2019 // All our useful types have === semantics. But we don't want to |
| 2004 // speculatively test for all possible types. Therefore we try to match | 2020 // speculatively test for all possible types. Therefore we try to match |
| 2005 // the two types. That is, if we see x == 3, then we speculatively test | 2021 // the two types. That is, if we see x == 3, then we speculatively test |
| 2006 // if x is a number and bailout if it isn't. | 2022 // if x is a number and bailout if it isn't. |
| 2007 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. | 2023 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. |
| 2008 // String equality testing is much more common than array equality | 2024 // String equality testing is much more common than array equality |
| 2009 // testing. | 2025 // testing. |
| 2010 if (right.isStringOrArray()) return HType.STRING; | 2026 if (right.isStringOrArray()) return HType.STRING; |
| 2011 return right.propagatedType; | 2027 return right.propagatedType; |
| 2012 } | 2028 } |
| 2013 // String equality testing is much more common than array equality testing. | 2029 // String equality testing is much more common than array equality testing. |
| 2014 if (input == left && left.isStringOrArray()) { | 2030 if (input == left && left.isStringOrArray()) { |
| 2015 return HType.READABLE_ARRAY; | 2031 return HType.READABLE_ARRAY; |
| 2016 } | 2032 } |
| 2017 // String equality testing is much more common than array equality testing. | 2033 // String equality testing is much more common than array equality testing. |
| 2018 if (input == right && right.isStringOrArray()) { | 2034 if (input == right && right.isStringOrArray()) { |
| 2019 return HType.STRING; | 2035 return HType.STRING; |
| 2020 } | 2036 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 class HIfBlockInformation { | 2242 class HIfBlockInformation { |
| 2227 final HIf branch; | 2243 final HIf branch; |
| 2228 final SubGraph thenGraph; | 2244 final SubGraph thenGraph; |
| 2229 final SubGraph elseGraph; | 2245 final SubGraph elseGraph; |
| 2230 final HBasicBlock joinBlock; | 2246 final HBasicBlock joinBlock; |
| 2231 HIfBlockInformation(this.branch, | 2247 HIfBlockInformation(this.branch, |
| 2232 this.thenGraph, | 2248 this.thenGraph, |
| 2233 this.elseGraph, | 2249 this.elseGraph, |
| 2234 this.joinBlock); | 2250 this.joinBlock); |
| 2235 } | 2251 } |
| OLD | NEW |