| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 visitReturn(HReturn node) => visitControlFlow(node); | 298 visitReturn(HReturn node) => visitControlFlow(node); |
| 299 visitShiftRight(HShiftRight node) => visitBinaryBitOp(node); | 299 visitShiftRight(HShiftRight node) => visitBinaryBitOp(node); |
| 300 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node); | 300 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node); |
| 301 visitSubtract(HSubtract node) => visitBinaryArithmetic(node); | 301 visitSubtract(HSubtract node) => visitBinaryArithmetic(node); |
| 302 visitStatic(HStatic node) => visitInstruction(node); | 302 visitStatic(HStatic node) => visitInstruction(node); |
| 303 visitStaticStore(HStaticStore node) => visitInstruction(node); | 303 visitStaticStore(HStaticStore node) => visitInstruction(node); |
| 304 visitThis(HThis node) => visitParameterValue(node); | 304 visitThis(HThis node) => visitParameterValue(node); |
| 305 visitThrow(HThrow node) => visitControlFlow(node); | 305 visitThrow(HThrow node) => visitControlFlow(node); |
| 306 visitTry(HTry node) => visitControlFlow(node); | 306 visitTry(HTry node) => visitControlFlow(node); |
| 307 visitTruncatingDivide(HTruncatingDivide node) => visitBinaryArithmetic(node); | 307 visitTruncatingDivide(HTruncatingDivide node) => visitBinaryArithmetic(node); |
| 308 visitTypeGuard(HTypeGuard node) => visitInstruction(node); | 308 visitTypeGuard(HTypeGuard node) => visitCheck(node); |
| 309 visitIs(HIs node) => visitInstruction(node); | 309 visitIs(HIs node) => visitInstruction(node); |
| 310 visitTypeConversion(HTypeConversion node) => visitInstruction(node); | 310 visitTypeConversion(HTypeConversion node) => visitCheck(node); |
| 311 } | 311 } |
| 312 | 312 |
| 313 class SubGraph { | 313 class SubGraph { |
| 314 // The first and last block of the sub-graph. | 314 // The first and last block of the sub-graph. |
| 315 final HBasicBlock start; | 315 final HBasicBlock start; |
| 316 final HBasicBlock end; | 316 final HBasicBlock end; |
| 317 | 317 |
| 318 const SubGraph(this.start, this.end); | 318 const SubGraph(this.start, this.end); |
| 319 | 319 |
| 320 bool contains(HBasicBlock block) { | 320 bool contains(HBasicBlock block) { |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 bool typeEquals(other) => other is HBoolify; | 948 bool typeEquals(other) => other is HBoolify; |
| 949 bool dataEquals(HInstruction other) => true; | 949 bool dataEquals(HInstruction other) => true; |
| 950 } | 950 } |
| 951 | 951 |
| 952 class HCheck extends HInstruction { | 952 class HCheck extends HInstruction { |
| 953 HCheck(inputs) : super(inputs); | 953 HCheck(inputs) : super(inputs); |
| 954 | 954 |
| 955 // TODO(floitsch): make class abstract instead of adding an abstract method. | 955 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 956 abstract accept(HVisitor visitor); | 956 abstract accept(HVisitor visitor); |
| 957 | 957 |
| 958 bool isControlFlow() => true; | 958 HInstruction get checkedInput() => inputs[0]; |
| 959 } | 959 } |
| 960 | 960 |
| 961 class HTypeGuard extends HInstruction { | 961 class HTypeGuard extends HCheck { |
| 962 final int state; | 962 final int state; |
| 963 final HType guardedType; | 963 final HType guardedType; |
| 964 bool isOn = false; | 964 bool isOn = false; |
| 965 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env); | 965 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env); |
| 966 | 966 |
| 967 void prepareGvn() { | 967 void prepareGvn() { |
| 968 assert(!hasSideEffects()); | 968 assert(!hasSideEffects()); |
| 969 setUseGvn(); | 969 setUseGvn(); |
| 970 } | 970 } |
| 971 | 971 |
| 972 HInstruction get guarded() => inputs.last(); | 972 HInstruction get guarded() => inputs.last(); |
| 973 HInstruction get checkedInput() => guarded; |
| 973 | 974 |
| 974 HType computeTypeFromInputTypes() { | 975 HType computeTypeFromInputTypes() { |
| 975 return isOn ? guardedType : guarded.propagatedType; | 976 return isOn ? guardedType : guarded.propagatedType; |
| 976 } | 977 } |
| 977 | 978 |
| 978 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN; | 979 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN; |
| 979 | 980 |
| 980 bool isControlFlow() => true; | 981 bool isControlFlow() => true; |
| 981 | 982 |
| 982 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 983 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 983 int typeCode() => 1; | 984 int typeCode() => 1; |
| 984 bool typeEquals(other) => other is HTypeGuard; | 985 bool typeEquals(other) => other is HTypeGuard; |
| 985 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; | 986 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 986 } | 987 } |
| 987 | 988 |
| 988 class HBoundsCheck extends HCheck { | 989 class HBoundsCheck extends HCheck { |
| 989 static final int ALWAYS_FALSE = 0; | 990 static final int ALWAYS_FALSE = 0; |
| 990 static final int FULL_CHECK = 1; | 991 static final int FULL_CHECK = 1; |
| 991 static final int ALWAYS_ABOVE_ZERO = 2; | 992 static final int ALWAYS_ABOVE_ZERO = 2; |
| 992 static final int ALWAYS_TRUE = 3; | 993 static final int ALWAYS_TRUE = 3; |
| 993 /** | 994 /** |
| 994 * Details which tests have been done statically during compilation. | 995 * Details which tests have been done statically during compilation. |
| 995 * Default is that all checks must be performed dynamically. | 996 * Default is that all checks must be performed dynamically. |
| 996 */ | 997 */ |
| 997 int staticChecks = FULL_CHECK; | 998 int staticChecks = FULL_CHECK; |
| 998 | 999 |
| 999 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); | 1000 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); |
| 1000 | 1001 |
| 1001 HInstruction get length() => inputs[0]; | 1002 HInstruction get length() => inputs[1]; |
| 1002 HInstruction get index() => inputs[1]; | 1003 HInstruction get index() => inputs[0]; |
| 1004 bool isControlFlow() => true; |
| 1003 | 1005 |
| 1004 void prepareGvn() { | 1006 void prepareGvn() { |
| 1005 assert(!hasSideEffects()); | 1007 assert(!hasSideEffects()); |
| 1006 setUseGvn(); | 1008 setUseGvn(); |
| 1007 } | 1009 } |
| 1008 | 1010 |
| 1009 HType get guaranteedType() => HType.INTEGER; | 1011 HType get guaranteedType() => HType.INTEGER; |
| 1010 | 1012 |
| 1011 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); | 1013 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); |
| 1012 int typeCode() => 2; | 1014 int typeCode() => 2; |
| 1013 bool typeEquals(other) => other is HBoundsCheck; | 1015 bool typeEquals(other) => other is HBoundsCheck; |
| 1014 bool dataEquals(HInstruction other) => true; | 1016 bool dataEquals(HInstruction other) => true; |
| 1015 } | 1017 } |
| 1016 | 1018 |
| 1017 class HIntegerCheck extends HCheck { | 1019 class HIntegerCheck extends HCheck { |
| 1018 bool alwaysFalse = false; | 1020 bool alwaysFalse = false; |
| 1019 | 1021 |
| 1020 HIntegerCheck(value) : super(<HInstruction>[value]); | 1022 HIntegerCheck(value) : super(<HInstruction>[value]); |
| 1021 | 1023 |
| 1022 HInstruction get value() => inputs[0]; | 1024 HInstruction get value() => inputs[0]; |
| 1025 bool isControlFlow() => true; |
| 1023 | 1026 |
| 1024 void prepareGvn() { | 1027 void prepareGvn() { |
| 1025 assert(!hasSideEffects()); | 1028 assert(!hasSideEffects()); |
| 1026 setUseGvn(); | 1029 setUseGvn(); |
| 1027 } | 1030 } |
| 1028 | 1031 |
| 1029 HType get guaranteedType() => HType.INTEGER; | 1032 HType get guaranteedType() => HType.INTEGER; |
| 1030 | 1033 |
| 1031 accept(HVisitor visitor) => visitor.visitIntegerCheck(this); | 1034 accept(HVisitor visitor) => visitor.visitIntegerCheck(this); |
| 1032 int typeCode() => 3; | 1035 int typeCode() => 3; |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2141 | 2144 |
| 2142 HInstruction get typeInfoCall() => inputs[1]; | 2145 HInstruction get typeInfoCall() => inputs[1]; |
| 2143 | 2146 |
| 2144 HType get guaranteedType() => HType.BOOLEAN; | 2147 HType get guaranteedType() => HType.BOOLEAN; |
| 2145 | 2148 |
| 2146 accept(HVisitor visitor) => visitor.visitIs(this); | 2149 accept(HVisitor visitor) => visitor.visitIs(this); |
| 2147 | 2150 |
| 2148 toString() => "$expression is $typeExpression"; | 2151 toString() => "$expression is $typeExpression"; |
| 2149 } | 2152 } |
| 2150 | 2153 |
| 2151 class HTypeConversion extends HInstruction { | 2154 class HTypeConversion extends HCheck { |
| 2152 HType type; | 2155 HType type; |
| 2153 final bool checked; | 2156 final bool checked; |
| 2154 | 2157 |
| 2155 HTypeConversion(HType this.type, | 2158 HTypeConversion(HType this.type, |
| 2156 HInstruction input, | 2159 HInstruction input, |
| 2157 [bool this.checked = false]) | 2160 [bool this.checked = false]) |
| 2158 : super(<HInstruction>[input]) { | 2161 : super(<HInstruction>[input]) { |
| 2159 sourceElement = input.sourceElement; | 2162 sourceElement = input.sourceElement; |
| 2160 } | 2163 } |
| 2161 | 2164 |
| 2162 HType get guaranteedType() => type; | 2165 HType get guaranteedType() => type; |
| 2163 | 2166 |
| 2164 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2167 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2168 |
| 2169 bool hasSideEffects() => checked; |
| 2165 } | 2170 } |
| 2166 | 2171 |
| 2167 /** Non-block-based (aka. traditional) loop information. */ | 2172 /** Non-block-based (aka. traditional) loop information. */ |
| 2168 class HLoopInformation { | 2173 class HLoopInformation { |
| 2169 final HBasicBlock header; | 2174 final HBasicBlock header; |
| 2170 final List<HBasicBlock> blocks; | 2175 final List<HBasicBlock> blocks; |
| 2171 final List<HBasicBlock> backEdges; | 2176 final List<HBasicBlock> backEdges; |
| 2172 final List<LabelElement> labels; | 2177 final List<LabelElement> labels; |
| 2173 final TargetElement target; | 2178 final TargetElement target; |
| 2174 | 2179 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2449 this.catchBlock, | 2454 this.catchBlock, |
| 2450 this.finallyBlock); | 2455 this.finallyBlock); |
| 2451 | 2456 |
| 2452 HBasicBlock get start() => body.start; | 2457 HBasicBlock get start() => body.start; |
| 2453 HBasicBlock get end() => | 2458 HBasicBlock get end() => |
| 2454 finallyBlock === null ? catchBlock.end : finallyBlock.end; | 2459 finallyBlock === null ? catchBlock.end : finallyBlock.end; |
| 2455 | 2460 |
| 2456 bool accept(HStatementInformationVisitor visitor) => | 2461 bool accept(HStatementInformationVisitor visitor) => |
| 2457 visitor.visitTryInfo(this); | 2462 visitor.visitTryInfo(this); |
| 2458 } | 2463 } |
| OLD | NEW |