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

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

Issue 10876008: Remove most superfluous getter arguments from dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 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 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 assert(block !== null); 339 assert(block !== null);
340 return start.id <= block.id && block.id <= end.id; 340 return start.id <= block.id && block.id <= end.id;
341 } 341 }
342 } 342 }
343 343
344 class SubExpression extends SubGraph { 344 class SubExpression extends SubGraph {
345 const SubExpression(HBasicBlock start, HBasicBlock end) 345 const SubExpression(HBasicBlock start, HBasicBlock end)
346 : super(start, end); 346 : super(start, end);
347 347
348 /** Find the condition expression if this sub-expression is a condition. */ 348 /** Find the condition expression if this sub-expression is a condition. */
349 HInstruction get conditionExpression() { 349 HInstruction get conditionExpression {
350 HInstruction last = end.last; 350 HInstruction last = end.last;
351 if (last is HConditionalBranch || last is HSwitch) return last.inputs[0]; 351 if (last is HConditionalBranch || last is HSwitch) return last.inputs[0];
352 return null; 352 return null;
353 } 353 }
354 } 354 }
355 355
356 class HInstructionList { 356 class HInstructionList {
357 HInstruction first = null; 357 HInstruction first = null;
358 HInstruction last = null; 358 HInstruction last = null;
359 359
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 468 }
469 469
470 void setBlockFlow(HBlockInformation blockInfo, HBasicBlock continuation) { 470 void setBlockFlow(HBlockInformation blockInfo, HBasicBlock continuation) {
471 blockFlow = new HBlockFlow(blockInfo, continuation); 471 blockFlow = new HBlockFlow(blockInfo, continuation);
472 } 472 }
473 473
474 bool isLabeledBlock() => 474 bool isLabeledBlock() =>
475 blockFlow !== null && 475 blockFlow !== null &&
476 blockFlow.body is HLabeledBlockInformation; 476 blockFlow.body is HLabeledBlockInformation;
477 477
478 HBasicBlock get enclosingLoopHeader() { 478 HBasicBlock get enclosingLoopHeader {
479 if (isLoopHeader()) return this; 479 if (isLoopHeader()) return this;
480 return parentLoopHeader; 480 return parentLoopHeader;
481 } 481 }
482 482
483 bool hasBailoutTargets() => !bailoutTargets.isEmpty(); 483 bool hasBailoutTargets() => !bailoutTargets.isEmpty();
484 484
485 void open() { 485 void open() {
486 assert(isNew()); 486 assert(isNew());
487 status = STATUS_OPEN; 487 status = STATUS_OPEN;
488 } 488 }
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 } 1046 }
1047 } 1047 }
1048 1048
1049 class HBoolify extends HInstruction { 1049 class HBoolify extends HInstruction {
1050 HBoolify(HInstruction value) : super(<HInstruction>[value]); 1050 HBoolify(HInstruction value) : super(<HInstruction>[value]);
1051 void prepareGvn(HTypeMap types) { 1051 void prepareGvn(HTypeMap types) {
1052 assert(!hasSideEffects(types)); 1052 assert(!hasSideEffects(types));
1053 setUseGvn(); 1053 setUseGvn();
1054 } 1054 }
1055 1055
1056 HType get guaranteedType() => HType.BOOLEAN; 1056 HType get guaranteedType => HType.BOOLEAN;
1057 1057
1058 accept(HVisitor visitor) => visitor.visitBoolify(this); 1058 accept(HVisitor visitor) => visitor.visitBoolify(this);
1059 int typeCode() => 0; 1059 int typeCode() => 0;
1060 bool typeEquals(other) => other is HBoolify; 1060 bool typeEquals(other) => other is HBoolify;
1061 bool dataEquals(HInstruction other) => true; 1061 bool dataEquals(HInstruction other) => true;
1062 } 1062 }
1063 1063
1064 /** 1064 /**
1065 * A [HCheck] instruction is an instruction that might do a dynamic 1065 * A [HCheck] instruction is an instruction that might do a dynamic
1066 * check at runtime on another instruction. To have proper instruction 1066 * check at runtime on another instruction. To have proper instruction
1067 * dependencies in the graph, instructions that depend on the check 1067 * dependencies in the graph, instructions that depend on the check
1068 * being done reference the [HCheck] instruction instead of the 1068 * being done reference the [HCheck] instruction instead of the
1069 * instruction itself. 1069 * instruction itself.
1070 */ 1070 */
1071 abstract class HCheck extends HInstruction { 1071 abstract class HCheck extends HInstruction {
1072 HCheck(inputs) : super(inputs); 1072 HCheck(inputs) : super(inputs);
1073 HInstruction get checkedInput() => inputs[0]; 1073 HInstruction get checkedInput => inputs[0];
1074 bool isStatement(HTypeMap types) => true; 1074 bool isStatement(HTypeMap types) => true;
1075 void prepareGvn(HTypeMap types) { 1075 void prepareGvn(HTypeMap types) {
1076 assert(!hasSideEffects(types)); 1076 assert(!hasSideEffects(types));
1077 setUseGvn(); 1077 setUseGvn();
1078 } 1078 }
1079 } 1079 }
1080 1080
1081 class HBailoutTarget extends HInstruction { 1081 class HBailoutTarget extends HInstruction {
1082 final int state; 1082 final int state;
1083 bool isEnabled = false; 1083 bool isEnabled = false;
(...skipping 12 matching lines...) Expand all
1096 bool dataEquals(HBailoutTarget other) => other.state == state; 1096 bool dataEquals(HBailoutTarget other) => other.state == state;
1097 } 1097 }
1098 1098
1099 class HTypeGuard extends HCheck { 1099 class HTypeGuard extends HCheck {
1100 final HType guardedType; 1100 final HType guardedType;
1101 bool isEnabled = false; 1101 bool isEnabled = false;
1102 1102
1103 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget) 1103 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget)
1104 : super(<HInstruction>[guarded, bailoutTarget]); 1104 : super(<HInstruction>[guarded, bailoutTarget]);
1105 1105
1106 HInstruction get guarded() => inputs[0]; 1106 HInstruction get guarded => inputs[0];
1107 HInstruction get checkedInput() => guarded; 1107 HInstruction get checkedInput => guarded;
1108 HBailoutTarget get bailoutTarget() => inputs[1]; 1108 HBailoutTarget get bailoutTarget => inputs[1];
1109 int get state() => bailoutTarget.state; 1109 int get state => bailoutTarget.state;
1110 1110
1111 HType computeTypeFromInputTypes(HTypeMap types) { 1111 HType computeTypeFromInputTypes(HTypeMap types) {
1112 return isEnabled ? guardedType : types[guarded]; 1112 return isEnabled ? guardedType : types[guarded];
1113 } 1113 }
1114 1114
1115 HType get guaranteedType() => isEnabled ? guardedType : HType.UNKNOWN; 1115 HType get guaranteedType => isEnabled ? guardedType : HType.UNKNOWN;
1116 1116
1117 bool isControlFlow() => true; 1117 bool isControlFlow() => true;
1118 1118
1119 bool isStatement(HTypeMap types) => isEnabled; 1119 bool isStatement(HTypeMap types) => isEnabled;
1120 1120
1121 accept(HVisitor visitor) => visitor.visitTypeGuard(this); 1121 accept(HVisitor visitor) => visitor.visitTypeGuard(this);
1122 int typeCode() => 1; 1122 int typeCode() => 1;
1123 bool typeEquals(other) => other is HTypeGuard; 1123 bool typeEquals(other) => other is HTypeGuard;
1124 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; 1124 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType;
1125 } 1125 }
1126 1126
1127 class HBoundsCheck extends HCheck { 1127 class HBoundsCheck extends HCheck {
1128 static final int ALWAYS_FALSE = 0; 1128 static final int ALWAYS_FALSE = 0;
1129 static final int FULL_CHECK = 1; 1129 static final int FULL_CHECK = 1;
1130 static final int ALWAYS_ABOVE_ZERO = 2; 1130 static final int ALWAYS_ABOVE_ZERO = 2;
1131 static final int ALWAYS_TRUE = 3; 1131 static final int ALWAYS_TRUE = 3;
1132 /** 1132 /**
1133 * Details which tests have been done statically during compilation. 1133 * Details which tests have been done statically during compilation.
1134 * Default is that all checks must be performed dynamically. 1134 * Default is that all checks must be performed dynamically.
1135 */ 1135 */
1136 int staticChecks = FULL_CHECK; 1136 int staticChecks = FULL_CHECK;
1137 1137
1138 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); 1138 HBoundsCheck(length, index) : super(<HInstruction>[length, index]);
1139 1139
1140 HInstruction get length() => inputs[1]; 1140 HInstruction get length => inputs[1];
1141 HInstruction get index() => inputs[0]; 1141 HInstruction get index => inputs[0];
1142 bool isControlFlow() => true; 1142 bool isControlFlow() => true;
1143 1143
1144 HType get guaranteedType() => HType.INTEGER; 1144 HType get guaranteedType => HType.INTEGER;
1145 1145
1146 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); 1146 accept(HVisitor visitor) => visitor.visitBoundsCheck(this);
1147 int typeCode() => 2; 1147 int typeCode() => 2;
1148 bool typeEquals(other) => other is HBoundsCheck; 1148 bool typeEquals(other) => other is HBoundsCheck;
1149 bool dataEquals(HInstruction other) => true; 1149 bool dataEquals(HInstruction other) => true;
1150 } 1150 }
1151 1151
1152 class HIntegerCheck extends HCheck { 1152 class HIntegerCheck extends HCheck {
1153 bool alwaysFalse = false; 1153 bool alwaysFalse = false;
1154 1154
1155 HIntegerCheck(value) : super(<HInstruction>[value]); 1155 HIntegerCheck(value) : super(<HInstruction>[value]);
1156 1156
1157 HInstruction get value() => inputs[0]; 1157 HInstruction get value => inputs[0];
1158 bool isControlFlow() => true; 1158 bool isControlFlow() => true;
1159 1159
1160 HType get guaranteedType() => HType.INTEGER; 1160 HType get guaranteedType => HType.INTEGER;
1161 1161
1162 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { 1162 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) {
1163 // If the desired type of the input is already a number, we want 1163 // If the desired type of the input is already a number, we want
1164 // to specialize it to an integer. 1164 // to specialize it to an integer.
1165 return input.isNumber(types) 1165 return input.isNumber(types)
1166 ? HType.INTEGER 1166 ? HType.INTEGER
1167 : super.computeDesiredTypeForInput(input, types); 1167 : super.computeDesiredTypeForInput(input, types);
1168 } 1168 }
1169 1169
1170 accept(HVisitor visitor) => visitor.visitIntegerCheck(this); 1170 accept(HVisitor visitor) => visitor.visitIntegerCheck(this);
1171 int typeCode() => 3; 1171 int typeCode() => 3;
1172 bool typeEquals(other) => other is HIntegerCheck; 1172 bool typeEquals(other) => other is HIntegerCheck;
1173 bool dataEquals(HInstruction other) => true; 1173 bool dataEquals(HInstruction other) => true;
1174 } 1174 }
1175 1175
1176 class HConditionalBranch extends HControlFlow { 1176 class HConditionalBranch extends HControlFlow {
1177 HConditionalBranch(inputs) : super(inputs); 1177 HConditionalBranch(inputs) : super(inputs);
1178 HInstruction get condition() => inputs[0]; 1178 HInstruction get condition => inputs[0];
1179 HBasicBlock get trueBranch() => block.successors[0]; 1179 HBasicBlock get trueBranch => block.successors[0];
1180 HBasicBlock get falseBranch() => block.successors[1]; 1180 HBasicBlock get falseBranch => block.successors[1];
1181 abstract toString(); 1181 abstract toString();
1182 } 1182 }
1183 1183
1184 class HControlFlow extends HInstruction { 1184 class HControlFlow extends HInstruction {
1185 HControlFlow(inputs) : super(inputs); 1185 HControlFlow(inputs) : super(inputs);
1186 abstract toString(); 1186 abstract toString();
1187 void prepareGvn(HTypeMap types) { 1187 void prepareGvn(HTypeMap types) {
1188 // Control flow does not have side-effects. 1188 // Control flow does not have side-effects.
1189 } 1189 }
1190 bool isControlFlow() => true; 1190 bool isControlFlow() => true;
(...skipping 13 matching lines...) Expand all
1204 abstract accept(HVisitor visitor); 1204 abstract accept(HVisitor visitor);
1205 } 1205 }
1206 1206
1207 class HInvokeDynamic extends HInvoke { 1207 class HInvokeDynamic extends HInvoke {
1208 final Selector selector; 1208 final Selector selector;
1209 Element element; 1209 Element element;
1210 1210
1211 HInvokeDynamic(this.selector, this.element, List<HInstruction> inputs) 1211 HInvokeDynamic(this.selector, this.element, List<HInstruction> inputs)
1212 : super(inputs); 1212 : super(inputs);
1213 toString() => 'invoke dynamic: $selector'; 1213 toString() => 'invoke dynamic: $selector';
1214 HInstruction get receiver() => inputs[0]; 1214 HInstruction get receiver => inputs[0];
1215 1215
1216 // TODO(floitsch): make class abstract instead of adding an abstract method. 1216 // TODO(floitsch): make class abstract instead of adding an abstract method.
1217 abstract accept(HVisitor visitor); 1217 abstract accept(HVisitor visitor);
1218 } 1218 }
1219 1219
1220 class HInvokeClosure extends HInvokeDynamic { 1220 class HInvokeClosure extends HInvokeDynamic {
1221 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1221 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1222 : super(selector, null, inputs); 1222 : super(selector, null, inputs);
1223 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1223 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1224 } 1224 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 static final int INVOKE_STATIC_TYPECODE = 30; 1258 static final int INVOKE_STATIC_TYPECODE = 30;
1259 1259
1260 /** The first input must be the target. */ 1260 /** The first input must be the target. */
1261 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { 1261 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) {
1262 guaranteedType = knownType; 1262 guaranteedType = knownType;
1263 } 1263 }
1264 1264
1265 toString() => 'invoke static: ${element.name}'; 1265 toString() => 'invoke static: ${element.name}';
1266 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); 1266 accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
1267 int typeCode() => INVOKE_STATIC_TYPECODE; 1267 int typeCode() => INVOKE_STATIC_TYPECODE;
1268 Element get element() => target.element; 1268 Element get element => target.element;
1269 HStatic get target() => inputs[0]; 1269 HStatic get target => inputs[0];
1270 1270
1271 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { 1271 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) {
1272 // TODO(floitsch): we want the target to be a function. 1272 // TODO(floitsch): we want the target to be a function.
1273 if (input == target) return HType.UNKNOWN; 1273 if (input == target) return HType.UNKNOWN;
1274 return computeDesiredTypeForNonTargetInput(input, types); 1274 return computeDesiredTypeForNonTargetInput(input, types);
1275 } 1275 }
1276 1276
1277 HType computeDesiredTypeForNonTargetInput(HInstruction input, 1277 HType computeDesiredTypeForNonTargetInput(HInstruction input,
1278 HTypeMap types) { 1278 HTypeMap types) {
1279 return HType.UNKNOWN; 1279 return HType.UNKNOWN;
1280 } 1280 }
1281 } 1281 }
1282 1282
1283 class HInvokeSuper extends HInvokeStatic { 1283 class HInvokeSuper extends HInvokeStatic {
1284 final bool isSetter; 1284 final bool isSetter;
1285 HInvokeSuper(inputs, [this.isSetter = false]) : super(inputs); 1285 HInvokeSuper(inputs, [this.isSetter = false]) : super(inputs);
1286 toString() => 'invoke super: ${element.name}'; 1286 toString() => 'invoke super: ${element.name}';
1287 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); 1287 accept(HVisitor visitor) => visitor.visitInvokeSuper(this);
1288 1288
1289 HInstruction get value() { 1289 HInstruction get value {
1290 assert(isSetter); 1290 assert(isSetter);
1291 // Index 0: the element, index 1: 'this'. 1291 // Index 0: the element, index 1: 'this'.
1292 return inputs[2]; 1292 return inputs[2];
1293 } 1293 }
1294 } 1294 }
1295 1295
1296 class HInvokeInterceptor extends HInvokeStatic { 1296 class HInvokeInterceptor extends HInvokeStatic {
1297 final Selector selector; 1297 final Selector selector;
1298 final SourceString name; 1298 final SourceString name;
1299 final bool getter; 1299 final bool getter;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 final bool isFinalOrConst; 1379 final bool isFinalOrConst;
1380 1380
1381 HFieldGet(SourceString name, LibraryElement library, HInstruction receiver, 1381 HFieldGet(SourceString name, LibraryElement library, HInstruction receiver,
1382 [this.isFinalOrConst = false]) 1382 [this.isFinalOrConst = false])
1383 : super(name, library, <HInstruction>[receiver]); 1383 : super(name, library, <HInstruction>[receiver]);
1384 1384
1385 HFieldGet.withElement(Element element, HInstruction receiver, 1385 HFieldGet.withElement(Element element, HInstruction receiver,
1386 [this.isFinalOrConst = false]) 1386 [this.isFinalOrConst = false])
1387 : super.withElement(element, <HInstruction>[receiver]); 1387 : super.withElement(element, <HInstruction>[receiver]);
1388 1388
1389 HInstruction get receiver() => inputs[0]; 1389 HInstruction get receiver => inputs[0];
1390 1390
1391 accept(HVisitor visitor) => visitor.visitFieldGet(this); 1391 accept(HVisitor visitor) => visitor.visitFieldGet(this);
1392 1392
1393 void prepareGvn(HTypeMap types) { 1393 void prepareGvn(HTypeMap types) {
1394 setUseGvn(); 1394 setUseGvn();
1395 clearAllSideEffects(); 1395 clearAllSideEffects();
1396 if (!isFinalOrConst) setDependsOnSomething(); 1396 if (!isFinalOrConst) setDependsOnSomething();
1397 } 1397 }
1398 1398
1399 int typeCode() => 27; 1399 int typeCode() => 27;
1400 bool typeEquals(other) => other is HFieldGet; 1400 bool typeEquals(other) => other is HFieldGet;
1401 bool dataEquals(HFieldGet other) => element == other.element; 1401 bool dataEquals(HFieldGet other) => element == other.element;
1402 String toString() => "FieldGet ${element == null ? fieldName : element}"; 1402 String toString() => "FieldGet ${element == null ? fieldName : element}";
1403 } 1403 }
1404 1404
1405 class HFieldSet extends HFieldAccess { 1405 class HFieldSet extends HFieldAccess {
1406 HFieldSet(SourceString name, 1406 HFieldSet(SourceString name,
1407 LibraryElement library, 1407 LibraryElement library,
1408 HInstruction receiver, 1408 HInstruction receiver,
1409 HInstruction value) 1409 HInstruction value)
1410 : super(name, library, <HInstruction>[receiver, value]); 1410 : super(name, library, <HInstruction>[receiver, value]);
1411 1411
1412 HFieldSet.withElement(Element element, 1412 HFieldSet.withElement(Element element,
1413 HInstruction receiver, 1413 HInstruction receiver,
1414 HInstruction value) 1414 HInstruction value)
1415 : super.withElement(element, <HInstruction>[receiver, value]); 1415 : super.withElement(element, <HInstruction>[receiver, value]);
1416 1416
1417 HInstruction get receiver() => inputs[0]; 1417 HInstruction get receiver => inputs[0];
1418 HInstruction get value() => inputs[1]; 1418 HInstruction get value => inputs[1];
1419 accept(HVisitor visitor) => visitor.visitFieldSet(this); 1419 accept(HVisitor visitor) => visitor.visitFieldSet(this);
1420 1420
1421 void prepareGvn(HTypeMap types) { 1421 void prepareGvn(HTypeMap types) {
1422 // TODO(ngeoffray): implement more fine grained side effects. 1422 // TODO(ngeoffray): implement more fine grained side effects.
1423 setAllSideEffects(); 1423 setAllSideEffects();
1424 } 1424 }
1425 1425
1426 bool isStatement(HTypeMap types) => true; 1426 bool isStatement(HTypeMap types) => true;
1427 String toString() => "FieldSet ${element == null ? fieldName : element}"; 1427 String toString() => "FieldSet ${element == null ? fieldName : element}";
1428 } 1428 }
1429 1429
1430 class HLocalGet extends HFieldGet { 1430 class HLocalGet extends HFieldGet {
1431 HLocalGet(Element element, HLocalValue local) 1431 HLocalGet(Element element, HLocalValue local)
1432 : super.withElement(element, local); 1432 : super.withElement(element, local);
1433 1433
1434 accept(HVisitor visitor) => visitor.visitLocalGet(this); 1434 accept(HVisitor visitor) => visitor.visitLocalGet(this);
1435 1435
1436 HLocalValue get local() => inputs[0]; 1436 HLocalValue get local => inputs[0];
1437 1437
1438 void prepareGvn(HTypeMap types) { 1438 void prepareGvn(HTypeMap types) {
1439 setUseGvn(); 1439 setUseGvn();
1440 // TODO(floitsch): if the variable is not captured then it only depends 1440 // TODO(floitsch): if the variable is not captured then it only depends
1441 // on assignments to the same variable. Otherwise we need to see if the 1441 // on assignments to the same variable. Otherwise we need to see if the
1442 // variable is mutated inside closures. 1442 // variable is mutated inside closures.
1443 setDependsOnSomething(); 1443 setDependsOnSomething();
1444 } 1444 }
1445 } 1445 }
1446 1446
1447 class HLocalSet extends HFieldSet { 1447 class HLocalSet extends HFieldSet {
1448 HLocalSet(Element element, HLocalValue local, HInstruction value) 1448 HLocalSet(Element element, HLocalValue local, HInstruction value)
1449 : super.withElement(element, local, value); 1449 : super.withElement(element, local, value);
1450 1450
1451 accept(HVisitor visitor) => visitor.visitLocalSet(this); 1451 accept(HVisitor visitor) => visitor.visitLocalSet(this);
1452 1452
1453 HLocalValue get local() => inputs[0]; 1453 HLocalValue get local => inputs[0];
1454 1454
1455 void prepareGvn(HTypeMap types) { 1455 void prepareGvn(HTypeMap types) {
1456 // TODO(floitsch): implement more fine grained side effects. 1456 // TODO(floitsch): implement more fine grained side effects.
1457 setAllSideEffects(); 1457 setAllSideEffects();
1458 } 1458 }
1459 } 1459 }
1460 1460
1461 class HForeign extends HInstruction { 1461 class HForeign extends HInstruction {
1462 final DartString code; 1462 final DartString code;
1463 final HType foreignType; 1463 final HType foreignType;
(...skipping 11 matching lines...) Expand all
1475 1475
1476 static HType computeTypeFromDeclaredType(DartString declaredType) { 1476 static HType computeTypeFromDeclaredType(DartString declaredType) {
1477 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN; 1477 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN;
1478 if (declaredType.slowToString() == 'int') return HType.INTEGER; 1478 if (declaredType.slowToString() == 'int') return HType.INTEGER;
1479 if (declaredType.slowToString() == 'double') return HType.DOUBLE; 1479 if (declaredType.slowToString() == 'double') return HType.DOUBLE;
1480 if (declaredType.slowToString() == 'num') return HType.NUMBER; 1480 if (declaredType.slowToString() == 'num') return HType.NUMBER;
1481 if (declaredType.slowToString() == 'String') return HType.STRING; 1481 if (declaredType.slowToString() == 'String') return HType.STRING;
1482 return HType.UNKNOWN; 1482 return HType.UNKNOWN;
1483 } 1483 }
1484 1484
1485 HType get guaranteedType() => foreignType; 1485 HType get guaranteedType => foreignType;
1486 1486
1487 bool isStatement(HTypeMap types) => _isStatement; 1487 bool isStatement(HTypeMap types) => _isStatement;
1488 } 1488 }
1489 1489
1490 class HForeignNew extends HForeign { 1490 class HForeignNew extends HForeign {
1491 ClassElement element; 1491 ClassElement element;
1492 HForeignNew(this.element, List<HInstruction> inputs) 1492 HForeignNew(this.element, List<HInstruction> inputs)
1493 : super(const LiteralDartString("new"), 1493 : super(const LiteralDartString("new"),
1494 const LiteralDartString("Object"), inputs); 1494 const LiteralDartString("Object"), inputs);
1495 accept(HVisitor visitor) => visitor.visitForeignNew(this); 1495 accept(HVisitor visitor) => visitor.visitForeignNew(this);
1496 } 1496 }
1497 1497
1498 class HInvokeBinary extends HInvokeStatic { 1498 class HInvokeBinary extends HInvokeStatic {
1499 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) 1499 HInvokeBinary(HStatic target, HInstruction left, HInstruction right)
1500 : super(<HInstruction>[target, left, right]); 1500 : super(<HInstruction>[target, left, right]);
1501 1501
1502 HInstruction get left() => inputs[1]; 1502 HInstruction get left => inputs[1];
1503 HInstruction get right() => inputs[2]; 1503 HInstruction get right => inputs[2];
1504 1504
1505 abstract BinaryOperation get operation(); 1505 abstract BinaryOperation get operation();
1506 abstract isBuiltin(HTypeMap types); 1506 abstract isBuiltin(HTypeMap types);
1507 } 1507 }
1508 1508
1509 class HBinaryArithmetic extends HInvokeBinary { 1509 class HBinaryArithmetic extends HInvokeBinary {
1510 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) 1510 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right)
1511 : super(target, left, right); 1511 : super(target, left, right);
1512 1512
1513 void prepareGvn(HTypeMap types) { 1513 void prepareGvn(HTypeMap types) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 1564
1565 // TODO(1603): The class should be marked as abstract. 1565 // TODO(1603): The class should be marked as abstract.
1566 abstract BinaryOperation get operation(); 1566 abstract BinaryOperation get operation();
1567 } 1567 }
1568 1568
1569 class HAdd extends HBinaryArithmetic { 1569 class HAdd extends HBinaryArithmetic {
1570 HAdd(HStatic target, HInstruction left, HInstruction right) 1570 HAdd(HStatic target, HInstruction left, HInstruction right)
1571 : super(target, left, right); 1571 : super(target, left, right);
1572 accept(HVisitor visitor) => visitor.visitAdd(this); 1572 accept(HVisitor visitor) => visitor.visitAdd(this);
1573 1573
1574 AddOperation get operation() => const AddOperation(); 1574 AddOperation get operation => const AddOperation();
1575 int typeCode() => 5; 1575 int typeCode() => 5;
1576 bool typeEquals(other) => other is HAdd; 1576 bool typeEquals(other) => other is HAdd;
1577 bool dataEquals(HInstruction other) => true; 1577 bool dataEquals(HInstruction other) => true;
1578 } 1578 }
1579 1579
1580 class HDivide extends HBinaryArithmetic { 1580 class HDivide extends HBinaryArithmetic {
1581 HDivide(HStatic target, HInstruction left, HInstruction right) 1581 HDivide(HStatic target, HInstruction left, HInstruction right)
1582 : super(target, left, right); 1582 : super(target, left, right);
1583 accept(HVisitor visitor) => visitor.visitDivide(this); 1583 accept(HVisitor visitor) => visitor.visitDivide(this);
1584 1584
1585 HType computeTypeFromInputTypes(HTypeMap types) { 1585 HType computeTypeFromInputTypes(HTypeMap types) {
1586 if (left.isNumber(types)) return HType.DOUBLE; 1586 if (left.isNumber(types)) return HType.DOUBLE;
1587 return HType.UNKNOWN; 1587 return HType.UNKNOWN;
1588 } 1588 }
1589 1589
1590 HType computeDesiredTypeForNonTargetInput(HInstruction input, 1590 HType computeDesiredTypeForNonTargetInput(HInstruction input,
1591 HTypeMap types) { 1591 HTypeMap types) {
1592 // A division can never return an integer. So don't ask for integer inputs. 1592 // A division can never return an integer. So don't ask for integer inputs.
1593 if (isInteger(types)) return HType.UNKNOWN; 1593 if (isInteger(types)) return HType.UNKNOWN;
1594 return super.computeDesiredTypeForNonTargetInput(input, types); 1594 return super.computeDesiredTypeForNonTargetInput(input, types);
1595 } 1595 }
1596 1596
1597 DivideOperation get operation() => const DivideOperation(); 1597 DivideOperation get operation => const DivideOperation();
1598 int typeCode() => 6; 1598 int typeCode() => 6;
1599 bool typeEquals(other) => other is HDivide; 1599 bool typeEquals(other) => other is HDivide;
1600 bool dataEquals(HInstruction other) => true; 1600 bool dataEquals(HInstruction other) => true;
1601 } 1601 }
1602 1602
1603 class HModulo extends HBinaryArithmetic { 1603 class HModulo extends HBinaryArithmetic {
1604 HModulo(HStatic target, HInstruction left, HInstruction right) 1604 HModulo(HStatic target, HInstruction left, HInstruction right)
1605 : super(target, left, right); 1605 : super(target, left, right);
1606 accept(HVisitor visitor) => visitor.visitModulo(this); 1606 accept(HVisitor visitor) => visitor.visitModulo(this);
1607 1607
1608 ModuloOperation get operation() => const ModuloOperation(); 1608 ModuloOperation get operation => const ModuloOperation();
1609 int typeCode() => 7; 1609 int typeCode() => 7;
1610 bool typeEquals(other) => other is HModulo; 1610 bool typeEquals(other) => other is HModulo;
1611 bool dataEquals(HInstruction other) => true; 1611 bool dataEquals(HInstruction other) => true;
1612 } 1612 }
1613 1613
1614 class HMultiply extends HBinaryArithmetic { 1614 class HMultiply extends HBinaryArithmetic {
1615 HMultiply(HStatic target, HInstruction left, HInstruction right) 1615 HMultiply(HStatic target, HInstruction left, HInstruction right)
1616 : super(target, left, right); 1616 : super(target, left, right);
1617 accept(HVisitor visitor) => visitor.visitMultiply(this); 1617 accept(HVisitor visitor) => visitor.visitMultiply(this);
1618 1618
1619 MultiplyOperation get operation() => const MultiplyOperation(); 1619 MultiplyOperation get operation => const MultiplyOperation();
1620 int typeCode() => 8; 1620 int typeCode() => 8;
1621 bool typeEquals(other) => other is HMultiply; 1621 bool typeEquals(other) => other is HMultiply;
1622 bool dataEquals(HInstruction other) => true; 1622 bool dataEquals(HInstruction other) => true;
1623 } 1623 }
1624 1624
1625 class HSubtract extends HBinaryArithmetic { 1625 class HSubtract extends HBinaryArithmetic {
1626 HSubtract(HStatic target, HInstruction left, HInstruction right) 1626 HSubtract(HStatic target, HInstruction left, HInstruction right)
1627 : super(target, left, right); 1627 : super(target, left, right);
1628 accept(HVisitor visitor) => visitor.visitSubtract(this); 1628 accept(HVisitor visitor) => visitor.visitSubtract(this);
1629 1629
1630 SubtractOperation get operation() => const SubtractOperation(); 1630 SubtractOperation get operation => const SubtractOperation();
1631 int typeCode() => 9; 1631 int typeCode() => 9;
1632 bool typeEquals(other) => other is HSubtract; 1632 bool typeEquals(other) => other is HSubtract;
1633 bool dataEquals(HInstruction other) => true; 1633 bool dataEquals(HInstruction other) => true;
1634 } 1634 }
1635 1635
1636 /** 1636 /**
1637 * An [HSwitch] instruction has one input for the incoming 1637 * An [HSwitch] instruction has one input for the incoming
1638 * value, and one input per constant that it can switch on. 1638 * value, and one input per constant that it can switch on.
1639 * Its block has one successor per constant, and one for the default. 1639 * Its block has one successor per constant, and one for the default.
1640 */ 1640 */
1641 class HSwitch extends HControlFlow { 1641 class HSwitch extends HControlFlow {
1642 HSwitch(List<HInstruction> inputs) : super(inputs); 1642 HSwitch(List<HInstruction> inputs) : super(inputs);
1643 1643
1644 HConstant constant(int index) => inputs[index + 1]; 1644 HConstant constant(int index) => inputs[index + 1];
1645 HInstruction get expression() => inputs[0]; 1645 HInstruction get expression => inputs[0];
1646 1646
1647 /** 1647 /**
1648 * Provides the target to jump to if none of the constants match 1648 * Provides the target to jump to if none of the constants match
1649 * the expression. If the switch had no default case, this is the 1649 * the expression. If the switch had no default case, this is the
1650 * following join-block. 1650 * following join-block.
1651 */ 1651 */
1652 HBasicBlock get defaultTarget() => block.successors.last(); 1652 HBasicBlock get defaultTarget => block.successors.last();
1653 1653
1654 accept(HVisitor visitor) => visitor.visitSwitch(this); 1654 accept(HVisitor visitor) => visitor.visitSwitch(this);
1655 1655
1656 String toString() => "HSwitch cases = $inputs"; 1656 String toString() => "HSwitch cases = $inputs";
1657 } 1657 }
1658 1658
1659 class HTruncatingDivide extends HBinaryArithmetic { 1659 class HTruncatingDivide extends HBinaryArithmetic {
1660 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) 1660 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right)
1661 : super(target, left, right); 1661 : super(target, left, right);
1662 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); 1662 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this);
1663 1663
1664 TruncatingDivideOperation get operation() 1664 TruncatingDivideOperation get operation
1665 => const TruncatingDivideOperation(); 1665 => const TruncatingDivideOperation();
1666 int typeCode() => 10; 1666 int typeCode() => 10;
1667 bool typeEquals(other) => other is HTruncatingDivide; 1667 bool typeEquals(other) => other is HTruncatingDivide;
1668 bool dataEquals(HInstruction other) => true; 1668 bool dataEquals(HInstruction other) => true;
1669 } 1669 }
1670 1670
1671 1671
1672 // TODO(floitsch): Should HBinaryArithmetic really be the super class of 1672 // TODO(floitsch): Should HBinaryArithmetic really be the super class of
1673 // HBinaryBitOp? 1673 // HBinaryBitOp?
1674 class HBinaryBitOp extends HBinaryArithmetic { 1674 class HBinaryBitOp extends HBinaryArithmetic {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 // Shift left cannot be mapped to the native operator unless the 1711 // Shift left cannot be mapped to the native operator unless the
1712 // shift count is guaranteed to be an integer in the [0,31] range. 1712 // shift count is guaranteed to be an integer in the [0,31] range.
1713 bool isBuiltin(HTypeMap types) { 1713 bool isBuiltin(HTypeMap types) {
1714 if (!left.isNumber(types) || !right.isConstantInteger()) return false; 1714 if (!left.isNumber(types) || !right.isConstantInteger()) return false;
1715 HConstant rightConstant = right; 1715 HConstant rightConstant = right;
1716 IntConstant intConstant = rightConstant.constant; 1716 IntConstant intConstant = rightConstant.constant;
1717 int count = intConstant.value; 1717 int count = intConstant.value;
1718 return count >= 0 && count <= 31; 1718 return count >= 0 && count <= 31;
1719 } 1719 }
1720 1720
1721 ShiftLeftOperation get operation() => const ShiftLeftOperation(); 1721 ShiftLeftOperation get operation => const ShiftLeftOperation();
1722 int typeCode() => 11; 1722 int typeCode() => 11;
1723 bool typeEquals(other) => other is HShiftLeft; 1723 bool typeEquals(other) => other is HShiftLeft;
1724 bool dataEquals(HInstruction other) => true; 1724 bool dataEquals(HInstruction other) => true;
1725 } 1725 }
1726 1726
1727 class HShiftRight extends HBinaryBitOp { 1727 class HShiftRight extends HBinaryBitOp {
1728 HShiftRight(HStatic target, HInstruction left, HInstruction right) 1728 HShiftRight(HStatic target, HInstruction left, HInstruction right)
1729 : super(target, left, right); 1729 : super(target, left, right);
1730 accept(HVisitor visitor) => visitor.visitShiftRight(this); 1730 accept(HVisitor visitor) => visitor.visitShiftRight(this);
1731 1731
1732 // Shift right cannot be mapped to the native operator easily. 1732 // Shift right cannot be mapped to the native operator easily.
1733 bool isBuiltin(HTypeMap types) => false; 1733 bool isBuiltin(HTypeMap types) => false;
1734 1734
1735 ShiftRightOperation get operation() => const ShiftRightOperation(); 1735 ShiftRightOperation get operation => const ShiftRightOperation();
1736 int typeCode() => 12; 1736 int typeCode() => 12;
1737 bool typeEquals(other) => other is HShiftRight; 1737 bool typeEquals(other) => other is HShiftRight;
1738 bool dataEquals(HInstruction other) => true; 1738 bool dataEquals(HInstruction other) => true;
1739 } 1739 }
1740 1740
1741 class HBitOr extends HBinaryBitOp { 1741 class HBitOr extends HBinaryBitOp {
1742 HBitOr(HStatic target, HInstruction left, HInstruction right) 1742 HBitOr(HStatic target, HInstruction left, HInstruction right)
1743 : super(target, left, right); 1743 : super(target, left, right);
1744 accept(HVisitor visitor) => visitor.visitBitOr(this); 1744 accept(HVisitor visitor) => visitor.visitBitOr(this);
1745 1745
1746 BitOrOperation get operation() => const BitOrOperation(); 1746 BitOrOperation get operation => const BitOrOperation();
1747 int typeCode() => 13; 1747 int typeCode() => 13;
1748 bool typeEquals(other) => other is HBitOr; 1748 bool typeEquals(other) => other is HBitOr;
1749 bool dataEquals(HInstruction other) => true; 1749 bool dataEquals(HInstruction other) => true;
1750 } 1750 }
1751 1751
1752 class HBitAnd extends HBinaryBitOp { 1752 class HBitAnd extends HBinaryBitOp {
1753 HBitAnd(HStatic target, HInstruction left, HInstruction right) 1753 HBitAnd(HStatic target, HInstruction left, HInstruction right)
1754 : super(target, left, right); 1754 : super(target, left, right);
1755 accept(HVisitor visitor) => visitor.visitBitAnd(this); 1755 accept(HVisitor visitor) => visitor.visitBitAnd(this);
1756 1756
1757 BitAndOperation get operation() => const BitAndOperation(); 1757 BitAndOperation get operation => const BitAndOperation();
1758 int typeCode() => 14; 1758 int typeCode() => 14;
1759 bool typeEquals(other) => other is HBitAnd; 1759 bool typeEquals(other) => other is HBitAnd;
1760 bool dataEquals(HInstruction other) => true; 1760 bool dataEquals(HInstruction other) => true;
1761 } 1761 }
1762 1762
1763 class HBitXor extends HBinaryBitOp { 1763 class HBitXor extends HBinaryBitOp {
1764 HBitXor(HStatic target, HInstruction left, HInstruction right) 1764 HBitXor(HStatic target, HInstruction left, HInstruction right)
1765 : super(target, left, right); 1765 : super(target, left, right);
1766 accept(HVisitor visitor) => visitor.visitBitXor(this); 1766 accept(HVisitor visitor) => visitor.visitBitXor(this);
1767 1767
1768 BitXorOperation get operation() => const BitXorOperation(); 1768 BitXorOperation get operation => const BitXorOperation();
1769 int typeCode() => 15; 1769 int typeCode() => 15;
1770 bool typeEquals(other) => other is HBitXor; 1770 bool typeEquals(other) => other is HBitXor;
1771 bool dataEquals(HInstruction other) => true; 1771 bool dataEquals(HInstruction other) => true;
1772 } 1772 }
1773 1773
1774 class HInvokeUnary extends HInvokeStatic { 1774 class HInvokeUnary extends HInvokeStatic {
1775 HInvokeUnary(HStatic target, HInstruction input) 1775 HInvokeUnary(HStatic target, HInstruction input)
1776 : super(<HInstruction>[target, input]); 1776 : super(<HInstruction>[target, input]);
1777 1777
1778 HInstruction get operand() => inputs[1]; 1778 HInstruction get operand => inputs[1];
1779 1779
1780 void prepareGvn(HTypeMap types) { 1780 void prepareGvn(HTypeMap types) {
1781 // A unary arithmetic expression can take part in global value 1781 // A unary arithmetic expression can take part in global value
1782 // numbering and does not have any side-effects if its input is a 1782 // numbering and does not have any side-effects if its input is a
1783 // number. 1783 // number.
1784 if (isBuiltin(types)) { 1784 if (isBuiltin(types)) {
1785 clearAllSideEffects(); 1785 clearAllSideEffects();
1786 setUseGvn(); 1786 setUseGvn();
1787 } else { 1787 } else {
1788 setAllSideEffects(); 1788 setAllSideEffects();
(...skipping 21 matching lines...) Expand all
1810 1810
1811 HType computeLikelyType(HTypeMap types) => HType.NUMBER; 1811 HType computeLikelyType(HTypeMap types) => HType.NUMBER;
1812 1812
1813 abstract UnaryOperation get operation(); 1813 abstract UnaryOperation get operation();
1814 } 1814 }
1815 1815
1816 class HNegate extends HInvokeUnary { 1816 class HNegate extends HInvokeUnary {
1817 HNegate(HStatic target, HInstruction input) : super(target, input); 1817 HNegate(HStatic target, HInstruction input) : super(target, input);
1818 accept(HVisitor visitor) => visitor.visitNegate(this); 1818 accept(HVisitor visitor) => visitor.visitNegate(this);
1819 1819
1820 NegateOperation get operation() => const NegateOperation(); 1820 NegateOperation get operation => const NegateOperation();
1821 int typeCode() => 16; 1821 int typeCode() => 16;
1822 bool typeEquals(other) => other is HNegate; 1822 bool typeEquals(other) => other is HNegate;
1823 bool dataEquals(HInstruction other) => true; 1823 bool dataEquals(HInstruction other) => true;
1824 } 1824 }
1825 1825
1826 class HBitNot extends HInvokeUnary { 1826 class HBitNot extends HInvokeUnary {
1827 HBitNot(HStatic target, HInstruction input) : super(target, input); 1827 HBitNot(HStatic target, HInstruction input) : super(target, input);
1828 accept(HVisitor visitor) => visitor.visitBitNot(this); 1828 accept(HVisitor visitor) => visitor.visitBitNot(this);
1829 1829
1830 HType computeTypeFromInputTypes(HTypeMap types) { 1830 HType computeTypeFromInputTypes(HTypeMap types) {
1831 // All bitwise operations on primitive types either produce an 1831 // All bitwise operations on primitive types either produce an
1832 // integer or throw an error. 1832 // integer or throw an error.
1833 if (operand.isPrimitive(types)) return HType.INTEGER; 1833 if (operand.isPrimitive(types)) return HType.INTEGER;
1834 return HType.UNKNOWN; 1834 return HType.UNKNOWN;
1835 } 1835 }
1836 1836
1837 HType computeDesiredTypeForNonTargetInput(HInstruction input, 1837 HType computeDesiredTypeForNonTargetInput(HInstruction input,
1838 HTypeMap types) { 1838 HTypeMap types) {
1839 HType propagatedType = types[this]; 1839 HType propagatedType = types[this];
1840 // Bit operations only work on integers. If there is no desired output 1840 // Bit operations only work on integers. If there is no desired output
1841 // type or if it as a number we want to get an integer as input. 1841 // type or if it as a number we want to get an integer as input.
1842 if (propagatedType.isUnknown() || propagatedType.isNumber()) { 1842 if (propagatedType.isUnknown() || propagatedType.isNumber()) {
1843 return HType.INTEGER; 1843 return HType.INTEGER;
1844 } 1844 }
1845 return HType.UNKNOWN; 1845 return HType.UNKNOWN;
1846 } 1846 }
1847 1847
1848 BitNotOperation get operation() => const BitNotOperation(); 1848 BitNotOperation get operation => const BitNotOperation();
1849 int typeCode() => 17; 1849 int typeCode() => 17;
1850 bool typeEquals(other) => other is HBitNot; 1850 bool typeEquals(other) => other is HBitNot;
1851 bool dataEquals(HInstruction other) => true; 1851 bool dataEquals(HInstruction other) => true;
1852 } 1852 }
1853 1853
1854 class HExit extends HControlFlow { 1854 class HExit extends HControlFlow {
1855 HExit() : super(const <HInstruction>[]); 1855 HExit() : super(const <HInstruction>[]);
1856 toString() => 'exit'; 1856 toString() => 'exit';
1857 accept(HVisitor visitor) => visitor.visitExit(this); 1857 accept(HVisitor visitor) => visitor.visitExit(this);
1858 } 1858 }
(...skipping 26 matching lines...) Expand all
1885 accept(HVisitor visitor) => visitor.visitContinue(this); 1885 accept(HVisitor visitor) => visitor.visitContinue(this);
1886 } 1886 }
1887 1887
1888 class HTry extends HControlFlow { 1888 class HTry extends HControlFlow {
1889 HParameterValue exception; 1889 HParameterValue exception;
1890 HBasicBlock catchBlock; 1890 HBasicBlock catchBlock;
1891 HBasicBlock finallyBlock; 1891 HBasicBlock finallyBlock;
1892 HTry() : super(const <HInstruction>[]); 1892 HTry() : super(const <HInstruction>[]);
1893 toString() => 'try'; 1893 toString() => 'try';
1894 accept(HVisitor visitor) => visitor.visitTry(this); 1894 accept(HVisitor visitor) => visitor.visitTry(this);
1895 HBasicBlock get joinBlock() => this.block.successors.last(); 1895 HBasicBlock get joinBlock => this.block.successors.last();
1896 } 1896 }
1897 1897
1898 class HIf extends HConditionalBranch { 1898 class HIf extends HConditionalBranch {
1899 HBlockFlow blockInformation = null; 1899 HBlockFlow blockInformation = null;
1900 HIf(HInstruction condition) : super(<HInstruction>[condition]); 1900 HIf(HInstruction condition) : super(<HInstruction>[condition]);
1901 toString() => 'if'; 1901 toString() => 'if';
1902 accept(HVisitor visitor) => visitor.visitIf(this); 1902 accept(HVisitor visitor) => visitor.visitIf(this);
1903 1903
1904 HBasicBlock get thenBlock() { 1904 HBasicBlock get thenBlock {
1905 assert(block.dominatedBlocks[0] === block.successors[0]); 1905 assert(block.dominatedBlocks[0] === block.successors[0]);
1906 return block.successors[0]; 1906 return block.successors[0];
1907 } 1907 }
1908 1908
1909 HBasicBlock get elseBlock() { 1909 HBasicBlock get elseBlock {
1910 assert(block.dominatedBlocks[1] === block.successors[1]); 1910 assert(block.dominatedBlocks[1] === block.successors[1]);
1911 return block.successors[1]; 1911 return block.successors[1];
1912 } 1912 }
1913 1913
1914 HBasicBlock get joinBlock() => blockInformation.continuation; 1914 HBasicBlock get joinBlock => blockInformation.continuation;
1915 } 1915 }
1916 1916
1917 class HLoopBranch extends HConditionalBranch { 1917 class HLoopBranch extends HConditionalBranch {
1918 static final int CONDITION_FIRST_LOOP = 0; 1918 static final int CONDITION_FIRST_LOOP = 0;
1919 static final int DO_WHILE_LOOP = 1; 1919 static final int DO_WHILE_LOOP = 1;
1920 1920
1921 final int kind; 1921 final int kind;
1922 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP]) 1922 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP])
1923 : super(<HInstruction>[condition]); 1923 : super(<HInstruction>[condition]);
1924 toString() => 'loop-branch'; 1924 toString() => 'loop-branch';
(...skipping 10 matching lines...) Expand all
1935 HConstant.internal(this.constant, HType this.constantType) 1935 HConstant.internal(this.constant, HType this.constantType)
1936 : super(<HInstruction>[]); 1936 : super(<HInstruction>[]);
1937 1937
1938 void prepareGvn(HTypeMap types) { 1938 void prepareGvn(HTypeMap types) {
1939 assert(!hasSideEffects(types)); 1939 assert(!hasSideEffects(types));
1940 } 1940 }
1941 1941
1942 toString() => 'literal: $constant'; 1942 toString() => 'literal: $constant';
1943 accept(HVisitor visitor) => visitor.visitConstant(this); 1943 accept(HVisitor visitor) => visitor.visitConstant(this);
1944 1944
1945 HType get guaranteedType() => constantType; 1945 HType get guaranteedType => constantType;
1946 1946
1947 bool isConstant() => true; 1947 bool isConstant() => true;
1948 bool isConstantBoolean() => constant.isBool(); 1948 bool isConstantBoolean() => constant.isBool();
1949 bool isConstantNull() => constant.isNull(); 1949 bool isConstantNull() => constant.isNull();
1950 bool isConstantNumber() => constant.isNum(); 1950 bool isConstantNumber() => constant.isNum();
1951 bool isConstantInteger() => constant.isInt(); 1951 bool isConstantInteger() => constant.isInt();
1952 bool isConstantString() => constant.isString(); 1952 bool isConstantString() => constant.isString();
1953 bool isConstantList() => constant.isList(); 1953 bool isConstantList() => constant.isList();
1954 bool isConstantMap() => constant.isMap(); 1954 bool isConstantMap() => constant.isMap();
1955 bool isConstantFalse() => constant.isFalse(); 1955 bool isConstantFalse() => constant.isFalse();
1956 bool isConstantTrue() => constant.isTrue(); 1956 bool isConstantTrue() => constant.isTrue();
1957 1957
1958 // Maybe avoid this if the literal is big? 1958 // Maybe avoid this if the literal is big?
1959 bool isCodeMotionInvariant() => true; 1959 bool isCodeMotionInvariant() => true;
1960 } 1960 }
1961 1961
1962 class HNot extends HInstruction { 1962 class HNot extends HInstruction {
1963 HNot(HInstruction value) : super(<HInstruction>[value]); 1963 HNot(HInstruction value) : super(<HInstruction>[value]);
1964 void prepareGvn(HTypeMap types) { 1964 void prepareGvn(HTypeMap types) {
1965 assert(!hasSideEffects(types)); 1965 assert(!hasSideEffects(types));
1966 setUseGvn(); 1966 setUseGvn();
1967 } 1967 }
1968 1968
1969 HType get guaranteedType() => HType.BOOLEAN; 1969 HType get guaranteedType => HType.BOOLEAN;
1970 1970
1971 // 'Not' only works on booleans. That's what we want as input. 1971 // 'Not' only works on booleans. That's what we want as input.
1972 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) { 1972 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) {
1973 return HType.BOOLEAN; 1973 return HType.BOOLEAN;
1974 } 1974 }
1975 1975
1976 accept(HVisitor visitor) => visitor.visitNot(this); 1976 accept(HVisitor visitor) => visitor.visitNot(this);
1977 int typeCode() => 18; 1977 int typeCode() => 18;
1978 bool typeEquals(other) => other is HNot; 1978 bool typeEquals(other) => other is HNot;
1979 bool dataEquals(HInstruction other) => true; 1979 bool dataEquals(HInstruction other) => true;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 } else { 2113 } else {
2114 setAllSideEffects(); 2114 setAllSideEffects();
2115 } 2115 }
2116 } 2116 }
2117 2117
2118 HType computeTypeFromInputTypes(HTypeMap types) { 2118 HType computeTypeFromInputTypes(HTypeMap types) {
2119 if (left.isNumber(types) || usesBoolifiedInterceptor) return HType.BOOLEAN; 2119 if (left.isNumber(types) || usesBoolifiedInterceptor) return HType.BOOLEAN;
2120 return HType.UNKNOWN; 2120 return HType.UNKNOWN;
2121 } 2121 }
2122 2122
2123 HType get guaranteedType() { 2123 HType get guaranteedType {
2124 if (usesBoolifiedInterceptor) return HType.BOOLEAN; 2124 if (usesBoolifiedInterceptor) return HType.BOOLEAN;
2125 return HType.UNKNOWN; 2125 return HType.UNKNOWN;
2126 } 2126 }
2127 2127
2128 HType computeDesiredTypeForNonTargetInput(HInstruction input, 2128 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2129 HTypeMap types) { 2129 HTypeMap types) {
2130 HType propagatedType = types[this]; 2130 HType propagatedType = types[this];
2131 // For all relational operations exept HEquals, we expect to get numbers 2131 // For all relational operations exept HEquals, we expect to get numbers
2132 // only. With numbers the outgoing type is a boolean. If something else 2132 // only. With numbers the outgoing type is a boolean. If something else
2133 // is desired, then numbers are incorrect, though. 2133 // is desired, then numbers are incorrect, though.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 if (input == left && left.isIndexablePrimitive(types)) { 2186 if (input == left && left.isIndexablePrimitive(types)) {
2187 return HType.READABLE_ARRAY; 2187 return HType.READABLE_ARRAY;
2188 } 2188 }
2189 // String equality testing is much more common than array equality testing. 2189 // String equality testing is much more common than array equality testing.
2190 if (input == right && right.isIndexablePrimitive(types)) { 2190 if (input == right && right.isIndexablePrimitive(types)) {
2191 return HType.STRING; 2191 return HType.STRING;
2192 } 2192 }
2193 return HType.UNKNOWN; 2193 return HType.UNKNOWN;
2194 } 2194 }
2195 2195
2196 EqualsOperation get operation() => const EqualsOperation(); 2196 EqualsOperation get operation => const EqualsOperation();
2197 int typeCode() => 19; 2197 int typeCode() => 19;
2198 bool typeEquals(other) => other is HEquals; 2198 bool typeEquals(other) => other is HEquals;
2199 bool dataEquals(HInstruction other) => true; 2199 bool dataEquals(HInstruction other) => true;
2200 } 2200 }
2201 2201
2202 class HIdentity extends HRelational { 2202 class HIdentity extends HRelational {
2203 HIdentity(HStatic target, HInstruction left, HInstruction right) 2203 HIdentity(HStatic target, HInstruction left, HInstruction right)
2204 : super(target, left, right); 2204 : super(target, left, right);
2205 accept(HVisitor visitor) => visitor.visitIdentity(this); 2205 accept(HVisitor visitor) => visitor.visitIdentity(this);
2206 2206
2207 bool isBuiltin(HTypeMap types) => true; 2207 bool isBuiltin(HTypeMap types) => true;
2208 2208
2209 HType get guaranteedType() => HType.BOOLEAN; 2209 HType get guaranteedType => HType.BOOLEAN;
2210 HType computeTypeFromInputTypes(HTypeMap types) 2210 HType computeTypeFromInputTypes(HTypeMap types)
2211 => HType.BOOLEAN; 2211 => HType.BOOLEAN;
2212 // Note that the identity operator really does not care for its input types. 2212 // Note that the identity operator really does not care for its input types.
2213 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types) 2213 HType computeDesiredTypeForInput(HInstruction input, HTypeMap types)
2214 => HType.UNKNOWN; 2214 => HType.UNKNOWN;
2215 2215
2216 IdentityOperation get operation() => const IdentityOperation(); 2216 IdentityOperation get operation => const IdentityOperation();
2217 int typeCode() => 20; 2217 int typeCode() => 20;
2218 bool typeEquals(other) => other is HIdentity; 2218 bool typeEquals(other) => other is HIdentity;
2219 bool dataEquals(HInstruction other) => true; 2219 bool dataEquals(HInstruction other) => true;
2220 } 2220 }
2221 2221
2222 class HGreater extends HRelational { 2222 class HGreater extends HRelational {
2223 HGreater(HStatic target, HInstruction left, HInstruction right) 2223 HGreater(HStatic target, HInstruction left, HInstruction right)
2224 : super(target, left, right); 2224 : super(target, left, right);
2225 accept(HVisitor visitor) => visitor.visitGreater(this); 2225 accept(HVisitor visitor) => visitor.visitGreater(this);
2226 2226
2227 GreaterOperation get operation() => const GreaterOperation(); 2227 GreaterOperation get operation => const GreaterOperation();
2228 int typeCode() => 21; 2228 int typeCode() => 21;
2229 bool typeEquals(other) => other is HGreater; 2229 bool typeEquals(other) => other is HGreater;
2230 bool dataEquals(HInstruction other) => true; 2230 bool dataEquals(HInstruction other) => true;
2231 } 2231 }
2232 2232
2233 class HGreaterEqual extends HRelational { 2233 class HGreaterEqual extends HRelational {
2234 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) 2234 HGreaterEqual(HStatic target, HInstruction left, HInstruction right)
2235 : super(target, left, right); 2235 : super(target, left, right);
2236 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); 2236 accept(HVisitor visitor) => visitor.visitGreaterEqual(this);
2237 2237
2238 GreaterEqualOperation get operation() => const GreaterEqualOperation(); 2238 GreaterEqualOperation get operation => const GreaterEqualOperation();
2239 int typeCode() => 22; 2239 int typeCode() => 22;
2240 bool typeEquals(other) => other is HGreaterEqual; 2240 bool typeEquals(other) => other is HGreaterEqual;
2241 bool dataEquals(HInstruction other) => true; 2241 bool dataEquals(HInstruction other) => true;
2242 } 2242 }
2243 2243
2244 class HLess extends HRelational { 2244 class HLess extends HRelational {
2245 HLess(HStatic target, HInstruction left, HInstruction right) 2245 HLess(HStatic target, HInstruction left, HInstruction right)
2246 : super(target, left, right); 2246 : super(target, left, right);
2247 accept(HVisitor visitor) => visitor.visitLess(this); 2247 accept(HVisitor visitor) => visitor.visitLess(this);
2248 2248
2249 LessOperation get operation() => const LessOperation(); 2249 LessOperation get operation => const LessOperation();
2250 int typeCode() => 23; 2250 int typeCode() => 23;
2251 bool typeEquals(other) => other is HLess; 2251 bool typeEquals(other) => other is HLess;
2252 bool dataEquals(HInstruction other) => true; 2252 bool dataEquals(HInstruction other) => true;
2253 } 2253 }
2254 2254
2255 class HLessEqual extends HRelational { 2255 class HLessEqual extends HRelational {
2256 HLessEqual(HStatic target, HInstruction left, HInstruction right) 2256 HLessEqual(HStatic target, HInstruction left, HInstruction right)
2257 : super(target, left, right); 2257 : super(target, left, right);
2258 accept(HVisitor visitor) => visitor.visitLessEqual(this); 2258 accept(HVisitor visitor) => visitor.visitLessEqual(this);
2259 2259
2260 LessEqualOperation get operation() => const LessEqualOperation(); 2260 LessEqualOperation get operation => const LessEqualOperation();
2261 int typeCode() => 24; 2261 int typeCode() => 24;
2262 bool typeEquals(other) => other is HLessEqual; 2262 bool typeEquals(other) => other is HLessEqual;
2263 bool dataEquals(HInstruction other) => true; 2263 bool dataEquals(HInstruction other) => true;
2264 } 2264 }
2265 2265
2266 class HReturn extends HControlFlow { 2266 class HReturn extends HControlFlow {
2267 HReturn(value) : super(<HInstruction>[value]); 2267 HReturn(value) : super(<HInstruction>[value]);
2268 toString() => 'return'; 2268 toString() => 'return';
2269 accept(HVisitor visitor) => visitor.visitReturn(this); 2269 accept(HVisitor visitor) => visitor.visitReturn(this);
2270 } 2270 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2306 bool typeEquals(other) => other is HStaticStore; 2306 bool typeEquals(other) => other is HStaticStore;
2307 bool dataEquals(HStaticStore other) => element == other.element; 2307 bool dataEquals(HStaticStore other) => element == other.element;
2308 bool isStatement(HTypeMap types) => true; 2308 bool isStatement(HTypeMap types) => true;
2309 } 2309 }
2310 2310
2311 class HLiteralList extends HInstruction { 2311 class HLiteralList extends HInstruction {
2312 HLiteralList(inputs) : super(inputs); 2312 HLiteralList(inputs) : super(inputs);
2313 toString() => 'literal list'; 2313 toString() => 'literal list';
2314 accept(HVisitor visitor) => visitor.visitLiteralList(this); 2314 accept(HVisitor visitor) => visitor.visitLiteralList(this);
2315 2315
2316 HType get guaranteedType() => HType.MUTABLE_ARRAY; 2316 HType get guaranteedType => HType.MUTABLE_ARRAY;
2317 2317
2318 void prepareGvn(HTypeMap types) { 2318 void prepareGvn(HTypeMap types) {
2319 assert(!hasSideEffects(types)); 2319 assert(!hasSideEffects(types));
2320 } 2320 }
2321 } 2321 }
2322 2322
2323 class HIndex extends HInvokeStatic { 2323 class HIndex extends HInvokeStatic {
2324 HIndex(HStatic target, HInstruction receiver, HInstruction index) 2324 HIndex(HStatic target, HInstruction receiver, HInstruction index)
2325 : super(<HInstruction>[target, receiver, index]); 2325 : super(<HInstruction>[target, receiver, index]);
2326 toString() => 'index operator'; 2326 toString() => 'index operator';
2327 accept(HVisitor visitor) => visitor.visitIndex(this); 2327 accept(HVisitor visitor) => visitor.visitIndex(this);
2328 2328
2329 void prepareGvn(HTypeMap types) { 2329 void prepareGvn(HTypeMap types) {
2330 if (isBuiltin(types)) { 2330 if (isBuiltin(types)) {
2331 clearAllSideEffects(); 2331 clearAllSideEffects();
2332 } else { 2332 } else {
2333 setAllSideEffects(); 2333 setAllSideEffects();
2334 } 2334 }
2335 } 2335 }
2336 2336
2337 HInstruction get receiver() => inputs[1]; 2337 HInstruction get receiver => inputs[1];
2338 HInstruction get index() => inputs[2]; 2338 HInstruction get index => inputs[2];
2339 2339
2340 HType computeDesiredTypeForNonTargetInput(HInstruction input, 2340 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2341 HTypeMap types) { 2341 HTypeMap types) {
2342 if (input == receiver && 2342 if (input == receiver &&
2343 (index.isTypeUnknown(types) || index.isNumber(types))) { 2343 (index.isTypeUnknown(types) || index.isNumber(types))) {
2344 return HType.INDEXABLE_PRIMITIVE; 2344 return HType.INDEXABLE_PRIMITIVE;
2345 } 2345 }
2346 // The index should be an int when the receiver is a string or array. 2346 // The index should be an int when the receiver is a string or array.
2347 // However it turns out that inserting an integer check in the optimized 2347 // However it turns out that inserting an integer check in the optimized
2348 // version is cheaper than having another bailout case. This is true, 2348 // version is cheaper than having another bailout case. This is true,
2349 // because the integer check will simply throw if it fails. 2349 // because the integer check will simply throw if it fails.
2350 return HType.UNKNOWN; 2350 return HType.UNKNOWN;
2351 } 2351 }
2352 2352
2353 bool isBuiltin(HTypeMap types) 2353 bool isBuiltin(HTypeMap types)
2354 => receiver.isIndexablePrimitive(types) && index.isInteger(types); 2354 => receiver.isIndexablePrimitive(types) && index.isInteger(types);
2355 } 2355 }
2356 2356
2357 class HIndexAssign extends HInvokeStatic { 2357 class HIndexAssign extends HInvokeStatic {
2358 HIndexAssign(HStatic target, 2358 HIndexAssign(HStatic target,
2359 HInstruction receiver, 2359 HInstruction receiver,
2360 HInstruction index, 2360 HInstruction index,
2361 HInstruction value) 2361 HInstruction value)
2362 : super(<HInstruction>[target, receiver, index, value]); 2362 : super(<HInstruction>[target, receiver, index, value]);
2363 toString() => 'index assign operator'; 2363 toString() => 'index assign operator';
2364 accept(HVisitor visitor) => visitor.visitIndexAssign(this); 2364 accept(HVisitor visitor) => visitor.visitIndexAssign(this);
2365 2365
2366 HInstruction get receiver() => inputs[1]; 2366 HInstruction get receiver => inputs[1];
2367 HInstruction get index() => inputs[2]; 2367 HInstruction get index => inputs[2];
2368 HInstruction get value() => inputs[3]; 2368 HInstruction get value => inputs[3];
2369 2369
2370 // Note, that we don't have a computeTypeFromInputTypes, since [HIndexAssign] 2370 // Note, that we don't have a computeTypeFromInputTypes, since [HIndexAssign]
2371 // is never used as input. 2371 // is never used as input.
2372 2372
2373 HType computeDesiredTypeForNonTargetInput(HInstruction input, 2373 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2374 HTypeMap types) { 2374 HTypeMap types) {
2375 if (input == receiver && 2375 if (input == receiver &&
2376 (index.isTypeUnknown(types) || index.isNumber(types))) { 2376 (index.isTypeUnknown(types) || index.isNumber(types))) {
2377 return HType.MUTABLE_ARRAY; 2377 return HType.MUTABLE_ARRAY;
2378 } 2378 }
(...skipping 13 matching lines...) Expand all
2392 final Type typeExpression; 2392 final Type typeExpression;
2393 final bool nullOk; 2393 final bool nullOk;
2394 2394
2395 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression, 2395 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression,
2396 HInstruction typeInfo, [this.nullOk = false]) 2396 HInstruction typeInfo, [this.nullOk = false])
2397 : super(<HInstruction>[expression, typeInfo]); 2397 : super(<HInstruction>[expression, typeInfo]);
2398 2398
2399 HIs(this.typeExpression, HInstruction expression, [this.nullOk = false]) 2399 HIs(this.typeExpression, HInstruction expression, [this.nullOk = false])
2400 : super(<HInstruction>[expression]); 2400 : super(<HInstruction>[expression]);
2401 2401
2402 HInstruction get expression() => inputs[0]; 2402 HInstruction get expression => inputs[0];
2403 2403
2404 HInstruction get typeInfoCall() => inputs[1]; 2404 HInstruction get typeInfoCall => inputs[1];
2405 2405
2406 HType get guaranteedType() => HType.BOOLEAN; 2406 HType get guaranteedType => HType.BOOLEAN;
2407 2407
2408 accept(HVisitor visitor) => visitor.visitIs(this); 2408 accept(HVisitor visitor) => visitor.visitIs(this);
2409 2409
2410 toString() => "$expression is $typeExpression"; 2410 toString() => "$expression is $typeExpression";
2411 } 2411 }
2412 2412
2413 class HTypeConversion extends HCheck { 2413 class HTypeConversion extends HCheck {
2414 HType type; 2414 HType type;
2415 final int kind; 2415 final int kind;
2416 2416
2417 static final int NO_CHECK = 0; 2417 static final int NO_CHECK = 0;
2418 static final int CHECKED_MODE_CHECK = 1; 2418 static final int CHECKED_MODE_CHECK = 1;
2419 static final int ARGUMENT_TYPE_CHECK = 2; 2419 static final int ARGUMENT_TYPE_CHECK = 2;
2420 static final int CAST_TYPE_CHECK = 3; 2420 static final int CAST_TYPE_CHECK = 3;
2421 2421
2422 HTypeConversion(this.type, HInstruction input, [this.kind = NO_CHECK]) 2422 HTypeConversion(this.type, HInstruction input, [this.kind = NO_CHECK])
2423 : super(<HInstruction>[input]) { 2423 : super(<HInstruction>[input]) {
2424 sourceElement = input.sourceElement; 2424 sourceElement = input.sourceElement;
2425 } 2425 }
2426 HTypeConversion.checkedModeCheck(HType type, HInstruction input) 2426 HTypeConversion.checkedModeCheck(HType type, HInstruction input)
2427 : this(type, input, CHECKED_MODE_CHECK); 2427 : this(type, input, CHECKED_MODE_CHECK);
2428 HTypeConversion.argumentTypeCheck(HType type, HInstruction input) 2428 HTypeConversion.argumentTypeCheck(HType type, HInstruction input)
2429 : this(type, input, ARGUMENT_TYPE_CHECK); 2429 : this(type, input, ARGUMENT_TYPE_CHECK);
2430 HTypeConversion.castCheck(HType type, HInstruction input) 2430 HTypeConversion.castCheck(HType type, HInstruction input)
2431 : this(type, input, CAST_TYPE_CHECK); 2431 : this(type, input, CAST_TYPE_CHECK);
2432 2432
2433 2433
2434 bool get isChecked() => kind != NO_CHECK; 2434 bool get isChecked => kind != NO_CHECK;
2435 bool get isCheckedModeCheck() => kind == CHECKED_MODE_CHECK; 2435 bool get isCheckedModeCheck => kind == CHECKED_MODE_CHECK;
2436 bool get isArgumentTypeCheck() => kind == ARGUMENT_TYPE_CHECK; 2436 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK;
2437 bool get isCastTypeCheck() => kind == CAST_TYPE_CHECK; 2437 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK;
2438 2438
2439 HType get guaranteedType() => type; 2439 HType get guaranteedType => type;
2440 2440
2441 accept(HVisitor visitor) => visitor.visitTypeConversion(this); 2441 accept(HVisitor visitor) => visitor.visitTypeConversion(this);
2442 2442
2443 bool isStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK; 2443 bool isStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK;
2444 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; 2444 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK;
2445 2445
2446 int typeCode() => 28; 2446 int typeCode() => 28;
2447 bool typeEquals(HInstruction other) => other is HTypeConversion; 2447 bool typeEquals(HInstruction other) => other is HTypeConversion;
2448 bool dataEquals(HTypeConversion other) { 2448 bool dataEquals(HTypeConversion other) {
2449 return type == other.type && kind == other.kind; 2449 return type == other.type && kind == other.kind;
2450 } 2450 }
2451 } 2451 }
2452 2452
2453 class HStringConcat extends HInstruction { 2453 class HStringConcat extends HInstruction {
2454 final Node node; 2454 final Node node;
2455 HStringConcat(HInstruction left, HInstruction right, this.node) 2455 HStringConcat(HInstruction left, HInstruction right, this.node)
2456 : super(<HInstruction>[left, right]); 2456 : super(<HInstruction>[left, right]);
2457 HType get guaranteedType() => HType.STRING; 2457 HType get guaranteedType => HType.STRING;
2458 2458
2459 HInstruction get left() => inputs[0]; 2459 HInstruction get left => inputs[0];
2460 HInstruction get right() => inputs[1]; 2460 HInstruction get right => inputs[1];
2461 2461
2462 accept(HVisitor visitor) => visitor.visitStringConcat(this); 2462 accept(HVisitor visitor) => visitor.visitStringConcat(this);
2463 toString() => "string concat"; 2463 toString() => "string concat";
2464 } 2464 }
2465 2465
2466 /** Non-block-based (aka. traditional) loop information. */ 2466 /** Non-block-based (aka. traditional) loop information. */
2467 class HLoopInformation { 2467 class HLoopInformation {
2468 final HBasicBlock header; 2468 final HBasicBlock header;
2469 final List<HBasicBlock> blocks; 2469 final List<HBasicBlock> blocks;
2470 final List<HBasicBlock> backEdges; 2470 final List<HBasicBlock> backEdges;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 2581
2582 2582
2583 /** 2583 /**
2584 * Generic class wrapping a [SubGraph] as a block-information until 2584 * Generic class wrapping a [SubGraph] as a block-information until
2585 * all structures are handled properly. 2585 * all structures are handled properly.
2586 */ 2586 */
2587 class HSubGraphBlockInformation implements HStatementInformation { 2587 class HSubGraphBlockInformation implements HStatementInformation {
2588 final SubGraph subGraph; 2588 final SubGraph subGraph;
2589 HSubGraphBlockInformation(this.subGraph); 2589 HSubGraphBlockInformation(this.subGraph);
2590 2590
2591 HBasicBlock get start() => subGraph.start; 2591 HBasicBlock get start => subGraph.start;
2592 HBasicBlock get end() => subGraph.end; 2592 HBasicBlock get end => subGraph.end;
2593 2593
2594 bool accept(HStatementInformationVisitor visitor) => 2594 bool accept(HStatementInformationVisitor visitor) =>
2595 visitor.visitSubGraphInfo(this); 2595 visitor.visitSubGraphInfo(this);
2596 } 2596 }
2597 2597
2598 2598
2599 /** 2599 /**
2600 * Generic class wrapping a [SubExpression] as a block-information until 2600 * Generic class wrapping a [SubExpression] as a block-information until
2601 * expressions structures are handled properly. 2601 * expressions structures are handled properly.
2602 */ 2602 */
2603 class HSubExpressionBlockInformation implements HExpressionInformation { 2603 class HSubExpressionBlockInformation implements HExpressionInformation {
2604 final SubExpression subExpression; 2604 final SubExpression subExpression;
2605 HSubExpressionBlockInformation(this.subExpression); 2605 HSubExpressionBlockInformation(this.subExpression);
2606 2606
2607 HBasicBlock get start() => subExpression.start; 2607 HBasicBlock get start => subExpression.start;
2608 HBasicBlock get end() => subExpression.end; 2608 HBasicBlock get end => subExpression.end;
2609 2609
2610 HInstruction get conditionExpression() => subExpression.conditionExpression; 2610 HInstruction get conditionExpression => subExpression.conditionExpression;
2611 2611
2612 bool accept(HExpressionInformationVisitor visitor) => 2612 bool accept(HExpressionInformationVisitor visitor) =>
2613 visitor.visitSubExpressionInfo(this); 2613 visitor.visitSubExpressionInfo(this);
2614 } 2614 }
2615 2615
2616 2616
2617 /** A sequence of separate statements. */ 2617 /** A sequence of separate statements. */
2618 class HStatementSequenceInformation implements HStatementInformation { 2618 class HStatementSequenceInformation implements HStatementInformation {
2619 final List<HStatementInformation> statements; 2619 final List<HStatementInformation> statements;
2620 HStatementSequenceInformation(this.statements); 2620 HStatementSequenceInformation(this.statements);
2621 2621
2622 HBasicBlock get start() => statements[0].start; 2622 HBasicBlock get start => statements[0].start;
2623 HBasicBlock get end() => statements.last().end; 2623 HBasicBlock get end => statements.last().end;
2624 2624
2625 bool accept(HStatementInformationVisitor visitor) => 2625 bool accept(HStatementInformationVisitor visitor) =>
2626 visitor.visitSequenceInfo(this); 2626 visitor.visitSequenceInfo(this);
2627 } 2627 }
2628 2628
2629 2629
2630 class HLabeledBlockInformation implements HStatementInformation { 2630 class HLabeledBlockInformation implements HStatementInformation {
2631 final HStatementInformation body; 2631 final HStatementInformation body;
2632 final List<LabelElement> labels; 2632 final List<LabelElement> labels;
2633 final TargetElement target; 2633 final TargetElement target;
2634 final bool isContinue; 2634 final bool isContinue;
2635 2635
2636 HLabeledBlockInformation(this.body, 2636 HLabeledBlockInformation(this.body,
2637 List<LabelElement> labels, 2637 List<LabelElement> labels,
2638 [this.isContinue = false]) : 2638 [this.isContinue = false]) :
2639 this.labels = labels, this.target = labels[0].target; 2639 this.labels = labels, this.target = labels[0].target;
2640 2640
2641 HLabeledBlockInformation.implicit(this.body, 2641 HLabeledBlockInformation.implicit(this.body,
2642 this.target, 2642 this.target,
2643 [this.isContinue = false]) 2643 [this.isContinue = false])
2644 : this.labels = const<LabelElement>[]; 2644 : this.labels = const<LabelElement>[];
2645 2645
2646 HBasicBlock get start() => body.start; 2646 HBasicBlock get start => body.start;
2647 HBasicBlock get end() => body.end; 2647 HBasicBlock get end => body.end;
2648 2648
2649 bool accept(HStatementInformationVisitor visitor) => 2649 bool accept(HStatementInformationVisitor visitor) =>
2650 visitor.visitLabeledBlockInfo(this); 2650 visitor.visitLabeledBlockInfo(this);
2651 } 2651 }
2652 2652
2653 class LoopTypeVisitor extends AbstractVisitor { 2653 class LoopTypeVisitor extends AbstractVisitor {
2654 const LoopTypeVisitor(); 2654 const LoopTypeVisitor();
2655 int visitNode(Node node) => HLoopBlockInformation.NOT_A_LOOP; 2655 int visitNode(Node node) => HLoopBlockInformation.NOT_A_LOOP;
2656 int visitWhile(While node) => HLoopBlockInformation.WHILE_LOOP; 2656 int visitWhile(While node) => HLoopBlockInformation.WHILE_LOOP;
2657 int visitFor(For node) => HLoopBlockInformation.FOR_LOOP; 2657 int visitFor(For node) => HLoopBlockInformation.FOR_LOOP;
(...skipping 19 matching lines...) Expand all
2677 2677
2678 HLoopBlockInformation(this.kind, 2678 HLoopBlockInformation(this.kind,
2679 this.initializer, 2679 this.initializer,
2680 this.condition, 2680 this.condition,
2681 this.body, 2681 this.body,
2682 this.updates, 2682 this.updates,
2683 this.target, 2683 this.target,
2684 this.labels, 2684 this.labels,
2685 this.sourcePosition); 2685 this.sourcePosition);
2686 2686
2687 HBasicBlock get start() { 2687 HBasicBlock get start {
2688 if (initializer !== null) return initializer.start; 2688 if (initializer !== null) return initializer.start;
2689 if (kind == DO_WHILE_LOOP) { 2689 if (kind == DO_WHILE_LOOP) {
2690 return body.start; 2690 return body.start;
2691 } 2691 }
2692 return condition.start; 2692 return condition.start;
2693 } 2693 }
2694 2694
2695 HBasicBlock get loopHeader() { 2695 HBasicBlock get loopHeader {
2696 return kind == DO_WHILE_LOOP ? body.start : condition.start; 2696 return kind == DO_WHILE_LOOP ? body.start : condition.start;
2697 } 2697 }
2698 2698
2699 HBasicBlock get end() { 2699 HBasicBlock get end {
2700 if (updates !== null) return updates.end; 2700 if (updates !== null) return updates.end;
2701 if (kind == DO_WHILE_LOOP) { 2701 if (kind == DO_WHILE_LOOP) {
2702 return condition.end; 2702 return condition.end;
2703 } 2703 }
2704 return body.end; 2704 return body.end;
2705 } 2705 }
2706 2706
2707 static int loopType(Node node) { 2707 static int loopType(Node node) {
2708 return node.accept(const LoopTypeVisitor()); 2708 return node.accept(const LoopTypeVisitor());
2709 } 2709 }
2710 2710
2711 bool accept(HStatementInformationVisitor visitor) => 2711 bool accept(HStatementInformationVisitor visitor) =>
2712 visitor.visitLoopInfo(this); 2712 visitor.visitLoopInfo(this);
2713 } 2713 }
2714 2714
2715 class HIfBlockInformation implements HStatementInformation { 2715 class HIfBlockInformation implements HStatementInformation {
2716 final HExpressionInformation condition; 2716 final HExpressionInformation condition;
2717 final HStatementInformation thenGraph; 2717 final HStatementInformation thenGraph;
2718 final HStatementInformation elseGraph; 2718 final HStatementInformation elseGraph;
2719 HIfBlockInformation(this.condition, 2719 HIfBlockInformation(this.condition,
2720 this.thenGraph, 2720 this.thenGraph,
2721 this.elseGraph); 2721 this.elseGraph);
2722 2722
2723 HBasicBlock get start() => condition.start; 2723 HBasicBlock get start => condition.start;
2724 HBasicBlock get end() => elseGraph === null ? thenGraph.end : elseGraph.end; 2724 HBasicBlock get end => elseGraph === null ? thenGraph.end : elseGraph.end;
2725 2725
2726 bool accept(HStatementInformationVisitor visitor) => 2726 bool accept(HStatementInformationVisitor visitor) =>
2727 visitor.visitIfInfo(this); 2727 visitor.visitIfInfo(this);
2728 } 2728 }
2729 2729
2730 class HAndOrBlockInformation implements HExpressionInformation { 2730 class HAndOrBlockInformation implements HExpressionInformation {
2731 final bool isAnd; 2731 final bool isAnd;
2732 final HExpressionInformation left; 2732 final HExpressionInformation left;
2733 final HExpressionInformation right; 2733 final HExpressionInformation right;
2734 HAndOrBlockInformation(this.isAnd, 2734 HAndOrBlockInformation(this.isAnd,
2735 this.left, 2735 this.left,
2736 this.right); 2736 this.right);
2737 2737
2738 HBasicBlock get start() => left.start; 2738 HBasicBlock get start => left.start;
2739 HBasicBlock get end() => right.end; 2739 HBasicBlock get end => right.end;
2740 2740
2741 // We don't currently use HAndOrBlockInformation. 2741 // We don't currently use HAndOrBlockInformation.
2742 HInstruction get conditionExpression() { 2742 HInstruction get conditionExpression {
2743 return null; 2743 return null;
2744 } 2744 }
2745 bool accept(HExpressionInformationVisitor visitor) => 2745 bool accept(HExpressionInformationVisitor visitor) =>
2746 visitor.visitAndOrInfo(this); 2746 visitor.visitAndOrInfo(this);
2747 } 2747 }
2748 2748
2749 class HTryBlockInformation implements HStatementInformation { 2749 class HTryBlockInformation implements HStatementInformation {
2750 final HStatementInformation body; 2750 final HStatementInformation body;
2751 final HParameterValue catchVariable; 2751 final HParameterValue catchVariable;
2752 final HStatementInformation catchBlock; 2752 final HStatementInformation catchBlock;
2753 final HStatementInformation finallyBlock; 2753 final HStatementInformation finallyBlock;
2754 HTryBlockInformation(this.body, 2754 HTryBlockInformation(this.body,
2755 this.catchVariable, 2755 this.catchVariable,
2756 this.catchBlock, 2756 this.catchBlock,
2757 this.finallyBlock); 2757 this.finallyBlock);
2758 2758
2759 HBasicBlock get start() => body.start; 2759 HBasicBlock get start => body.start;
2760 HBasicBlock get end() => 2760 HBasicBlock get end =>
2761 finallyBlock === null ? catchBlock.end : finallyBlock.end; 2761 finallyBlock === null ? catchBlock.end : finallyBlock.end;
2762 2762
2763 bool accept(HStatementInformationVisitor visitor) => 2763 bool accept(HStatementInformationVisitor visitor) =>
2764 visitor.visitTryInfo(this); 2764 visitor.visitTryInfo(this);
2765 } 2765 }
2766 2766
2767 2767
2768 2768
2769 class HSwitchBlockInformation implements HStatementInformation { 2769 class HSwitchBlockInformation implements HStatementInformation {
2770 final HExpressionInformation expression; 2770 final HExpressionInformation expression;
2771 final List<List<Constant>> matchExpressions; 2771 final List<List<Constant>> matchExpressions;
2772 final List<HStatementInformation> statements; 2772 final List<HStatementInformation> statements;
2773 // If the switch has a default, it's the last statement block, which 2773 // If the switch has a default, it's the last statement block, which
2774 // may or may not have other expresions. 2774 // may or may not have other expresions.
2775 final bool hasDefault; 2775 final bool hasDefault;
2776 final TargetElement target; 2776 final TargetElement target;
2777 final List<LabelElement> labels; 2777 final List<LabelElement> labels;
2778 2778
2779 HSwitchBlockInformation(this.expression, 2779 HSwitchBlockInformation(this.expression,
2780 this.matchExpressions, 2780 this.matchExpressions,
2781 this.statements, 2781 this.statements,
2782 this.hasDefault, 2782 this.hasDefault,
2783 this.target, 2783 this.target,
2784 this.labels); 2784 this.labels);
2785 2785
2786 HBasicBlock get start() => expression.start; 2786 HBasicBlock get start => expression.start;
2787 HBasicBlock get end() { 2787 HBasicBlock get end {
2788 // We don't create a switch block if there are no cases. 2788 // We don't create a switch block if there are no cases.
2789 assert(!statements.isEmpty()); 2789 assert(!statements.isEmpty());
2790 return statements.last().end; 2790 return statements.last().end;
2791 } 2791 }
2792 2792
2793 bool accept(HStatementInformationVisitor visitor) => 2793 bool accept(HStatementInformationVisitor visitor) =>
2794 visitor.visitSwitchInfo(this); 2794 visitor.visitSwitchInfo(this);
2795 } 2795 }
OLDNEW
« no previous file with comments | « dart/lib/compiler/implementation/ssa/js_names.dart ('k') | dart/lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698