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 |