| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 final ConstantSystem constantSystem; | 138 final ConstantSystem constantSystem; |
| 139 HGraph graph; | 139 HGraph graph; |
| 140 Compiler get compiler => backend.compiler; | 140 Compiler get compiler => backend.compiler; |
| 141 final SsaOptimizerTask optimizer; | 141 final SsaOptimizerTask optimizer; |
| 142 | 142 |
| 143 SsaInstructionSimplifier(this.constantSystem, | 143 SsaInstructionSimplifier(this.constantSystem, |
| 144 this.backend, | 144 this.backend, |
| 145 this.optimizer, | 145 this.optimizer, |
| 146 this.work); | 146 this.work); |
| 147 | 147 |
| 148 CoreClasses get coreClasses => compiler.coreClasses; |
| 149 |
| 148 void visitGraph(HGraph visitee) { | 150 void visitGraph(HGraph visitee) { |
| 149 graph = visitee; | 151 graph = visitee; |
| 150 visitDominatorTree(visitee); | 152 visitDominatorTree(visitee); |
| 151 } | 153 } |
| 152 | 154 |
| 153 visitBasicBlock(HBasicBlock block) { | 155 visitBasicBlock(HBasicBlock block) { |
| 154 HInstruction instruction = block.first; | 156 HInstruction instruction = block.first; |
| 155 while (instruction != null) { | 157 while (instruction != null) { |
| 156 HInstruction next = instruction.next; | 158 HInstruction next = instruction.next; |
| 157 HInstruction replacement = instruction.accept(this); | 159 HInstruction replacement = instruction.accept(this); |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 } | 670 } |
| 669 | 671 |
| 670 HInstruction visitIs(HIs node) { | 672 HInstruction visitIs(HIs node) { |
| 671 DartType type = node.typeExpression; | 673 DartType type = node.typeExpression; |
| 672 Element element = type.element; | 674 Element element = type.element; |
| 673 | 675 |
| 674 if (!node.isRawCheck) { | 676 if (!node.isRawCheck) { |
| 675 return node; | 677 return node; |
| 676 } else if (type.isTypedef) { | 678 } else if (type.isTypedef) { |
| 677 return node; | 679 return node; |
| 678 } else if (element == compiler.functionClass) { | 680 } else if (element == coreClasses.functionClass) { |
| 679 return node; | 681 return node; |
| 680 } | 682 } |
| 681 | 683 |
| 682 if (element == compiler.objectClass || type.treatAsDynamic) { | 684 if (type.isObject || type.treatAsDynamic) { |
| 683 return graph.addConstantBool(true, compiler); | 685 return graph.addConstantBool(true, compiler); |
| 684 } | 686 } |
| 685 | 687 |
| 686 ClassWorld classWorld = compiler.world; | 688 ClassWorld classWorld = compiler.world; |
| 687 HInstruction expression = node.expression; | 689 HInstruction expression = node.expression; |
| 688 if (expression.isInteger(compiler)) { | 690 if (expression.isInteger(compiler)) { |
| 689 if (identical(element, compiler.intClass) | 691 if (element == coreClasses.intClass || |
| 690 || identical(element, compiler.numClass) | 692 element == coreClasses.numClass || |
| 691 || Elements.isNumberOrStringSupertype(element, compiler)) { | 693 Elements.isNumberOrStringSupertype(element, compiler)) { |
| 692 return graph.addConstantBool(true, compiler); | 694 return graph.addConstantBool(true, compiler); |
| 693 } else if (identical(element, compiler.doubleClass)) { | 695 } else if (element == coreClasses.doubleClass) { |
| 694 // We let the JS semantics decide for that check. Currently | 696 // We let the JS semantics decide for that check. Currently |
| 695 // the code we emit will always return true. | 697 // the code we emit will always return true. |
| 696 return node; | 698 return node; |
| 697 } else { | 699 } else { |
| 698 return graph.addConstantBool(false, compiler); | 700 return graph.addConstantBool(false, compiler); |
| 699 } | 701 } |
| 700 } else if (expression.isDouble(compiler)) { | 702 } else if (expression.isDouble(compiler)) { |
| 701 if (identical(element, compiler.doubleClass) | 703 if (element == coreClasses.doubleClass || |
| 702 || identical(element, compiler.numClass) | 704 element == coreClasses.numClass || |
| 703 || Elements.isNumberOrStringSupertype(element, compiler)) { | 705 Elements.isNumberOrStringSupertype(element, compiler)) { |
| 704 return graph.addConstantBool(true, compiler); | 706 return graph.addConstantBool(true, compiler); |
| 705 } else if (identical(element, compiler.intClass)) { | 707 } else if (element == coreClasses.intClass) { |
| 706 // We let the JS semantics decide for that check. Currently | 708 // We let the JS semantics decide for that check. Currently |
| 707 // the code we emit will return true for a double that can be | 709 // the code we emit will return true for a double that can be |
| 708 // represented as a 31-bit integer and for -0.0. | 710 // represented as a 31-bit integer and for -0.0. |
| 709 return node; | 711 return node; |
| 710 } else { | 712 } else { |
| 711 return graph.addConstantBool(false, compiler); | 713 return graph.addConstantBool(false, compiler); |
| 712 } | 714 } |
| 713 } else if (expression.isNumber(compiler)) { | 715 } else if (expression.isNumber(compiler)) { |
| 714 if (identical(element, compiler.numClass)) { | 716 if (element == coreClasses.numClass) { |
| 715 return graph.addConstantBool(true, compiler); | 717 return graph.addConstantBool(true, compiler); |
| 716 } else { | 718 } else { |
| 717 // We cannot just return false, because the expression may be of | 719 // We cannot just return false, because the expression may be of |
| 718 // type int or double. | 720 // type int or double. |
| 719 } | 721 } |
| 720 } else if (expression.canBePrimitiveNumber(compiler) | 722 } else if (expression.canBePrimitiveNumber(compiler) && |
| 721 && identical(element, compiler.intClass)) { | 723 element == coreClasses.intClass) { |
| 722 // We let the JS semantics decide for that check. | 724 // We let the JS semantics decide for that check. |
| 723 return node; | 725 return node; |
| 724 // We need the [:hasTypeArguments:] check because we don't have | 726 // We need the [:hasTypeArguments:] check because we don't have |
| 725 // the notion of generics in the backend. For example, [:this:] in | 727 // the notion of generics in the backend. For example, [:this:] in |
| 726 // a class [:A<T>:], is currently always considered to have the | 728 // a class [:A<T>:], is currently always considered to have the |
| 727 // raw type. | 729 // raw type. |
| 728 } else if (!RuntimeTypes.hasTypeArguments(type)) { | 730 } else if (!RuntimeTypes.hasTypeArguments(type)) { |
| 729 TypeMask expressionMask = expression.instructionType; | 731 TypeMask expressionMask = expression.instructionType; |
| 730 assert(TypeMask.assertIsNormalized(expressionMask, classWorld)); | 732 assert(TypeMask.assertIsNormalized(expressionMask, classWorld)); |
| 731 TypeMask typeMask = (element == compiler.nullClass) | 733 TypeMask typeMask = (element == coreClasses.nullClass) |
| 732 ? new TypeMask.subtype(element, classWorld) | 734 ? new TypeMask.subtype(element, classWorld) |
| 733 : new TypeMask.nonNullSubtype(element, classWorld); | 735 : new TypeMask.nonNullSubtype(element, classWorld); |
| 734 if (expressionMask.union(typeMask, classWorld) == typeMask) { | 736 if (expressionMask.union(typeMask, classWorld) == typeMask) { |
| 735 return graph.addConstantBool(true, compiler); | 737 return graph.addConstantBool(true, compiler); |
| 736 } else if (expressionMask.intersection(typeMask, | 738 } else if (expressionMask.intersection(typeMask, |
| 737 compiler.world).isEmpty) { | 739 compiler.world).isEmpty) { |
| 738 return graph.addConstantBool(false, compiler); | 740 return graph.addConstantBool(false, compiler); |
| 739 } | 741 } |
| 740 } | 742 } |
| 741 return node; | 743 return node; |
| (...skipping 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 | 2398 |
| 2397 keyedValues.forEach((receiver, values) { | 2399 keyedValues.forEach((receiver, values) { |
| 2398 result.keyedValues[receiver] = | 2400 result.keyedValues[receiver] = |
| 2399 new Map<HInstruction, HInstruction>.from(values); | 2401 new Map<HInstruction, HInstruction>.from(values); |
| 2400 }); | 2402 }); |
| 2401 | 2403 |
| 2402 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2404 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2403 return result; | 2405 return result; |
| 2404 } | 2406 } |
| 2405 } | 2407 } |
| OLD | NEW |