| 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 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 HInstruction right = node.right; | 586 HInstruction right = node.right; |
| 587 TypeMask leftType = left.instructionType; | 587 TypeMask leftType = left.instructionType; |
| 588 TypeMask rightType = right.instructionType; | 588 TypeMask rightType = right.instructionType; |
| 589 | 589 |
| 590 HInstruction makeTrue() => graph.addConstantBool(true, compiler); | 590 HInstruction makeTrue() => graph.addConstantBool(true, compiler); |
| 591 HInstruction makeFalse() => graph.addConstantBool(false, compiler); | 591 HInstruction makeFalse() => graph.addConstantBool(false, compiler); |
| 592 | 592 |
| 593 // Intersection of int and double return conflicting, so | 593 // Intersection of int and double return conflicting, so |
| 594 // we don't optimize on numbers to preserve the runtime semantics. | 594 // we don't optimize on numbers to preserve the runtime semantics. |
| 595 if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) { | 595 if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) { |
| 596 TypeMask intersection = leftType.intersection(rightType, compiler.world); | 596 if (leftType.isDisjoint(rightType, compiler.world)) { |
| 597 if (intersection.isEmpty && !intersection.isNullable) { | |
| 598 return makeFalse(); | 597 return makeFalse(); |
| 599 } | 598 } |
| 600 } | 599 } |
| 601 | 600 |
| 602 if (left.isNull() && right.isNull()) { | 601 if (left.isNull() && right.isNull()) { |
| 603 return makeTrue(); | 602 return makeTrue(); |
| 604 } | 603 } |
| 605 | 604 |
| 606 HInstruction compareConstant(HConstant constant, HInstruction input) { | 605 HInstruction compareConstant(HConstant constant, HInstruction input) { |
| 607 if (constant.constant.isTrue) { | 606 if (constant.constant.isTrue) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 // a class [:A<T>:], is currently always considered to have the | 729 // a class [:A<T>:], is currently always considered to have the |
| 731 // raw type. | 730 // raw type. |
| 732 } else if (!RuntimeTypes.hasTypeArguments(type)) { | 731 } else if (!RuntimeTypes.hasTypeArguments(type)) { |
| 733 TypeMask expressionMask = expression.instructionType; | 732 TypeMask expressionMask = expression.instructionType; |
| 734 assert(TypeMask.assertIsNormalized(expressionMask, classWorld)); | 733 assert(TypeMask.assertIsNormalized(expressionMask, classWorld)); |
| 735 TypeMask typeMask = (element == coreClasses.nullClass) | 734 TypeMask typeMask = (element == coreClasses.nullClass) |
| 736 ? new TypeMask.subtype(element, classWorld) | 735 ? new TypeMask.subtype(element, classWorld) |
| 737 : new TypeMask.nonNullSubtype(element, classWorld); | 736 : new TypeMask.nonNullSubtype(element, classWorld); |
| 738 if (expressionMask.union(typeMask, classWorld) == typeMask) { | 737 if (expressionMask.union(typeMask, classWorld) == typeMask) { |
| 739 return graph.addConstantBool(true, compiler); | 738 return graph.addConstantBool(true, compiler); |
| 740 } else if (expressionMask.intersection(typeMask, | 739 } else if (expressionMask.isDisjoint(typeMask, compiler.world)) { |
| 741 compiler.world).isEmpty) { | |
| 742 return graph.addConstantBool(false, compiler); | 740 return graph.addConstantBool(false, compiler); |
| 743 } | 741 } |
| 744 } | 742 } |
| 745 return node; | 743 return node; |
| 746 } | 744 } |
| 747 | 745 |
| 748 HInstruction visitTypeConversion(HTypeConversion node) { | 746 HInstruction visitTypeConversion(HTypeConversion node) { |
| 749 DartType type = node.typeExpression; | 747 DartType type = node.typeExpression; |
| 750 if (type != null) { | 748 if (type != null) { |
| 751 if (type.isMalformed) { | 749 if (type.isMalformed) { |
| (...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 /** | 2145 /** |
| 2148 * Returns whether [first] and [second] may alias to the same object. | 2146 * Returns whether [first] and [second] may alias to the same object. |
| 2149 */ | 2147 */ |
| 2150 bool mayAlias(HInstruction first, HInstruction second) { | 2148 bool mayAlias(HInstruction first, HInstruction second) { |
| 2151 if (mustAlias(first, second)) return true; | 2149 if (mustAlias(first, second)) return true; |
| 2152 if (isConcrete(first) && isConcrete(second)) return false; | 2150 if (isConcrete(first) && isConcrete(second)) return false; |
| 2153 if (nonEscapingReceivers.contains(first)) return false; | 2151 if (nonEscapingReceivers.contains(first)) return false; |
| 2154 if (nonEscapingReceivers.contains(second)) return false; | 2152 if (nonEscapingReceivers.contains(second)) return false; |
| 2155 // Typed arrays of different types might have a shared buffer. | 2153 // Typed arrays of different types might have a shared buffer. |
| 2156 if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true; | 2154 if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true; |
| 2157 TypeMask intersection = first.instructionType.intersection( | 2155 return !first.instructionType.isDisjoint( |
| 2158 second.instructionType, compiler.world); | 2156 second.instructionType, compiler.world); |
| 2159 if (intersection.isEmpty) return false; | |
| 2160 return true; | |
| 2161 } | 2157 } |
| 2162 | 2158 |
| 2163 bool isFinal(Element element) { | 2159 bool isFinal(Element element) { |
| 2164 return compiler.world.fieldNeverChanges(element); | 2160 return compiler.world.fieldNeverChanges(element); |
| 2165 } | 2161 } |
| 2166 | 2162 |
| 2167 bool isConcrete(HInstruction instruction) { | 2163 bool isConcrete(HInstruction instruction) { |
| 2168 return instruction is HForeignNew | 2164 return instruction is HForeignNew |
| 2169 || instruction is HConstant | 2165 || instruction is HConstant |
| 2170 || instruction is HLiteralList; | 2166 || instruction is HLiteralList; |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2402 | 2398 |
| 2403 keyedValues.forEach((receiver, values) { | 2399 keyedValues.forEach((receiver, values) { |
| 2404 result.keyedValues[receiver] = | 2400 result.keyedValues[receiver] = |
| 2405 new Map<HInstruction, HInstruction>.from(values); | 2401 new Map<HInstruction, HInstruction>.from(values); |
| 2406 }); | 2402 }); |
| 2407 | 2403 |
| 2408 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2404 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2409 return result; | 2405 return result; |
| 2410 } | 2406 } |
| 2411 } | 2407 } |
| OLD | NEW |