| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
| 8 String get name; | 8 String get name; |
| 9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
| 10 } | 10 } |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 392 |
| 393 HInstruction handleIdentityCheck(HInvokeBinary node) { | 393 HInstruction handleIdentityCheck(HInvokeBinary node) { |
| 394 HInstruction left = node.left; | 394 HInstruction left = node.left; |
| 395 HInstruction right = node.right; | 395 HInstruction right = node.right; |
| 396 HType leftType = types[left]; | 396 HType leftType = types[left]; |
| 397 HType rightType = types[right]; | 397 HType rightType = types[right]; |
| 398 assert(!leftType.isConflicting() && !rightType.isConflicting()); | 398 assert(!leftType.isConflicting() && !rightType.isConflicting()); |
| 399 | 399 |
| 400 // We don't optimize on numbers to preserve the runtime semantics. | 400 // We don't optimize on numbers to preserve the runtime semantics. |
| 401 if (!(left.isNumber(types) && right.isNumber(types)) && | 401 if (!(left.isNumber(types) && right.isNumber(types)) && |
| 402 leftType.intersection(rightType).isConflicting()) { | 402 leftType.intersection(rightType, compiler).isConflicting()) { |
| 403 return graph.addConstantBool(false, constantSystem); | 403 return graph.addConstantBool(false, constantSystem); |
| 404 } | 404 } |
| 405 | 405 |
| 406 if (left.isConstantBoolean() && right.isBoolean(types)) { | 406 if (left.isConstantBoolean() && right.isBoolean(types)) { |
| 407 HConstant constant = left; | 407 HConstant constant = left; |
| 408 if (constant.constant.isTrue()) { | 408 if (constant.constant.isTrue()) { |
| 409 return right; | 409 return right; |
| 410 } else { | 410 } else { |
| 411 return new HNot(right); | 411 return new HNot(right); |
| 412 } | 412 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 // [visitInvokeBinary], which are visited by invoking the [super]'s | 482 // [visitInvokeBinary], which are visited by invoking the [super]'s |
| 483 // visit method. | 483 // visit method. |
| 484 return super.visitEquals(node); | 484 return super.visitEquals(node); |
| 485 } | 485 } |
| 486 | 486 |
| 487 HInstruction visitTypeGuard(HTypeGuard node) { | 487 HInstruction visitTypeGuard(HTypeGuard node) { |
| 488 HInstruction value = node.guarded; | 488 HInstruction value = node.guarded; |
| 489 // If the intersection of the types is still the incoming type then | 489 // If the intersection of the types is still the incoming type then |
| 490 // the incoming type was a subtype of the guarded type, and no check | 490 // the incoming type was a subtype of the guarded type, and no check |
| 491 // is required. | 491 // is required. |
| 492 HType combinedType = types[value].intersection(node.guardedType); | 492 HType combinedType = types[value].intersection(node.guardedType, compiler); |
| 493 return (combinedType == types[value]) ? value : node; | 493 return (combinedType == types[value]) ? value : node; |
| 494 } | 494 } |
| 495 | 495 |
| 496 HInstruction visitIs(HIs node) { | 496 HInstruction visitIs(HIs node) { |
| 497 DartType type = node.typeExpression; | 497 DartType type = node.typeExpression; |
| 498 Element element = type.element; | 498 Element element = type.element; |
| 499 if (identical(element.kind, ElementKind.TYPE_VARIABLE)) { | 499 if (identical(element.kind, ElementKind.TYPE_VARIABLE)) { |
| 500 compiler.unimplemented("visitIs for type variables"); | 500 compiler.unimplemented("visitIs for type variables"); |
| 501 } | 501 } |
| 502 | 502 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 HInstruction visitTypeConversion(HTypeConversion node) { | 569 HInstruction visitTypeConversion(HTypeConversion node) { |
| 570 HInstruction value = node.inputs[0]; | 570 HInstruction value = node.inputs[0]; |
| 571 DartType type = types[node].computeType(compiler); | 571 DartType type = types[node].computeType(compiler); |
| 572 if (identical(type.element, compiler.dynamicClass) | 572 if (identical(type.element, compiler.dynamicClass) |
| 573 || identical(type.element, compiler.objectClass)) { | 573 || identical(type.element, compiler.objectClass)) { |
| 574 return value; | 574 return value; |
| 575 } | 575 } |
| 576 if (types[value].canBeNull() && node.isBooleanConversionCheck) { | 576 if (types[value].canBeNull() && node.isBooleanConversionCheck) { |
| 577 return node; | 577 return node; |
| 578 } | 578 } |
| 579 HType combinedType = types[value].intersection(types[node]); | 579 HType combinedType = types[value].intersection(types[node], compiler); |
| 580 return (combinedType == types[value]) ? value : node; | 580 return (combinedType == types[value]) ? value : node; |
| 581 } | 581 } |
| 582 | 582 |
| 583 Element findConcreteFieldForDynamicAccess(HInstruction receiver, | 583 Element findConcreteFieldForDynamicAccess(HInstruction receiver, |
| 584 Selector selector) { | 584 Selector selector) { |
| 585 HType receiverType = types[receiver]; | 585 HType receiverType = types[receiver]; |
| 586 if (!receiverType.isUseful()) return null; | 586 if (!receiverType.isUseful()) return null; |
| 587 if (receiverType.canBeNull()) return null; | 587 if (receiverType.canBeNull()) return null; |
| 588 DartType type = receiverType.computeType(compiler); | 588 DartType type = receiverType.computeType(compiler); |
| 589 if (type == null) return null; | 589 if (type == null) return null; |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 new Map.from(blockFieldSetters[block.predecessors[0]]); | 1249 new Map.from(blockFieldSetters[block.predecessors[0]]); |
| 1250 // Loop headers are the only nodes with back edges. | 1250 // Loop headers are the only nodes with back edges. |
| 1251 if (!block.isLoopHeader()) { | 1251 if (!block.isLoopHeader()) { |
| 1252 for (int i = 1; i < block.predecessors.length; i++) { | 1252 for (int i = 1; i < block.predecessors.length; i++) { |
| 1253 Map<Element, HType> predecessorsFieldSetters = | 1253 Map<Element, HType> predecessorsFieldSetters = |
| 1254 blockFieldSetters[block.predecessors[i]]; | 1254 blockFieldSetters[block.predecessors[i]]; |
| 1255 Map<Element, HType> newFieldSetters = new Map<Element, HType>(); | 1255 Map<Element, HType> newFieldSetters = new Map<Element, HType>(); |
| 1256 predecessorsFieldSetters.forEach((Element element, HType type) { | 1256 predecessorsFieldSetters.forEach((Element element, HType type) { |
| 1257 HType currentType = currentFieldSetters[element]; | 1257 HType currentType = currentFieldSetters[element]; |
| 1258 if (currentType != null) { | 1258 if (currentType != null) { |
| 1259 newFieldSetters[element] = currentType.union(type); | 1259 newFieldSetters[element] = |
| 1260 currentType.union(type, backend.compiler); |
| 1260 } | 1261 } |
| 1261 }); | 1262 }); |
| 1262 currentFieldSetters = newFieldSetters; | 1263 currentFieldSetters = newFieldSetters; |
| 1263 } | 1264 } |
| 1264 } else { | 1265 } else { |
| 1265 assert(block.predecessors.length <= 2); | 1266 assert(block.predecessors.length <= 2); |
| 1266 } | 1267 } |
| 1267 } | 1268 } |
| 1268 block.forEachPhi((HPhi phi) => phi.accept(this)); | 1269 block.forEachPhi((HPhi phi) => phi.accept(this)); |
| 1269 block.forEachInstruction( | 1270 block.forEachInstruction( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 } | 1340 } |
| 1340 | 1341 |
| 1341 // For other fields having setters in the generative constructor body, set | 1342 // For other fields having setters in the generative constructor body, set |
| 1342 // the type to UNKNOWN to avoid relying on the type set in the initializer | 1343 // the type to UNKNOWN to avoid relying on the type set in the initializer |
| 1343 // list. | 1344 // list. |
| 1344 allSetters.forEach((Element element) { | 1345 allSetters.forEach((Element element) { |
| 1345 backend.registerFieldConstructor(element, HType.UNKNOWN); | 1346 backend.registerFieldConstructor(element, HType.UNKNOWN); |
| 1346 }); | 1347 }); |
| 1347 } | 1348 } |
| 1348 } | 1349 } |
| OLD | NEW |