| 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 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 // Changes flags. | 751 // Changes flags. |
| 752 static final int FLAG_CHANGES_SOMETHING = 0; | 752 static final int FLAG_CHANGES_SOMETHING = 0; |
| 753 static final int FLAG_CHANGES_COUNT = FLAG_CHANGES_SOMETHING + 1; | 753 static final int FLAG_CHANGES_COUNT = FLAG_CHANGES_SOMETHING + 1; |
| 754 | 754 |
| 755 // Depends flags (one for each changes flag). | 755 // Depends flags (one for each changes flag). |
| 756 static final int FLAG_DEPENDS_ON_SOMETHING = FLAG_CHANGES_COUNT; | 756 static final int FLAG_DEPENDS_ON_SOMETHING = FLAG_CHANGES_COUNT; |
| 757 | 757 |
| 758 // Other flags. | 758 // Other flags. |
| 759 static final int FLAG_USE_GVN = FLAG_DEPENDS_ON_SOMETHING + 1; | 759 static final int FLAG_USE_GVN = FLAG_DEPENDS_ON_SOMETHING + 1; |
| 760 | 760 |
| 761 // Type codes. |
| 762 static final int UNDEFINED_TYPECODE = -1; |
| 763 static final int BOOLIFY_TYPECODE = 0; |
| 764 static final int TYPE_GUARD_TYPECODE = 1; |
| 765 static final int BOUNDS_CHECK_TYPECODE = 2; |
| 766 static final int INTEGER_CHECK_TYPECODE = 3; |
| 767 static final int INVOKE_INTERCEPTOR_TYPECODE = 4; |
| 768 static final int ADD_TYPECODE = 5; |
| 769 static final int DIVIDE_TYPECODE = 6; |
| 770 static final int MODULO_TYPECODE = 7; |
| 771 static final int MULTIPLY_TYPECODE = 8; |
| 772 static final int SUBTRACT_TYPECODE = 9; |
| 773 static final int TRUNCATING_DIVIDE_TYPECODE = 10; |
| 774 static final int SHIFT_LEFT_TYPECODE = 11; |
| 775 static final int SHIFT_RIGHT_TYPECODE = 12; |
| 776 static final int BIT_OR_TYPECODE = 13; |
| 777 static final int BIT_AND_TYPECODE = 14; |
| 778 static final int BIT_XOR_TYPECODE = 15; |
| 779 static final int NEGATE_TYPECODE = 16; |
| 780 static final int BIT_NOT_TYPECODE = 17; |
| 781 static final int NOT_TYPECODE = 18; |
| 782 static final int EQUALS_TYPECODE = 19; |
| 783 static final int IDENTITY_TYPECODE = 20; |
| 784 static final int GREATER_TYPECODE = 21; |
| 785 static final int GREATER_EQUAL_TYPECODE = 22; |
| 786 static final int LESS_TYPECODE = 23; |
| 787 static final int LESS_EQUAL_TYPECODE = 24; |
| 788 static final int STATIC_TYPECODE = 25; |
| 789 static final int STATIC_STORE_TYPECODE = 26; |
| 790 static final int FIELD_GET_TYPECODE = 27; |
| 791 static final int TYPE_CONVERSION_TYPECODE = 28; |
| 792 static final int BAILOUT_TARGET_TYPECODE = 29; |
| 793 static final int INVOKE_STATIC_TYPECODE = 30; |
| 794 |
| 761 HInstruction(this.inputs) | 795 HInstruction(this.inputs) |
| 762 : id = idCounter++, | 796 : id = idCounter++, |
| 763 usedBy = <HInstruction>[]; | 797 usedBy = <HInstruction>[]; |
| 764 | 798 |
| 765 int hashCode() => id; | 799 int hashCode() => id; |
| 766 | 800 |
| 767 bool getFlag(int position) => (flags & (1 << position)) != 0; | 801 bool getFlag(int position) => (flags & (1 << position)) != 0; |
| 768 void setFlag(int position) { flags |= (1 << position); } | 802 void setFlag(int position) { flags |= (1 << position); } |
| 769 void clearFlag(int position) { flags &= ~(1 << position); } | 803 void clearFlag(int position) { flags &= ~(1 << position); } |
| 770 | 804 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 int result = typeCode(); | 917 int result = typeCode(); |
| 884 int length = inputs.length; | 918 int length = inputs.length; |
| 885 for (int i = 0; i < length; i++) { | 919 for (int i = 0; i < length; i++) { |
| 886 result = (result * 19) + (inputs[i].id) + (result >> 7); | 920 result = (result * 19) + (inputs[i].id) + (result >> 7); |
| 887 } | 921 } |
| 888 return result; | 922 return result; |
| 889 } | 923 } |
| 890 | 924 |
| 891 // These methods should be overwritten by instructions that | 925 // These methods should be overwritten by instructions that |
| 892 // participate in global value numbering. | 926 // participate in global value numbering. |
| 893 int typeCode() => -1; | 927 int typeCode() => HInstruction.UNDEFINED_TYPECODE; |
| 894 bool typeEquals(HInstruction other) => false; | 928 bool typeEquals(HInstruction other) => false; |
| 895 bool dataEquals(HInstruction other) => false; | 929 bool dataEquals(HInstruction other) => false; |
| 896 | 930 |
| 897 abstract accept(HVisitor visitor); | 931 abstract accept(HVisitor visitor); |
| 898 | 932 |
| 899 void notifyAddedToBlock(HBasicBlock targetBlock) { | 933 void notifyAddedToBlock(HBasicBlock targetBlock) { |
| 900 assert(!isInBasicBlock()); | 934 assert(!isInBasicBlock()); |
| 901 assert(block === null); | 935 assert(block === null); |
| 902 // Add [this] to the inputs' uses. | 936 // Add [this] to the inputs' uses. |
| 903 for (int i = 0; i < inputs.length; i++) { | 937 for (int i = 0; i < inputs.length; i++) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 class HBoolify extends HInstruction { | 1083 class HBoolify extends HInstruction { |
| 1050 HBoolify(HInstruction value) : super(<HInstruction>[value]); | 1084 HBoolify(HInstruction value) : super(<HInstruction>[value]); |
| 1051 void prepareGvn(HTypeMap types) { | 1085 void prepareGvn(HTypeMap types) { |
| 1052 assert(!hasSideEffects(types)); | 1086 assert(!hasSideEffects(types)); |
| 1053 setUseGvn(); | 1087 setUseGvn(); |
| 1054 } | 1088 } |
| 1055 | 1089 |
| 1056 HType get guaranteedType => HType.BOOLEAN; | 1090 HType get guaranteedType => HType.BOOLEAN; |
| 1057 | 1091 |
| 1058 accept(HVisitor visitor) => visitor.visitBoolify(this); | 1092 accept(HVisitor visitor) => visitor.visitBoolify(this); |
| 1059 int typeCode() => 0; | 1093 int typeCode() => HInstruction.BOOLIFY_TYPECODE; |
| 1060 bool typeEquals(other) => other is HBoolify; | 1094 bool typeEquals(other) => other is HBoolify; |
| 1061 bool dataEquals(HInstruction other) => true; | 1095 bool dataEquals(HInstruction other) => true; |
| 1062 } | 1096 } |
| 1063 | 1097 |
| 1064 /** | 1098 /** |
| 1065 * A [HCheck] instruction is an instruction that might do a dynamic | 1099 * A [HCheck] instruction is an instruction that might do a dynamic |
| 1066 * check at runtime on another instruction. To have proper instruction | 1100 * check at runtime on another instruction. To have proper instruction |
| 1067 * dependencies in the graph, instructions that depend on the check | 1101 * dependencies in the graph, instructions that depend on the check |
| 1068 * being done reference the [HCheck] instruction instead of the | 1102 * being done reference the [HCheck] instruction instead of the |
| 1069 * instruction itself. | 1103 * instruction itself. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1084 HBailoutTarget(this.state) : super(<HInstruction>[]); | 1118 HBailoutTarget(this.state) : super(<HInstruction>[]); |
| 1085 void prepareGvn(HTypeMap types) { | 1119 void prepareGvn(HTypeMap types) { |
| 1086 assert(!hasSideEffects(types)); | 1120 assert(!hasSideEffects(types)); |
| 1087 setUseGvn(); | 1121 setUseGvn(); |
| 1088 } | 1122 } |
| 1089 | 1123 |
| 1090 bool isControlFlow() => true; | 1124 bool isControlFlow() => true; |
| 1091 bool isStatement(HTypeMap types) => isEnabled; | 1125 bool isStatement(HTypeMap types) => isEnabled; |
| 1092 | 1126 |
| 1093 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); | 1127 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); |
| 1094 int typeCode() => 29; | 1128 int typeCode() => HInstruction.BAILOUT_TARGET_TYPECODE; |
| 1095 bool typeEquals(other) => other is HBailoutTarget; | 1129 bool typeEquals(other) => other is HBailoutTarget; |
| 1096 bool dataEquals(HBailoutTarget other) => other.state == state; | 1130 bool dataEquals(HBailoutTarget other) => other.state == state; |
| 1097 } | 1131 } |
| 1098 | 1132 |
| 1099 class HTypeGuard extends HCheck { | 1133 class HTypeGuard extends HCheck { |
| 1100 final HType guardedType; | 1134 final HType guardedType; |
| 1101 bool isEnabled = false; | 1135 bool isEnabled = false; |
| 1102 | 1136 |
| 1103 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget) | 1137 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget) |
| 1104 : super(<HInstruction>[guarded, bailoutTarget]); | 1138 : super(<HInstruction>[guarded, bailoutTarget]); |
| 1105 | 1139 |
| 1106 HInstruction get guarded => inputs[0]; | 1140 HInstruction get guarded => inputs[0]; |
| 1107 HInstruction get checkedInput => guarded; | 1141 HInstruction get checkedInput => guarded; |
| 1108 HBailoutTarget get bailoutTarget => inputs[1]; | 1142 HBailoutTarget get bailoutTarget => inputs[1]; |
| 1109 int get state => bailoutTarget.state; | 1143 int get state => bailoutTarget.state; |
| 1110 | 1144 |
| 1111 HType computeTypeFromInputTypes(HTypeMap types) { | 1145 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1112 return isEnabled ? guardedType : types[guarded]; | 1146 return isEnabled ? guardedType : types[guarded]; |
| 1113 } | 1147 } |
| 1114 | 1148 |
| 1115 HType get guaranteedType => isEnabled ? guardedType : HType.UNKNOWN; | 1149 HType get guaranteedType => isEnabled ? guardedType : HType.UNKNOWN; |
| 1116 | 1150 |
| 1117 bool isControlFlow() => true; | 1151 bool isControlFlow() => true; |
| 1118 | 1152 |
| 1119 bool isStatement(HTypeMap types) => isEnabled; | 1153 bool isStatement(HTypeMap types) => isEnabled; |
| 1120 | 1154 |
| 1121 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1155 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1122 int typeCode() => 1; | 1156 int typeCode() => HInstruction.TYPE_GUARD_TYPECODE; |
| 1123 bool typeEquals(other) => other is HTypeGuard; | 1157 bool typeEquals(other) => other is HTypeGuard; |
| 1124 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; | 1158 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 1125 } | 1159 } |
| 1126 | 1160 |
| 1127 class HBoundsCheck extends HCheck { | 1161 class HBoundsCheck extends HCheck { |
| 1128 static final int ALWAYS_FALSE = 0; | 1162 static final int ALWAYS_FALSE = 0; |
| 1129 static final int FULL_CHECK = 1; | 1163 static final int FULL_CHECK = 1; |
| 1130 static final int ALWAYS_ABOVE_ZERO = 2; | 1164 static final int ALWAYS_ABOVE_ZERO = 2; |
| 1131 static final int ALWAYS_TRUE = 3; | 1165 static final int ALWAYS_TRUE = 3; |
| 1132 /** | 1166 /** |
| 1133 * Details which tests have been done statically during compilation. | 1167 * Details which tests have been done statically during compilation. |
| 1134 * Default is that all checks must be performed dynamically. | 1168 * Default is that all checks must be performed dynamically. |
| 1135 */ | 1169 */ |
| 1136 int staticChecks = FULL_CHECK; | 1170 int staticChecks = FULL_CHECK; |
| 1137 | 1171 |
| 1138 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); | 1172 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); |
| 1139 | 1173 |
| 1140 HInstruction get length => inputs[1]; | 1174 HInstruction get length => inputs[1]; |
| 1141 HInstruction get index => inputs[0]; | 1175 HInstruction get index => inputs[0]; |
| 1142 bool isControlFlow() => true; | 1176 bool isControlFlow() => true; |
| 1143 | 1177 |
| 1144 HType get guaranteedType => HType.INTEGER; | 1178 HType get guaranteedType => HType.INTEGER; |
| 1145 | 1179 |
| 1146 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); | 1180 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); |
| 1147 int typeCode() => 2; | 1181 int typeCode() => HInstruction.BOUNDS_CHECK_TYPECODE; |
| 1148 bool typeEquals(other) => other is HBoundsCheck; | 1182 bool typeEquals(other) => other is HBoundsCheck; |
| 1149 bool dataEquals(HInstruction other) => true; | 1183 bool dataEquals(HInstruction other) => true; |
| 1150 } | 1184 } |
| 1151 | 1185 |
| 1152 class HIntegerCheck extends HCheck { | 1186 class HIntegerCheck extends HCheck { |
| 1153 bool alwaysFalse = false; | 1187 bool alwaysFalse = false; |
| 1154 | 1188 |
| 1155 HIntegerCheck(value) : super(<HInstruction>[value]); | 1189 HIntegerCheck(value) : super(<HInstruction>[value]); |
| 1156 | 1190 |
| 1157 HInstruction get value => inputs[0]; | 1191 HInstruction get value => inputs[0]; |
| 1158 bool isControlFlow() => true; | 1192 bool isControlFlow() => true; |
| 1159 | 1193 |
| 1160 HType get guaranteedType => HType.INTEGER; | 1194 HType get guaranteedType => HType.INTEGER; |
| 1161 | 1195 |
| 1162 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { | 1196 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { |
| 1163 // If the desired type of the input is already a number, we want | 1197 // If the desired type of the input is already a number, we want |
| 1164 // to specialize it to an integer. | 1198 // to specialize it to an integer. |
| 1165 return input.isNumber(types) | 1199 return input.isNumber(types) |
| 1166 ? HType.INTEGER | 1200 ? HType.INTEGER |
| 1167 : super.computeDesiredTypeForInput(input, types); | 1201 : super.computeDesiredTypeForInput(input, types); |
| 1168 } | 1202 } |
| 1169 | 1203 |
| 1170 accept(HVisitor visitor) => visitor.visitIntegerCheck(this); | 1204 accept(HVisitor visitor) => visitor.visitIntegerCheck(this); |
| 1171 int typeCode() => 3; | 1205 int typeCode() => HInstruction.INTEGER_CHECK_TYPECODE; |
| 1172 bool typeEquals(other) => other is HIntegerCheck; | 1206 bool typeEquals(other) => other is HIntegerCheck; |
| 1173 bool dataEquals(HInstruction other) => true; | 1207 bool dataEquals(HInstruction other) => true; |
| 1174 } | 1208 } |
| 1175 | 1209 |
| 1176 class HConditionalBranch extends HControlFlow { | 1210 class HConditionalBranch extends HControlFlow { |
| 1177 HConditionalBranch(inputs) : super(inputs); | 1211 HConditionalBranch(inputs) : super(inputs); |
| 1178 HInstruction get condition => inputs[0]; | 1212 HInstruction get condition => inputs[0]; |
| 1179 HBasicBlock get trueBranch => block.successors[0]; | 1213 HBasicBlock get trueBranch => block.successors[0]; |
| 1180 HBasicBlock get falseBranch => block.successors[1]; | 1214 HBasicBlock get falseBranch => block.successors[1]; |
| 1181 abstract toString(); | 1215 abstract toString(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 } | 1282 } |
| 1249 | 1283 |
| 1250 class HInvokeDynamicSetter extends HInvokeDynamicField { | 1284 class HInvokeDynamicSetter extends HInvokeDynamicField { |
| 1251 HInvokeDynamicSetter(selector, element, receiver, value) | 1285 HInvokeDynamicSetter(selector, element, receiver, value) |
| 1252 : super(selector, element, [receiver, value]); | 1286 : super(selector, element, [receiver, value]); |
| 1253 toString() => 'invoke dynamic setter: $selector'; | 1287 toString() => 'invoke dynamic setter: $selector'; |
| 1254 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); | 1288 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); |
| 1255 } | 1289 } |
| 1256 | 1290 |
| 1257 class HInvokeStatic extends HInvoke { | 1291 class HInvokeStatic extends HInvoke { |
| 1258 static final int INVOKE_INTERCEPTOR_TYPECODE = 4; | |
| 1259 static final int INVOKE_STATIC_TYPECODE = 30; | |
| 1260 | |
| 1261 /** The first input must be the target. */ | 1292 /** The first input must be the target. */ |
| 1262 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { | 1293 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { |
| 1263 guaranteedType = knownType; | 1294 guaranteedType = knownType; |
| 1264 } | 1295 } |
| 1265 | 1296 |
| 1266 toString() => 'invoke static: ${element.name}'; | 1297 toString() => 'invoke static: ${element.name}'; |
| 1267 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); | 1298 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); |
| 1268 int typeCode() => INVOKE_STATIC_TYPECODE; | 1299 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; |
| 1269 Element get element => target.element; | 1300 Element get element => target.element; |
| 1270 HStatic get target => inputs[0]; | 1301 HStatic get target => inputs[0]; |
| 1271 | 1302 |
| 1272 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { | 1303 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { |
| 1273 // TODO(floitsch): we want the target to be a function. | 1304 // TODO(floitsch): we want the target to be a function. |
| 1274 if (input == target) return HType.UNKNOWN; | 1305 if (input == target) return HType.UNKNOWN; |
| 1275 return computeDesiredTypeForNonTargetInput(input, types); | 1306 return computeDesiredTypeForNonTargetInput(input, types); |
| 1276 } | 1307 } |
| 1277 | 1308 |
| 1278 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1309 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 void prepareGvn(HTypeMap types) { | 1378 void prepareGvn(HTypeMap types) { |
| 1348 if (isLengthGetterOnStringOrArray(types)) { | 1379 if (isLengthGetterOnStringOrArray(types)) { |
| 1349 setUseGvn(); | 1380 setUseGvn(); |
| 1350 clearAllSideEffects(); | 1381 clearAllSideEffects(); |
| 1351 setDependsOnSomething(); | 1382 setDependsOnSomething(); |
| 1352 } else { | 1383 } else { |
| 1353 setAllSideEffects(); | 1384 setAllSideEffects(); |
| 1354 } | 1385 } |
| 1355 } | 1386 } |
| 1356 | 1387 |
| 1357 int typeCode() => HInvokeStatic.INVOKE_INTERCEPTOR_TYPECODE; | 1388 int typeCode() => HInstruction.INVOKE_INTERCEPTOR_TYPECODE; |
| 1358 bool typeEquals(other) => other is HInvokeInterceptor; | 1389 bool typeEquals(other) => other is HInvokeInterceptor; |
| 1359 bool dataEquals(HInvokeInterceptor other) { | 1390 bool dataEquals(HInvokeInterceptor other) { |
| 1360 return getter == other.getter && name == other.name; | 1391 return getter == other.getter && name == other.name; |
| 1361 } | 1392 } |
| 1362 } | 1393 } |
| 1363 | 1394 |
| 1364 abstract class HFieldAccess extends HInstruction { | 1395 abstract class HFieldAccess extends HInstruction { |
| 1365 final Element element; | 1396 final Element element; |
| 1366 final SourceString fieldName; | 1397 final SourceString fieldName; |
| 1367 final LibraryElement library; | 1398 final LibraryElement library; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1390 HInstruction get receiver => inputs[0]; | 1421 HInstruction get receiver => inputs[0]; |
| 1391 | 1422 |
| 1392 accept(HVisitor visitor) => visitor.visitFieldGet(this); | 1423 accept(HVisitor visitor) => visitor.visitFieldGet(this); |
| 1393 | 1424 |
| 1394 void prepareGvn(HTypeMap types) { | 1425 void prepareGvn(HTypeMap types) { |
| 1395 setUseGvn(); | 1426 setUseGvn(); |
| 1396 clearAllSideEffects(); | 1427 clearAllSideEffects(); |
| 1397 if (!isFinalOrConst) setDependsOnSomething(); | 1428 if (!isFinalOrConst) setDependsOnSomething(); |
| 1398 } | 1429 } |
| 1399 | 1430 |
| 1400 int typeCode() => 27; | 1431 int typeCode() => HInstruction.FIELD_GET_TYPECODE; |
| 1401 bool typeEquals(other) => other is HFieldGet; | 1432 bool typeEquals(other) => other is HFieldGet; |
| 1402 bool dataEquals(HFieldGet other) => element == other.element; | 1433 bool dataEquals(HFieldGet other) => element == other.element; |
| 1403 String toString() => "FieldGet ${element == null ? fieldName : element}"; | 1434 String toString() => "FieldGet ${element == null ? fieldName : element}"; |
| 1404 } | 1435 } |
| 1405 | 1436 |
| 1406 class HFieldSet extends HFieldAccess { | 1437 class HFieldSet extends HFieldAccess { |
| 1407 HFieldSet(SourceString name, | 1438 HFieldSet(SourceString name, |
| 1408 LibraryElement library, | 1439 LibraryElement library, |
| 1409 HInstruction receiver, | 1440 HInstruction receiver, |
| 1410 HInstruction value) | 1441 HInstruction value) |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 // TODO(1603): The class should be marked as abstract. | 1597 // TODO(1603): The class should be marked as abstract. |
| 1567 abstract BinaryOperation get operation(); | 1598 abstract BinaryOperation get operation(); |
| 1568 } | 1599 } |
| 1569 | 1600 |
| 1570 class HAdd extends HBinaryArithmetic { | 1601 class HAdd extends HBinaryArithmetic { |
| 1571 HAdd(HStatic target, HInstruction left, HInstruction right) | 1602 HAdd(HStatic target, HInstruction left, HInstruction right) |
| 1572 : super(target, left, right); | 1603 : super(target, left, right); |
| 1573 accept(HVisitor visitor) => visitor.visitAdd(this); | 1604 accept(HVisitor visitor) => visitor.visitAdd(this); |
| 1574 | 1605 |
| 1575 AddOperation get operation => const AddOperation(); | 1606 AddOperation get operation => const AddOperation(); |
| 1576 int typeCode() => 5; | 1607 int typeCode() => HInstruction.ADD_TYPECODE; |
| 1577 bool typeEquals(other) => other is HAdd; | 1608 bool typeEquals(other) => other is HAdd; |
| 1578 bool dataEquals(HInstruction other) => true; | 1609 bool dataEquals(HInstruction other) => true; |
| 1579 } | 1610 } |
| 1580 | 1611 |
| 1581 class HDivide extends HBinaryArithmetic { | 1612 class HDivide extends HBinaryArithmetic { |
| 1582 HDivide(HStatic target, HInstruction left, HInstruction right) | 1613 HDivide(HStatic target, HInstruction left, HInstruction right) |
| 1583 : super(target, left, right); | 1614 : super(target, left, right); |
| 1584 accept(HVisitor visitor) => visitor.visitDivide(this); | 1615 accept(HVisitor visitor) => visitor.visitDivide(this); |
| 1585 | 1616 |
| 1586 HType computeTypeFromInputTypes(HTypeMap types) { | 1617 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1587 if (left.isNumber(types)) return HType.DOUBLE; | 1618 if (left.isNumber(types)) return HType.DOUBLE; |
| 1588 return HType.UNKNOWN; | 1619 return HType.UNKNOWN; |
| 1589 } | 1620 } |
| 1590 | 1621 |
| 1591 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1622 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
| 1592 HTypeMap types) { | 1623 HTypeMap types) { |
| 1593 // A division can never return an integer. So don't ask for integer inputs. | 1624 // A division can never return an integer. So don't ask for integer inputs. |
| 1594 if (isInteger(types)) return HType.UNKNOWN; | 1625 if (isInteger(types)) return HType.UNKNOWN; |
| 1595 return super.computeDesiredTypeForNonTargetInput(input, types); | 1626 return super.computeDesiredTypeForNonTargetInput(input, types); |
| 1596 } | 1627 } |
| 1597 | 1628 |
| 1598 DivideOperation get operation => const DivideOperation(); | 1629 DivideOperation get operation => const DivideOperation(); |
| 1599 int typeCode() => 6; | 1630 int typeCode() => HInstruction.DIVIDE_TYPECODE; |
| 1600 bool typeEquals(other) => other is HDivide; | 1631 bool typeEquals(other) => other is HDivide; |
| 1601 bool dataEquals(HInstruction other) => true; | 1632 bool dataEquals(HInstruction other) => true; |
| 1602 } | 1633 } |
| 1603 | 1634 |
| 1604 class HModulo extends HBinaryArithmetic { | 1635 class HModulo extends HBinaryArithmetic { |
| 1605 HModulo(HStatic target, HInstruction left, HInstruction right) | 1636 HModulo(HStatic target, HInstruction left, HInstruction right) |
| 1606 : super(target, left, right); | 1637 : super(target, left, right); |
| 1607 accept(HVisitor visitor) => visitor.visitModulo(this); | 1638 accept(HVisitor visitor) => visitor.visitModulo(this); |
| 1608 | 1639 |
| 1609 ModuloOperation get operation => const ModuloOperation(); | 1640 ModuloOperation get operation => const ModuloOperation(); |
| 1610 int typeCode() => 7; | 1641 int typeCode() => HInstruction.MODULO_TYPECODE; |
| 1611 bool typeEquals(other) => other is HModulo; | 1642 bool typeEquals(other) => other is HModulo; |
| 1612 bool dataEquals(HInstruction other) => true; | 1643 bool dataEquals(HInstruction other) => true; |
| 1613 } | 1644 } |
| 1614 | 1645 |
| 1615 class HMultiply extends HBinaryArithmetic { | 1646 class HMultiply extends HBinaryArithmetic { |
| 1616 HMultiply(HStatic target, HInstruction left, HInstruction right) | 1647 HMultiply(HStatic target, HInstruction left, HInstruction right) |
| 1617 : super(target, left, right); | 1648 : super(target, left, right); |
| 1618 accept(HVisitor visitor) => visitor.visitMultiply(this); | 1649 accept(HVisitor visitor) => visitor.visitMultiply(this); |
| 1619 | 1650 |
| 1620 MultiplyOperation get operation => const MultiplyOperation(); | 1651 MultiplyOperation get operation => const MultiplyOperation(); |
| 1621 int typeCode() => 8; | 1652 int typeCode() => HInstruction.MULTIPLY_TYPECODE; |
| 1622 bool typeEquals(other) => other is HMultiply; | 1653 bool typeEquals(other) => other is HMultiply; |
| 1623 bool dataEquals(HInstruction other) => true; | 1654 bool dataEquals(HInstruction other) => true; |
| 1624 } | 1655 } |
| 1625 | 1656 |
| 1626 class HSubtract extends HBinaryArithmetic { | 1657 class HSubtract extends HBinaryArithmetic { |
| 1627 HSubtract(HStatic target, HInstruction left, HInstruction right) | 1658 HSubtract(HStatic target, HInstruction left, HInstruction right) |
| 1628 : super(target, left, right); | 1659 : super(target, left, right); |
| 1629 accept(HVisitor visitor) => visitor.visitSubtract(this); | 1660 accept(HVisitor visitor) => visitor.visitSubtract(this); |
| 1630 | 1661 |
| 1631 SubtractOperation get operation => const SubtractOperation(); | 1662 SubtractOperation get operation => const SubtractOperation(); |
| 1632 int typeCode() => 9; | 1663 int typeCode() => HInstruction.SUBTRACT_TYPECODE; |
| 1633 bool typeEquals(other) => other is HSubtract; | 1664 bool typeEquals(other) => other is HSubtract; |
| 1634 bool dataEquals(HInstruction other) => true; | 1665 bool dataEquals(HInstruction other) => true; |
| 1635 } | 1666 } |
| 1636 | 1667 |
| 1637 /** | 1668 /** |
| 1638 * An [HSwitch] instruction has one input for the incoming | 1669 * An [HSwitch] instruction has one input for the incoming |
| 1639 * value, and one input per constant that it can switch on. | 1670 * value, and one input per constant that it can switch on. |
| 1640 * Its block has one successor per constant, and one for the default. | 1671 * Its block has one successor per constant, and one for the default. |
| 1641 */ | 1672 */ |
| 1642 class HSwitch extends HControlFlow { | 1673 class HSwitch extends HControlFlow { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1657 String toString() => "HSwitch cases = $inputs"; | 1688 String toString() => "HSwitch cases = $inputs"; |
| 1658 } | 1689 } |
| 1659 | 1690 |
| 1660 class HTruncatingDivide extends HBinaryArithmetic { | 1691 class HTruncatingDivide extends HBinaryArithmetic { |
| 1661 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) | 1692 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) |
| 1662 : super(target, left, right); | 1693 : super(target, left, right); |
| 1663 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); | 1694 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); |
| 1664 | 1695 |
| 1665 TruncatingDivideOperation get operation | 1696 TruncatingDivideOperation get operation |
| 1666 => const TruncatingDivideOperation(); | 1697 => const TruncatingDivideOperation(); |
| 1667 int typeCode() => 10; | 1698 int typeCode() => HInstruction.TRUNCATING_DIVIDE_TYPECODE; |
| 1668 bool typeEquals(other) => other is HTruncatingDivide; | 1699 bool typeEquals(other) => other is HTruncatingDivide; |
| 1669 bool dataEquals(HInstruction other) => true; | 1700 bool dataEquals(HInstruction other) => true; |
| 1670 } | 1701 } |
| 1671 | 1702 |
| 1672 | 1703 |
| 1673 // TODO(floitsch): Should HBinaryArithmetic really be the super class of | 1704 // TODO(floitsch): Should HBinaryArithmetic really be the super class of |
| 1674 // HBinaryBitOp? | 1705 // HBinaryBitOp? |
| 1675 class HBinaryBitOp extends HBinaryArithmetic { | 1706 class HBinaryBitOp extends HBinaryArithmetic { |
| 1676 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) | 1707 HBinaryBitOp(HStatic target, HInstruction left, HInstruction right) |
| 1677 : super(target, left, right); | 1708 : super(target, left, right); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 // shift count is guaranteed to be an integer in the [0,31] range. | 1744 // shift count is guaranteed to be an integer in the [0,31] range. |
| 1714 bool isBuiltin(HTypeMap types) { | 1745 bool isBuiltin(HTypeMap types) { |
| 1715 if (!left.isNumber(types) || !right.isConstantInteger()) return false; | 1746 if (!left.isNumber(types) || !right.isConstantInteger()) return false; |
| 1716 HConstant rightConstant = right; | 1747 HConstant rightConstant = right; |
| 1717 IntConstant intConstant = rightConstant.constant; | 1748 IntConstant intConstant = rightConstant.constant; |
| 1718 int count = intConstant.value; | 1749 int count = intConstant.value; |
| 1719 return count >= 0 && count <= 31; | 1750 return count >= 0 && count <= 31; |
| 1720 } | 1751 } |
| 1721 | 1752 |
| 1722 ShiftLeftOperation get operation => const ShiftLeftOperation(); | 1753 ShiftLeftOperation get operation => const ShiftLeftOperation(); |
| 1723 int typeCode() => 11; | 1754 int typeCode() => HInstruction.SHIFT_LEFT_TYPECODE; |
| 1724 bool typeEquals(other) => other is HShiftLeft; | 1755 bool typeEquals(other) => other is HShiftLeft; |
| 1725 bool dataEquals(HInstruction other) => true; | 1756 bool dataEquals(HInstruction other) => true; |
| 1726 } | 1757 } |
| 1727 | 1758 |
| 1728 class HShiftRight extends HBinaryBitOp { | 1759 class HShiftRight extends HBinaryBitOp { |
| 1729 HShiftRight(HStatic target, HInstruction left, HInstruction right) | 1760 HShiftRight(HStatic target, HInstruction left, HInstruction right) |
| 1730 : super(target, left, right); | 1761 : super(target, left, right); |
| 1731 accept(HVisitor visitor) => visitor.visitShiftRight(this); | 1762 accept(HVisitor visitor) => visitor.visitShiftRight(this); |
| 1732 | 1763 |
| 1733 // Shift right cannot be mapped to the native operator easily. | 1764 // Shift right cannot be mapped to the native operator easily. |
| 1734 bool isBuiltin(HTypeMap types) => false; | 1765 bool isBuiltin(HTypeMap types) => false; |
| 1735 | 1766 |
| 1736 ShiftRightOperation get operation => const ShiftRightOperation(); | 1767 ShiftRightOperation get operation => const ShiftRightOperation(); |
| 1737 int typeCode() => 12; | 1768 int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE; |
| 1738 bool typeEquals(other) => other is HShiftRight; | 1769 bool typeEquals(other) => other is HShiftRight; |
| 1739 bool dataEquals(HInstruction other) => true; | 1770 bool dataEquals(HInstruction other) => true; |
| 1740 } | 1771 } |
| 1741 | 1772 |
| 1742 class HBitOr extends HBinaryBitOp { | 1773 class HBitOr extends HBinaryBitOp { |
| 1743 HBitOr(HStatic target, HInstruction left, HInstruction right) | 1774 HBitOr(HStatic target, HInstruction left, HInstruction right) |
| 1744 : super(target, left, right); | 1775 : super(target, left, right); |
| 1745 accept(HVisitor visitor) => visitor.visitBitOr(this); | 1776 accept(HVisitor visitor) => visitor.visitBitOr(this); |
| 1746 | 1777 |
| 1747 BitOrOperation get operation => const BitOrOperation(); | 1778 BitOrOperation get operation => const BitOrOperation(); |
| 1748 int typeCode() => 13; | 1779 int typeCode() => HInstruction.BIT_OR_TYPECODE; |
| 1749 bool typeEquals(other) => other is HBitOr; | 1780 bool typeEquals(other) => other is HBitOr; |
| 1750 bool dataEquals(HInstruction other) => true; | 1781 bool dataEquals(HInstruction other) => true; |
| 1751 } | 1782 } |
| 1752 | 1783 |
| 1753 class HBitAnd extends HBinaryBitOp { | 1784 class HBitAnd extends HBinaryBitOp { |
| 1754 HBitAnd(HStatic target, HInstruction left, HInstruction right) | 1785 HBitAnd(HStatic target, HInstruction left, HInstruction right) |
| 1755 : super(target, left, right); | 1786 : super(target, left, right); |
| 1756 accept(HVisitor visitor) => visitor.visitBitAnd(this); | 1787 accept(HVisitor visitor) => visitor.visitBitAnd(this); |
| 1757 | 1788 |
| 1758 BitAndOperation get operation => const BitAndOperation(); | 1789 BitAndOperation get operation => const BitAndOperation(); |
| 1759 int typeCode() => 14; | 1790 int typeCode() => HInstruction.BIT_AND_TYPECODE; |
| 1760 bool typeEquals(other) => other is HBitAnd; | 1791 bool typeEquals(other) => other is HBitAnd; |
| 1761 bool dataEquals(HInstruction other) => true; | 1792 bool dataEquals(HInstruction other) => true; |
| 1762 } | 1793 } |
| 1763 | 1794 |
| 1764 class HBitXor extends HBinaryBitOp { | 1795 class HBitXor extends HBinaryBitOp { |
| 1765 HBitXor(HStatic target, HInstruction left, HInstruction right) | 1796 HBitXor(HStatic target, HInstruction left, HInstruction right) |
| 1766 : super(target, left, right); | 1797 : super(target, left, right); |
| 1767 accept(HVisitor visitor) => visitor.visitBitXor(this); | 1798 accept(HVisitor visitor) => visitor.visitBitXor(this); |
| 1768 | 1799 |
| 1769 BitXorOperation get operation => const BitXorOperation(); | 1800 BitXorOperation get operation => const BitXorOperation(); |
| 1770 int typeCode() => 15; | 1801 int typeCode() => HInstruction.BIT_XOR_TYPECODE; |
| 1771 bool typeEquals(other) => other is HBitXor; | 1802 bool typeEquals(other) => other is HBitXor; |
| 1772 bool dataEquals(HInstruction other) => true; | 1803 bool dataEquals(HInstruction other) => true; |
| 1773 } | 1804 } |
| 1774 | 1805 |
| 1775 class HInvokeUnary extends HInvokeStatic { | 1806 class HInvokeUnary extends HInvokeStatic { |
| 1776 HInvokeUnary(HStatic target, HInstruction input) | 1807 HInvokeUnary(HStatic target, HInstruction input) |
| 1777 : super(<HInstruction>[target, input]); | 1808 : super(<HInstruction>[target, input]); |
| 1778 | 1809 |
| 1779 HInstruction get operand => inputs[1]; | 1810 HInstruction get operand => inputs[1]; |
| 1780 | 1811 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1812 HType computeLikelyType(HTypeMap types) => HType.NUMBER; | 1843 HType computeLikelyType(HTypeMap types) => HType.NUMBER; |
| 1813 | 1844 |
| 1814 abstract UnaryOperation get operation(); | 1845 abstract UnaryOperation get operation(); |
| 1815 } | 1846 } |
| 1816 | 1847 |
| 1817 class HNegate extends HInvokeUnary { | 1848 class HNegate extends HInvokeUnary { |
| 1818 HNegate(HStatic target, HInstruction input) : super(target, input); | 1849 HNegate(HStatic target, HInstruction input) : super(target, input); |
| 1819 accept(HVisitor visitor) => visitor.visitNegate(this); | 1850 accept(HVisitor visitor) => visitor.visitNegate(this); |
| 1820 | 1851 |
| 1821 NegateOperation get operation => const NegateOperation(); | 1852 NegateOperation get operation => const NegateOperation(); |
| 1822 int typeCode() => 16; | 1853 int typeCode() => HInstruction.NEGATE_TYPECODE; |
| 1823 bool typeEquals(other) => other is HNegate; | 1854 bool typeEquals(other) => other is HNegate; |
| 1824 bool dataEquals(HInstruction other) => true; | 1855 bool dataEquals(HInstruction other) => true; |
| 1825 } | 1856 } |
| 1826 | 1857 |
| 1827 class HBitNot extends HInvokeUnary { | 1858 class HBitNot extends HInvokeUnary { |
| 1828 HBitNot(HStatic target, HInstruction input) : super(target, input); | 1859 HBitNot(HStatic target, HInstruction input) : super(target, input); |
| 1829 accept(HVisitor visitor) => visitor.visitBitNot(this); | 1860 accept(HVisitor visitor) => visitor.visitBitNot(this); |
| 1830 | 1861 |
| 1831 HType computeTypeFromInputTypes(HTypeMap types) { | 1862 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1832 // All bitwise operations on primitive types either produce an | 1863 // All bitwise operations on primitive types either produce an |
| 1833 // integer or throw an error. | 1864 // integer or throw an error. |
| 1834 if (operand.isPrimitive(types)) return HType.INTEGER; | 1865 if (operand.isPrimitive(types)) return HType.INTEGER; |
| 1835 return HType.UNKNOWN; | 1866 return HType.UNKNOWN; |
| 1836 } | 1867 } |
| 1837 | 1868 |
| 1838 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1869 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
| 1839 HTypeMap types) { | 1870 HTypeMap types) { |
| 1840 HType propagatedType = types[this]; | 1871 HType propagatedType = types[this]; |
| 1841 // Bit operations only work on integers. If there is no desired output | 1872 // Bit operations only work on integers. If there is no desired output |
| 1842 // type or if it as a number we want to get an integer as input. | 1873 // type or if it as a number we want to get an integer as input. |
| 1843 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 1874 if (propagatedType.isUnknown() || propagatedType.isNumber()) { |
| 1844 return HType.INTEGER; | 1875 return HType.INTEGER; |
| 1845 } | 1876 } |
| 1846 return HType.UNKNOWN; | 1877 return HType.UNKNOWN; |
| 1847 } | 1878 } |
| 1848 | 1879 |
| 1849 BitNotOperation get operation => const BitNotOperation(); | 1880 BitNotOperation get operation => const BitNotOperation(); |
| 1850 int typeCode() => 17; | 1881 int typeCode() => HInstruction.BIT_NOT_TYPECODE; |
| 1851 bool typeEquals(other) => other is HBitNot; | 1882 bool typeEquals(other) => other is HBitNot; |
| 1852 bool dataEquals(HInstruction other) => true; | 1883 bool dataEquals(HInstruction other) => true; |
| 1853 } | 1884 } |
| 1854 | 1885 |
| 1855 class HExit extends HControlFlow { | 1886 class HExit extends HControlFlow { |
| 1856 HExit() : super(const <HInstruction>[]); | 1887 HExit() : super(const <HInstruction>[]); |
| 1857 toString() => 'exit'; | 1888 toString() => 'exit'; |
| 1858 accept(HVisitor visitor) => visitor.visitExit(this); | 1889 accept(HVisitor visitor) => visitor.visitExit(this); |
| 1859 } | 1890 } |
| 1860 | 1891 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1968 } | 1999 } |
| 1969 | 2000 |
| 1970 HType get guaranteedType => HType.BOOLEAN; | 2001 HType get guaranteedType => HType.BOOLEAN; |
| 1971 | 2002 |
| 1972 // 'Not' only works on booleans. That's what we want as input. | 2003 // 'Not' only works on booleans. That's what we want as input. |
| 1973 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { | 2004 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { |
| 1974 return HType.BOOLEAN; | 2005 return HType.BOOLEAN; |
| 1975 } | 2006 } |
| 1976 | 2007 |
| 1977 accept(HVisitor visitor) => visitor.visitNot(this); | 2008 accept(HVisitor visitor) => visitor.visitNot(this); |
| 1978 int typeCode() => 18; | 2009 int typeCode() => HInstruction.NOT_TYPECODE; |
| 1979 bool typeEquals(other) => other is HNot; | 2010 bool typeEquals(other) => other is HNot; |
| 1980 bool dataEquals(HInstruction other) => true; | 2011 bool dataEquals(HInstruction other) => true; |
| 1981 } | 2012 } |
| 1982 | 2013 |
| 1983 /** | 2014 /** |
| 1984 * An [HLocalValue] represents a local. Unlike [HParameterValue]s its | 2015 * An [HLocalValue] represents a local. Unlike [HParameterValue]s its |
| 1985 * first use must be in an HLocalSet. That is, [HParameterValue]s have a | 2016 * first use must be in an HLocalSet. That is, [HParameterValue]s have a |
| 1986 * value from the start, whereas [HLocalValue]s need to be initialized first. | 2017 * value from the start, whereas [HLocalValue]s need to be initialized first. |
| 1987 */ | 2018 */ |
| 1988 class HLocalValue extends HInstruction { | 2019 class HLocalValue extends HInstruction { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 return HType.READABLE_ARRAY; | 2219 return HType.READABLE_ARRAY; |
| 2189 } | 2220 } |
| 2190 // String equality testing is much more common than array equality testing. | 2221 // String equality testing is much more common than array equality testing. |
| 2191 if (input == right && right.isIndexablePrimitive(types)) { | 2222 if (input == right && right.isIndexablePrimitive(types)) { |
| 2192 return HType.STRING; | 2223 return HType.STRING; |
| 2193 } | 2224 } |
| 2194 return HType.UNKNOWN; | 2225 return HType.UNKNOWN; |
| 2195 } | 2226 } |
| 2196 | 2227 |
| 2197 EqualsOperation get operation => const EqualsOperation(); | 2228 EqualsOperation get operation => const EqualsOperation(); |
| 2198 int typeCode() => 19; | 2229 int typeCode() => HInstruction.EQUALS_TYPECODE; |
| 2199 bool typeEquals(other) => other is HEquals; | 2230 bool typeEquals(other) => other is HEquals; |
| 2200 bool dataEquals(HInstruction other) => true; | 2231 bool dataEquals(HInstruction other) => true; |
| 2201 } | 2232 } |
| 2202 | 2233 |
| 2203 class HIdentity extends HRelational { | 2234 class HIdentity extends HRelational { |
| 2204 HIdentity(HStatic target, HInstruction left, HInstruction right) | 2235 HIdentity(HStatic target, HInstruction left, HInstruction right) |
| 2205 : super(target, left, right); | 2236 : super(target, left, right); |
| 2206 accept(HVisitor visitor) => visitor.visitIdentity(this); | 2237 accept(HVisitor visitor) => visitor.visitIdentity(this); |
| 2207 | 2238 |
| 2208 bool isBuiltin(HTypeMap types) => true; | 2239 bool isBuiltin(HTypeMap types) => true; |
| 2209 | 2240 |
| 2210 HType get guaranteedType => HType.BOOLEAN; | 2241 HType get guaranteedType => HType.BOOLEAN; |
| 2211 HType computeTypeFromInputTypes(HTypeMap types) | 2242 HType computeTypeFromInputTypes(HTypeMap types) |
| 2212 => HType.BOOLEAN; | 2243 => HType.BOOLEAN; |
| 2213 // Note that the identity operator really does not care for its input types. | 2244 // Note that the identity operator really does not care for its input types. |
| 2214 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) | 2245 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) |
| 2215 => HType.UNKNOWN; | 2246 => HType.UNKNOWN; |
| 2216 | 2247 |
| 2217 IdentityOperation get operation => const IdentityOperation(); | 2248 IdentityOperation get operation => const IdentityOperation(); |
| 2218 int typeCode() => 20; | 2249 int typeCode() => HInstruction.IDENTITY_TYPECODE; |
| 2219 bool typeEquals(other) => other is HIdentity; | 2250 bool typeEquals(other) => other is HIdentity; |
| 2220 bool dataEquals(HInstruction other) => true; | 2251 bool dataEquals(HInstruction other) => true; |
| 2221 } | 2252 } |
| 2222 | 2253 |
| 2223 class HGreater extends HRelational { | 2254 class HGreater extends HRelational { |
| 2224 HGreater(HStatic target, HInstruction left, HInstruction right) | 2255 HGreater(HStatic target, HInstruction left, HInstruction right) |
| 2225 : super(target, left, right); | 2256 : super(target, left, right); |
| 2226 accept(HVisitor visitor) => visitor.visitGreater(this); | 2257 accept(HVisitor visitor) => visitor.visitGreater(this); |
| 2227 | 2258 |
| 2228 GreaterOperation get operation => const GreaterOperation(); | 2259 GreaterOperation get operation => const GreaterOperation(); |
| 2229 int typeCode() => 21; | 2260 int typeCode() => HInstruction.GREATER_TYPECODE; |
| 2230 bool typeEquals(other) => other is HGreater; | 2261 bool typeEquals(other) => other is HGreater; |
| 2231 bool dataEquals(HInstruction other) => true; | 2262 bool dataEquals(HInstruction other) => true; |
| 2232 } | 2263 } |
| 2233 | 2264 |
| 2234 class HGreaterEqual extends HRelational { | 2265 class HGreaterEqual extends HRelational { |
| 2235 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) | 2266 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) |
| 2236 : super(target, left, right); | 2267 : super(target, left, right); |
| 2237 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); | 2268 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); |
| 2238 | 2269 |
| 2239 GreaterEqualOperation get operation => const GreaterEqualOperation(); | 2270 GreaterEqualOperation get operation => const GreaterEqualOperation(); |
| 2240 int typeCode() => 22; | 2271 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; |
| 2241 bool typeEquals(other) => other is HGreaterEqual; | 2272 bool typeEquals(other) => other is HGreaterEqual; |
| 2242 bool dataEquals(HInstruction other) => true; | 2273 bool dataEquals(HInstruction other) => true; |
| 2243 } | 2274 } |
| 2244 | 2275 |
| 2245 class HLess extends HRelational { | 2276 class HLess extends HRelational { |
| 2246 HLess(HStatic target, HInstruction left, HInstruction right) | 2277 HLess(HStatic target, HInstruction left, HInstruction right) |
| 2247 : super(target, left, right); | 2278 : super(target, left, right); |
| 2248 accept(HVisitor visitor) => visitor.visitLess(this); | 2279 accept(HVisitor visitor) => visitor.visitLess(this); |
| 2249 | 2280 |
| 2250 LessOperation get operation => const LessOperation(); | 2281 LessOperation get operation => const LessOperation(); |
| 2251 int typeCode() => 23; | 2282 int typeCode() => HInstruction.LESS_TYPECODE; |
| 2252 bool typeEquals(other) => other is HLess; | 2283 bool typeEquals(other) => other is HLess; |
| 2253 bool dataEquals(HInstruction other) => true; | 2284 bool dataEquals(HInstruction other) => true; |
| 2254 } | 2285 } |
| 2255 | 2286 |
| 2256 class HLessEqual extends HRelational { | 2287 class HLessEqual extends HRelational { |
| 2257 HLessEqual(HStatic target, HInstruction left, HInstruction right) | 2288 HLessEqual(HStatic target, HInstruction left, HInstruction right) |
| 2258 : super(target, left, right); | 2289 : super(target, left, right); |
| 2259 accept(HVisitor visitor) => visitor.visitLessEqual(this); | 2290 accept(HVisitor visitor) => visitor.visitLessEqual(this); |
| 2260 | 2291 |
| 2261 LessEqualOperation get operation => const LessEqualOperation(); | 2292 LessEqualOperation get operation => const LessEqualOperation(); |
| 2262 int typeCode() => 24; | 2293 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; |
| 2263 bool typeEquals(other) => other is HLessEqual; | 2294 bool typeEquals(other) => other is HLessEqual; |
| 2264 bool dataEquals(HInstruction other) => true; | 2295 bool dataEquals(HInstruction other) => true; |
| 2265 } | 2296 } |
| 2266 | 2297 |
| 2267 class HReturn extends HControlFlow { | 2298 class HReturn extends HControlFlow { |
| 2268 HReturn(value) : super(<HInstruction>[value]); | 2299 HReturn(value) : super(<HInstruction>[value]); |
| 2269 toString() => 'return'; | 2300 toString() => 'return'; |
| 2270 accept(HVisitor visitor) => visitor.visitReturn(this); | 2301 accept(HVisitor visitor) => visitor.visitReturn(this); |
| 2271 } | 2302 } |
| 2272 | 2303 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2284 void prepareGvn(HTypeMap types) { | 2315 void prepareGvn(HTypeMap types) { |
| 2285 if (!element.isAssignable()) { | 2316 if (!element.isAssignable()) { |
| 2286 clearAllSideEffects(); | 2317 clearAllSideEffects(); |
| 2287 setUseGvn(); | 2318 setUseGvn(); |
| 2288 } | 2319 } |
| 2289 } | 2320 } |
| 2290 toString() => 'static ${element.name}'; | 2321 toString() => 'static ${element.name}'; |
| 2291 accept(HVisitor visitor) => visitor.visitStatic(this); | 2322 accept(HVisitor visitor) => visitor.visitStatic(this); |
| 2292 | 2323 |
| 2293 int gvnHashCode() => super.gvnHashCode() ^ element.hashCode(); | 2324 int gvnHashCode() => super.gvnHashCode() ^ element.hashCode(); |
| 2294 int typeCode() => 25; | 2325 int typeCode() => HInstruction.STATIC_TYPECODE; |
| 2295 bool typeEquals(other) => other is HStatic; | 2326 bool typeEquals(other) => other is HStatic; |
| 2296 bool dataEquals(HStatic other) => element == other.element; | 2327 bool dataEquals(HStatic other) => element == other.element; |
| 2297 bool isCodeMotionInvariant() => !element.isAssignable(); | 2328 bool isCodeMotionInvariant() => !element.isAssignable(); |
| 2298 } | 2329 } |
| 2299 | 2330 |
| 2300 class HStaticStore extends HInstruction { | 2331 class HStaticStore extends HInstruction { |
| 2301 Element element; | 2332 Element element; |
| 2302 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]); | 2333 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]); |
| 2303 toString() => 'static store ${element.name}'; | 2334 toString() => 'static store ${element.name}'; |
| 2304 accept(HVisitor visitor) => visitor.visitStaticStore(this); | 2335 accept(HVisitor visitor) => visitor.visitStaticStore(this); |
| 2305 | 2336 |
| 2306 int typeCode() => 26; | 2337 int typeCode() => HInstruction.STATIC_STORE_TYPECODE; |
| 2307 bool typeEquals(other) => other is HStaticStore; | 2338 bool typeEquals(other) => other is HStaticStore; |
| 2308 bool dataEquals(HStaticStore other) => element == other.element; | 2339 bool dataEquals(HStaticStore other) => element == other.element; |
| 2309 bool isStatement(HTypeMap types) => true; | 2340 bool isStatement(HTypeMap types) => true; |
| 2310 } | 2341 } |
| 2311 | 2342 |
| 2312 class HLiteralList extends HInstruction { | 2343 class HLiteralList extends HInstruction { |
| 2313 HLiteralList(inputs) : super(inputs); | 2344 HLiteralList(inputs) : super(inputs); |
| 2314 toString() => 'literal list'; | 2345 toString() => 'literal list'; |
| 2315 accept(HVisitor visitor) => visitor.visitLiteralList(this); | 2346 accept(HVisitor visitor) => visitor.visitLiteralList(this); |
| 2316 | 2347 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; | 2468 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; |
| 2438 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; | 2469 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; |
| 2439 | 2470 |
| 2440 HType get guaranteedType => type; | 2471 HType get guaranteedType => type; |
| 2441 | 2472 |
| 2442 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2473 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2443 | 2474 |
| 2444 bool isStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK; | 2475 bool isStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK; |
| 2445 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; | 2476 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; |
| 2446 | 2477 |
| 2447 int typeCode() => 28; | 2478 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; |
| 2448 bool typeEquals(HInstruction other) => other is HTypeConversion; | 2479 bool typeEquals(HInstruction other) => other is HTypeConversion; |
| 2449 bool dataEquals(HTypeConversion other) { | 2480 bool dataEquals(HTypeConversion other) { |
| 2450 return type == other.type && kind == other.kind; | 2481 return type == other.type && kind == other.kind; |
| 2451 } | 2482 } |
| 2452 } | 2483 } |
| 2453 | 2484 |
| 2454 class HStringConcat extends HInstruction { | 2485 class HStringConcat extends HInstruction { |
| 2455 final Node node; | 2486 final Node node; |
| 2456 HStringConcat(HInstruction left, HInstruction right, this.node) | 2487 HStringConcat(HInstruction left, HInstruction right, this.node) |
| 2457 : super(<HInstruction>[left, right]); | 2488 : super(<HInstruction>[left, right]); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2787 HBasicBlock get start => expression.start; | 2818 HBasicBlock get start => expression.start; |
| 2788 HBasicBlock get end { | 2819 HBasicBlock get end { |
| 2789 // We don't create a switch block if there are no cases. | 2820 // We don't create a switch block if there are no cases. |
| 2790 assert(!statements.isEmpty()); | 2821 assert(!statements.isEmpty()); |
| 2791 return statements.last().end; | 2822 return statements.last().end; |
| 2792 } | 2823 } |
| 2793 | 2824 |
| 2794 bool accept(HStatementInformationVisitor visitor) => | 2825 bool accept(HStatementInformationVisitor visitor) => |
| 2795 visitor.visitSwitchInfo(this); | 2826 visitor.visitSwitchInfo(this); |
| 2796 } | 2827 } |
| OLD | NEW |