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 |