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 HVisitor<R> { | 7 abstract class HVisitor<R> { |
8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
9 R visitBitAnd(HBitAnd node); | 9 R visitBitAnd(HBitAnd node); |
10 R visitBitNot(HBitNot node); | 10 R visitBitNot(HBitNot node); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 R visitStringConcat(HStringConcat node); | 61 R visitStringConcat(HStringConcat node); |
62 R visitStringify(HStringify node); | 62 R visitStringify(HStringify node); |
63 R visitSubtract(HSubtract node); | 63 R visitSubtract(HSubtract node); |
64 R visitSwitch(HSwitch node); | 64 R visitSwitch(HSwitch node); |
65 R visitThis(HThis node); | 65 R visitThis(HThis node); |
66 R visitThrow(HThrow node); | 66 R visitThrow(HThrow node); |
67 R visitThrowExpression(HThrowExpression node); | 67 R visitThrowExpression(HThrowExpression node); |
68 R visitTry(HTry node); | 68 R visitTry(HTry node); |
69 R visitTypeConversion(HTypeConversion node); | 69 R visitTypeConversion(HTypeConversion node); |
70 R visitTypeKnown(HTypeKnown node); | 70 R visitTypeKnown(HTypeKnown node); |
| 71 R visitReadTypeVariable(HReadTypeVariable node); |
| 72 R visitFunctionType(HFunctionType node); |
| 73 R visitVoidType(HVoidType node); |
| 74 R visitInterfaceType(HInterfaceType node); |
| 75 R visitDynamicType(HDynamicType node); |
71 } | 76 } |
72 | 77 |
73 abstract class HGraphVisitor { | 78 abstract class HGraphVisitor { |
74 visitDominatorTree(HGraph graph) { | 79 visitDominatorTree(HGraph graph) { |
75 void visitBasicBlockAndSuccessors(HBasicBlock block) { | 80 void visitBasicBlockAndSuccessors(HBasicBlock block) { |
76 visitBasicBlock(block); | 81 visitBasicBlock(block); |
77 List dominated = block.dominatedBlocks; | 82 List dominated = block.dominatedBlocks; |
78 for (int i = 0; i < dominated.length; i++) { | 83 for (int i = 0; i < dominated.length; i++) { |
79 visitBasicBlockAndSuccessors(dominated[i]); | 84 visitBasicBlockAndSuccessors(dominated[i]); |
80 } | 85 } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 visitStaticStore(HStaticStore node) => visitInstruction(node); | 328 visitStaticStore(HStaticStore node) => visitInstruction(node); |
324 visitStringConcat(HStringConcat node) => visitInstruction(node); | 329 visitStringConcat(HStringConcat node) => visitInstruction(node); |
325 visitStringify(HStringify node) => visitInstruction(node); | 330 visitStringify(HStringify node) => visitInstruction(node); |
326 visitThis(HThis node) => visitParameterValue(node); | 331 visitThis(HThis node) => visitParameterValue(node); |
327 visitThrow(HThrow node) => visitControlFlow(node); | 332 visitThrow(HThrow node) => visitControlFlow(node); |
328 visitThrowExpression(HThrowExpression node) => visitInstruction(node); | 333 visitThrowExpression(HThrowExpression node) => visitInstruction(node); |
329 visitTry(HTry node) => visitControlFlow(node); | 334 visitTry(HTry node) => visitControlFlow(node); |
330 visitIs(HIs node) => visitInstruction(node); | 335 visitIs(HIs node) => visitInstruction(node); |
331 visitTypeConversion(HTypeConversion node) => visitCheck(node); | 336 visitTypeConversion(HTypeConversion node) => visitCheck(node); |
332 visitTypeKnown(HTypeKnown node) => visitCheck(node); | 337 visitTypeKnown(HTypeKnown node) => visitCheck(node); |
| 338 visitReadTypeVariable(HReadTypeVariable node) => visitInstruction(node); |
| 339 visitFunctionType(HFunctionType node) => visitInstruction(node); |
| 340 visitVoidType(HVoidType node) => visitInstruction(node); |
| 341 visitInterfaceType(HInterfaceType node) => visitInstruction(node); |
| 342 visitDynamicType(HDynamicType node) => visitInstruction(node); |
333 } | 343 } |
334 | 344 |
335 class SubGraph { | 345 class SubGraph { |
336 // The first and last block of the sub-graph. | 346 // The first and last block of the sub-graph. |
337 final HBasicBlock start; | 347 final HBasicBlock start; |
338 final HBasicBlock end; | 348 final HBasicBlock end; |
339 | 349 |
340 const SubGraph(this.start, this.end); | 350 const SubGraph(this.start, this.end); |
341 | 351 |
342 bool contains(HBasicBlock block) { | 352 bool contains(HBasicBlock block) { |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 static const int STATIC_TYPECODE = 21; | 786 static const int STATIC_TYPECODE = 21; |
777 static const int STATIC_STORE_TYPECODE = 22; | 787 static const int STATIC_STORE_TYPECODE = 22; |
778 static const int FIELD_GET_TYPECODE = 23; | 788 static const int FIELD_GET_TYPECODE = 23; |
779 static const int TYPE_CONVERSION_TYPECODE = 24; | 789 static const int TYPE_CONVERSION_TYPECODE = 24; |
780 static const int TYPE_KNOWN_TYPECODE = 25; | 790 static const int TYPE_KNOWN_TYPECODE = 25; |
781 static const int INVOKE_STATIC_TYPECODE = 26; | 791 static const int INVOKE_STATIC_TYPECODE = 26; |
782 static const int INDEX_TYPECODE = 27; | 792 static const int INDEX_TYPECODE = 27; |
783 static const int IS_TYPECODE = 28; | 793 static const int IS_TYPECODE = 28; |
784 static const int INVOKE_DYNAMIC_TYPECODE = 29; | 794 static const int INVOKE_DYNAMIC_TYPECODE = 29; |
785 static const int SHIFT_RIGHT_TYPECODE = 30; | 795 static const int SHIFT_RIGHT_TYPECODE = 30; |
| 796 static const int READ_TYPE_VARIABLE_TYPECODE = 31; |
| 797 static const int FUNCTION_TYPE_TYPECODE = 32; |
| 798 static const int VOID_TYPE_TYPECODE = 33; |
| 799 static const int INTERFACE_TYPE_TYPECODE = 34; |
| 800 static const int DYNAMIC_TYPE_TYPECODE = 35; |
786 | 801 |
787 HInstruction(this.inputs, this.instructionType) | 802 HInstruction(this.inputs, this.instructionType) |
788 : id = idCounter++, usedBy = <HInstruction>[] { | 803 : id = idCounter++, usedBy = <HInstruction>[] { |
789 assert(inputs.every((e) => e != null)); | 804 assert(inputs.every((e) => e != null)); |
790 } | 805 } |
791 | 806 |
792 int get hashCode => id; | 807 int get hashCode => id; |
793 | 808 |
794 bool useGvn() => _useGvn; | 809 bool useGvn() => _useGvn; |
795 void setUseGvn() { _useGvn = true; } | 810 void setUseGvn() { _useGvn = true; } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 } | 974 } |
960 | 975 |
961 bool isPrimitiveOrNull(Compiler compiler) { | 976 bool isPrimitiveOrNull(Compiler compiler) { |
962 return isIndexablePrimitive(compiler) | 977 return isIndexablePrimitive(compiler) |
963 || isNumberOrNull(compiler) | 978 || isNumberOrNull(compiler) |
964 || isBooleanOrNull(compiler) | 979 || isBooleanOrNull(compiler) |
965 || isNull(); | 980 || isNull(); |
966 } | 981 } |
967 | 982 |
968 /** | 983 /** |
969 * Type of the unstruction. | 984 * Type of the instruction. |
970 */ | 985 */ |
971 TypeMask instructionType; | 986 TypeMask instructionType; |
972 | 987 |
973 Selector get selector => null; | 988 Selector get selector => null; |
974 HInstruction getDartReceiver(Compiler compiler) => null; | 989 HInstruction getDartReceiver(Compiler compiler) => null; |
975 bool onlyThrowsNSM() => false; | 990 bool onlyThrowsNSM() => false; |
976 | 991 |
977 bool isInBasicBlock() => block != null; | 992 bool isInBasicBlock() => block != null; |
978 | 993 |
979 bool gvnEquals(HInstruction other) { | 994 bool gvnEquals(HInstruction other) { |
(...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2740 this.finallyBlock); | 2755 this.finallyBlock); |
2741 | 2756 |
2742 HBasicBlock get start => body.start; | 2757 HBasicBlock get start => body.start; |
2743 HBasicBlock get end => | 2758 HBasicBlock get end => |
2744 finallyBlock == null ? catchBlock.end : finallyBlock.end; | 2759 finallyBlock == null ? catchBlock.end : finallyBlock.end; |
2745 | 2760 |
2746 bool accept(HStatementInformationVisitor visitor) => | 2761 bool accept(HStatementInformationVisitor visitor) => |
2747 visitor.visitTryInfo(this); | 2762 visitor.visitTryInfo(this); |
2748 } | 2763 } |
2749 | 2764 |
2750 | |
2751 | |
2752 class HSwitchBlockInformation implements HStatementInformation { | 2765 class HSwitchBlockInformation implements HStatementInformation { |
2753 final HExpressionInformation expression; | 2766 final HExpressionInformation expression; |
2754 final List<HStatementInformation> statements; | 2767 final List<HStatementInformation> statements; |
2755 final TargetElement target; | 2768 final TargetElement target; |
2756 final List<LabelElement> labels; | 2769 final List<LabelElement> labels; |
2757 | 2770 |
2758 HSwitchBlockInformation(this.expression, | 2771 HSwitchBlockInformation(this.expression, |
2759 this.statements, | 2772 this.statements, |
2760 this.target, | 2773 this.target, |
2761 this.labels); | 2774 this.labels); |
2762 | 2775 |
2763 HBasicBlock get start => expression.start; | 2776 HBasicBlock get start => expression.start; |
2764 HBasicBlock get end { | 2777 HBasicBlock get end { |
2765 // We don't create a switch block if there are no cases. | 2778 // We don't create a switch block if there are no cases. |
2766 assert(!statements.isEmpty); | 2779 assert(!statements.isEmpty); |
2767 return statements.last.end; | 2780 return statements.last.end; |
2768 } | 2781 } |
2769 | 2782 |
2770 bool accept(HStatementInformationVisitor visitor) => | 2783 bool accept(HStatementInformationVisitor visitor) => |
2771 visitor.visitSwitchInfo(this); | 2784 visitor.visitSwitchInfo(this); |
2772 } | 2785 } |
| 2786 |
| 2787 class HReadTypeVariable extends HInstruction { |
| 2788 /// The type variable being read. |
| 2789 final TypeVariableType dartType; |
| 2790 |
| 2791 final bool hasReceiver; |
| 2792 |
| 2793 HReadTypeVariable(this.dartType, |
| 2794 HInstruction receiver, |
| 2795 TypeMask instructionType) |
| 2796 : hasReceiver = true, |
| 2797 super(<HInstruction>[receiver], instructionType) { |
| 2798 setUseGvn(); |
| 2799 } |
| 2800 |
| 2801 HReadTypeVariable.noReceiver(this.dartType, |
| 2802 HInstruction typeArgument, |
| 2803 TypeMask instructionType) |
| 2804 : hasReceiver = false, |
| 2805 super(<HInstruction>[typeArgument], instructionType) { |
| 2806 setUseGvn(); |
| 2807 } |
| 2808 |
| 2809 accept(HVisitor visitor) => visitor.visitReadTypeVariable(this); |
| 2810 |
| 2811 bool canThrow() => false; |
| 2812 |
| 2813 int typeCode() => HInstruction.READ_TYPE_VARIABLE_TYPECODE; |
| 2814 bool typeEquals(HInstruction other) => other is HReadTypeVariable; |
| 2815 |
| 2816 bool dataEquals(HReadTypeVariable other) { |
| 2817 return dartType.element == other.dartType.element |
| 2818 && hasReceiver == other.hasReceiver; |
| 2819 } |
| 2820 } |
| 2821 |
| 2822 abstract class HRuntimeType extends HInstruction { |
| 2823 final DartType dartType; |
| 2824 |
| 2825 HRuntimeType(List<HInstruction> inputs, |
| 2826 this.dartType, |
| 2827 TypeMask instructionType) |
| 2828 : super(inputs, instructionType) { |
| 2829 setUseGvn(); |
| 2830 } |
| 2831 |
| 2832 bool canThrow() => false; |
| 2833 |
| 2834 int typeCode() { |
| 2835 throw 'abstract method'; |
| 2836 } |
| 2837 |
| 2838 bool typeEquals(HInstruction other) { |
| 2839 throw 'abstract method'; |
| 2840 } |
| 2841 |
| 2842 bool dataEquals(HRuntimeType other) { |
| 2843 return dartType == other.dartType; |
| 2844 } |
| 2845 } |
| 2846 |
| 2847 class HFunctionType extends HRuntimeType { |
| 2848 HFunctionType(List<HInstruction> inputs, |
| 2849 FunctionType dartType, |
| 2850 TypeMask instructionType) |
| 2851 : super(inputs, dartType, instructionType); |
| 2852 |
| 2853 accept(HVisitor visitor) => visitor.visitFunctionType(this); |
| 2854 |
| 2855 int typeCode() => HInstruction.FUNCTION_TYPE_TYPECODE; |
| 2856 |
| 2857 bool typeEquals(HInstruction other) => other is HFunctionType; |
| 2858 } |
| 2859 |
| 2860 class HVoidType extends HRuntimeType { |
| 2861 HVoidType(VoidType dartType, TypeMask instructionType) |
| 2862 : super(const <HInstruction>[], dartType, instructionType); |
| 2863 |
| 2864 accept(HVisitor visitor) => visitor.visitVoidType(this); |
| 2865 |
| 2866 int typeCode() => HInstruction.VOID_TYPE_TYPECODE; |
| 2867 |
| 2868 bool typeEquals(HInstruction other) => other is HVoidType; |
| 2869 } |
| 2870 |
| 2871 class HInterfaceType extends HRuntimeType { |
| 2872 HInterfaceType(List<HInstruction> inputs, |
| 2873 InterfaceType dartType, |
| 2874 TypeMask instructionType) |
| 2875 : super(inputs, dartType, instructionType); |
| 2876 |
| 2877 accept(HVisitor visitor) => visitor.visitInterfaceType(this); |
| 2878 |
| 2879 int typeCode() => HInstruction.INTERFACE_TYPE_TYPECODE; |
| 2880 |
| 2881 bool typeEquals(HInstruction other) => other is HInterfaceType; |
| 2882 } |
| 2883 |
| 2884 class HDynamicType extends HRuntimeType { |
| 2885 HDynamicType(DynamicType dartType, TypeMask instructionType) |
| 2886 : super(const <HInstruction>[], dartType, instructionType); |
| 2887 |
| 2888 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
| 2889 |
| 2890 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
| 2891 |
| 2892 bool typeEquals(HInstruction other) => other is HDynamicType; |
| 2893 } |
OLD | NEW |