| 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 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 } | 957 } |
| 958 | 958 |
| 959 HType get guaranteedType() => HType.BOOLEAN; | 959 HType get guaranteedType() => HType.BOOLEAN; |
| 960 | 960 |
| 961 accept(HVisitor visitor) => visitor.visitBoolify(this); | 961 accept(HVisitor visitor) => visitor.visitBoolify(this); |
| 962 int typeCode() => 0; | 962 int typeCode() => 0; |
| 963 bool typeEquals(other) => other is HBoolify; | 963 bool typeEquals(other) => other is HBoolify; |
| 964 bool dataEquals(HInstruction other) => true; | 964 bool dataEquals(HInstruction other) => true; |
| 965 } | 965 } |
| 966 | 966 |
| 967 class HCheck extends HInstruction { | 967 /** |
| 968 * A [HCheck] instruction is an instruction that might do a dynamic |
| 969 * check at runtime on another instruction. To have proper instruction |
| 970 * dependencies in the graph, instructions that depend on the check |
| 971 * being done reference the [HCheck] instruction instead of the |
| 972 * instruction itself. |
| 973 */ |
| 974 abstract class HCheck extends HInstruction { |
| 968 HCheck(inputs) : super(inputs); | 975 HCheck(inputs) : super(inputs); |
| 969 | |
| 970 // TODO(floitsch): make class abstract instead of adding an abstract method. | |
| 971 abstract accept(HVisitor visitor); | |
| 972 | |
| 973 HInstruction get checkedInput() => inputs[0]; | 976 HInstruction get checkedInput() => inputs[0]; |
| 974 } | 977 } |
| 975 | 978 |
| 976 class HTypeGuard extends HCheck { | 979 /** |
| 980 * A [HCheckStatement] instruction is a [HCheck instruction] that |
| 981 * cannot be generated as an expression. |
| 982 */ |
| 983 abstract class HCheckStatement extends HCheck { |
| 984 HCheckStatement(inputs) : super(inputs); |
| 985 } |
| 986 |
| 987 class HTypeGuard extends HCheckStatement { |
| 977 final int state; | 988 final int state; |
| 978 final HType guardedType; | 989 final HType guardedType; |
| 979 bool isOn = false; | 990 bool isOn = false; |
| 980 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env); | 991 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env); |
| 981 | 992 |
| 982 void prepareGvn() { | 993 void prepareGvn() { |
| 983 assert(!hasSideEffects()); | 994 assert(!hasSideEffects()); |
| 984 setUseGvn(); | 995 setUseGvn(); |
| 985 } | 996 } |
| 986 | 997 |
| 987 HInstruction get guarded() => inputs.last(); | 998 HInstruction get guarded() => inputs.last(); |
| 988 HInstruction get checkedInput() => guarded; | 999 HInstruction get checkedInput() => guarded; |
| 989 | 1000 |
| 990 HType computeTypeFromInputTypes() { | 1001 HType computeTypeFromInputTypes() { |
| 991 return isOn ? guardedType : guarded.propagatedType; | 1002 return isOn ? guardedType : guarded.propagatedType; |
| 992 } | 1003 } |
| 993 | 1004 |
| 994 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN; | 1005 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN; |
| 995 | 1006 |
| 996 bool isControlFlow() => true; | 1007 bool isControlFlow() => true; |
| 997 | 1008 |
| 998 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1009 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 999 int typeCode() => 1; | 1010 int typeCode() => 1; |
| 1000 bool typeEquals(other) => other is HTypeGuard; | 1011 bool typeEquals(other) => other is HTypeGuard; |
| 1001 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; | 1012 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 1002 } | 1013 } |
| 1003 | 1014 |
| 1004 class HBoundsCheck extends HCheck { | 1015 class HBoundsCheck extends HCheckStatement { |
| 1005 static final int ALWAYS_FALSE = 0; | 1016 static final int ALWAYS_FALSE = 0; |
| 1006 static final int FULL_CHECK = 1; | 1017 static final int FULL_CHECK = 1; |
| 1007 static final int ALWAYS_ABOVE_ZERO = 2; | 1018 static final int ALWAYS_ABOVE_ZERO = 2; |
| 1008 static final int ALWAYS_TRUE = 3; | 1019 static final int ALWAYS_TRUE = 3; |
| 1009 /** | 1020 /** |
| 1010 * Details which tests have been done statically during compilation. | 1021 * Details which tests have been done statically during compilation. |
| 1011 * Default is that all checks must be performed dynamically. | 1022 * Default is that all checks must be performed dynamically. |
| 1012 */ | 1023 */ |
| 1013 int staticChecks = FULL_CHECK; | 1024 int staticChecks = FULL_CHECK; |
| 1014 | 1025 |
| 1015 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); | 1026 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); |
| 1016 | 1027 |
| 1017 HInstruction get length() => inputs[1]; | 1028 HInstruction get length() => inputs[1]; |
| 1018 HInstruction get index() => inputs[0]; | 1029 HInstruction get index() => inputs[0]; |
| 1019 bool isControlFlow() => true; | 1030 bool isControlFlow() => true; |
| 1020 | 1031 |
| 1021 void prepareGvn() { | 1032 void prepareGvn() { |
| 1022 assert(!hasSideEffects()); | 1033 assert(!hasSideEffects()); |
| 1023 setUseGvn(); | 1034 setUseGvn(); |
| 1024 } | 1035 } |
| 1025 | 1036 |
| 1026 HType get guaranteedType() => HType.INTEGER; | 1037 HType get guaranteedType() => HType.INTEGER; |
| 1027 | 1038 |
| 1028 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); | 1039 accept(HVisitor visitor) => visitor.visitBoundsCheck(this); |
| 1029 int typeCode() => 2; | 1040 int typeCode() => 2; |
| 1030 bool typeEquals(other) => other is HBoundsCheck; | 1041 bool typeEquals(other) => other is HBoundsCheck; |
| 1031 bool dataEquals(HInstruction other) => true; | 1042 bool dataEquals(HInstruction other) => true; |
| 1032 } | 1043 } |
| 1033 | 1044 |
| 1034 class HIntegerCheck extends HCheck { | 1045 class HIntegerCheck extends HCheckStatement { |
| 1035 bool alwaysFalse = false; | 1046 bool alwaysFalse = false; |
| 1036 | 1047 |
| 1037 HIntegerCheck(value) : super(<HInstruction>[value]); | 1048 HIntegerCheck(value) : super(<HInstruction>[value]); |
| 1038 | 1049 |
| 1039 HInstruction get value() => inputs[0]; | 1050 HInstruction get value() => inputs[0]; |
| 1040 bool isControlFlow() => true; | 1051 bool isControlFlow() => true; |
| 1041 | 1052 |
| 1042 void prepareGvn() { | 1053 void prepareGvn() { |
| 1043 assert(!hasSideEffects()); | 1054 assert(!hasSideEffects()); |
| 1044 setUseGvn(); | 1055 setUseGvn(); |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 HBasicBlock get start() => expression.start; | 2575 HBasicBlock get start() => expression.start; |
| 2565 HBasicBlock get end() { | 2576 HBasicBlock get end() { |
| 2566 // We don't create a switch block if there are no cases. | 2577 // We don't create a switch block if there are no cases. |
| 2567 assert(!statements.isEmpty()); | 2578 assert(!statements.isEmpty()); |
| 2568 return statements.last().end; | 2579 return statements.last().end; |
| 2569 } | 2580 } |
| 2570 | 2581 |
| 2571 bool accept(HStatementInformationVisitor visitor) => | 2582 bool accept(HStatementInformationVisitor visitor) => |
| 2572 visitor.visitSwitchInfo(this); | 2583 visitor.visitSwitchInfo(this); |
| 2573 } | 2584 } |
| OLD | NEW |