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 |