| 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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 M(NumberNegate, NumberNegateComp) \ | 101 M(NumberNegate, NumberNegateComp) \ |
| 102 M(CheckStackOverflow, CheckStackOverflowComp) \ | 102 M(CheckStackOverflow, CheckStackOverflowComp) \ |
| 103 M(DoubleToDouble, DoubleToDoubleComp) \ | 103 M(DoubleToDouble, DoubleToDoubleComp) \ |
| 104 M(SmiToDouble, SmiToDoubleComp) \ | 104 M(SmiToDouble, SmiToDoubleComp) \ |
| 105 M(CheckClass, CheckClassComp) \ | 105 M(CheckClass, CheckClassComp) \ |
| 106 M(CheckSmi, CheckSmiComp) \ | 106 M(CheckSmi, CheckSmiComp) \ |
| 107 M(Materialize, MaterializeComp) \ | 107 M(Materialize, MaterializeComp) \ |
| 108 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ | 108 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ |
| 109 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ | 109 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ |
| 110 M(UnboxDouble, UnboxDoubleComp) \ | 110 M(UnboxDouble, UnboxDoubleComp) \ |
| 111 M(BoxDouble, BoxDoubleComp) | 111 M(BoxDouble, BoxDoubleComp) \ |
| 112 M(CheckArrayBound, CheckArrayBoundComp) |
| 112 | 113 |
| 113 | 114 |
| 114 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 115 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 115 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 116 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 116 FOR_EACH_VALUE(FORWARD_DECLARATION) | 117 FOR_EACH_VALUE(FORWARD_DECLARATION) |
| 117 #undef FORWARD_DECLARATION | 118 #undef FORWARD_DECLARATION |
| 118 | 119 |
| 119 // Forward declarations. | 120 // Forward declarations. |
| 120 class BindInstr; | 121 class BindInstr; |
| 121 class BranchInstr; | 122 class BranchInstr; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 // Compares two computations. Returns true, if: | 172 // Compares two computations. Returns true, if: |
| 172 // 1. They are of the same kind. | 173 // 1. They are of the same kind. |
| 173 // 2. All input operands match. | 174 // 2. All input operands match. |
| 174 // 3. All other attributes match. | 175 // 3. All other attributes match. |
| 175 bool Equals(Computation* other) const; | 176 bool Equals(Computation* other) const; |
| 176 | 177 |
| 177 // Returns a hash code for use with hash maps. | 178 // Returns a hash code for use with hash maps. |
| 178 virtual intptr_t Hashcode() const; | 179 virtual intptr_t Hashcode() const; |
| 179 | 180 |
| 180 // Compare attributes of an computation (except input operands and kind). | 181 // Compare attributes of an computation (except input operands and kind). |
| 181 // TODO(fschneider): Make this abstract and implement for all computations. | 182 // All computations that participate in CSE have to override this function. |
| 182 virtual bool AttributesEqual(Computation* other) const { return true; } | 183 virtual bool AttributesEqual(Computation* other) const { |
| 184 UNREACHABLE(); |
| 185 return false; |
| 186 } |
| 183 | 187 |
| 184 // Returns true if the instruction may have side effects. | 188 // Returns true if the instruction may have side effects. |
| 185 // TODO(fschneider): Make this abstract and implement for all computations | 189 // TODO(fschneider): Make this abstract and implement for all computations |
| 186 // instead of returning the safe default (true). | 190 // instead of returning the safe default (true). |
| 187 virtual bool HasSideEffect() const { return true; } | 191 virtual bool HasSideEffect() const { return true; } |
| 188 | 192 |
| 189 // Compile time type of the computation, which typically depends on the | 193 // Compile time type of the computation, which typically depends on the |
| 190 // compile time types (and possibly propagated types) of its inputs. | 194 // compile time types (and possibly propagated types) of its inputs. |
| 191 virtual RawAbstractType* CompileType() const = 0; | 195 virtual RawAbstractType* CompileType() const = 0; |
| 192 virtual intptr_t ResultCid() const = 0; | 196 virtual intptr_t ResultCid() const = 0; |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 const Field& field_; | 1140 const Field& field_; |
| 1137 | 1141 |
| 1138 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); | 1142 DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); |
| 1139 }; | 1143 }; |
| 1140 | 1144 |
| 1141 | 1145 |
| 1142 class LoadIndexedComp : public TemplateComputation<2> { | 1146 class LoadIndexedComp : public TemplateComputation<2> { |
| 1143 public: | 1147 public: |
| 1144 LoadIndexedComp(Value* array, | 1148 LoadIndexedComp(Value* array, |
| 1145 Value* index, | 1149 Value* index, |
| 1146 intptr_t receiver_type, | 1150 intptr_t receiver_type) |
| 1147 InstanceCallComp* original) | 1151 : receiver_type_(receiver_type) { |
| 1148 : receiver_type_(receiver_type), | |
| 1149 original_(original) { | |
| 1150 ASSERT(array != NULL); | 1152 ASSERT(array != NULL); |
| 1151 ASSERT(index != NULL); | 1153 ASSERT(index != NULL); |
| 1152 inputs_[0] = array; | 1154 inputs_[0] = array; |
| 1153 inputs_[1] = index; | 1155 inputs_[1] = index; |
| 1154 } | 1156 } |
| 1155 | 1157 |
| 1156 DECLARE_COMPUTATION(LoadIndexed) | 1158 DECLARE_COMPUTATION(LoadIndexed) |
| 1157 | 1159 |
| 1158 Value* array() const { return inputs_[0]; } | 1160 Value* array() const { return inputs_[0]; } |
| 1159 Value* index() const { return inputs_[1]; } | 1161 Value* index() const { return inputs_[1]; } |
| 1160 | 1162 |
| 1161 intptr_t receiver_type() const { return receiver_type_; } | 1163 intptr_t receiver_type() const { return receiver_type_; } |
| 1162 | 1164 |
| 1163 InstanceCallComp* original() const { return original_; } | 1165 virtual bool CanDeoptimize() const { return false; } |
| 1164 | |
| 1165 virtual bool CanDeoptimize() const { return true; } | |
| 1166 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1166 virtual intptr_t ResultCid() const { return kDynamicCid; } |
| 1167 | 1167 |
| 1168 private: | 1168 private: |
| 1169 intptr_t receiver_type_; | 1169 intptr_t receiver_type_; |
| 1170 InstanceCallComp* original_; | |
| 1171 | 1170 |
| 1172 DISALLOW_COPY_AND_ASSIGN(LoadIndexedComp); | 1171 DISALLOW_COPY_AND_ASSIGN(LoadIndexedComp); |
| 1173 }; | 1172 }; |
| 1174 | 1173 |
| 1175 | 1174 |
| 1176 class StoreIndexedComp : public TemplateComputation<3> { | 1175 class StoreIndexedComp : public TemplateComputation<3> { |
| 1177 public: | 1176 public: |
| 1178 StoreIndexedComp(Value* array, | 1177 StoreIndexedComp(Value* array, |
| 1179 Value* index, | 1178 Value* index, |
| 1180 Value* value, | 1179 Value* value, |
| 1181 intptr_t receiver_type, | 1180 intptr_t receiver_type) |
| 1182 InstanceCallComp* original) | 1181 : receiver_type_(receiver_type) { |
| 1183 : receiver_type_(receiver_type), | |
| 1184 original_(original) { | |
| 1185 ASSERT(array != NULL); | 1182 ASSERT(array != NULL); |
| 1186 ASSERT(index != NULL); | 1183 ASSERT(index != NULL); |
| 1187 ASSERT(value != NULL); | 1184 ASSERT(value != NULL); |
| 1188 inputs_[0] = array; | 1185 inputs_[0] = array; |
| 1189 inputs_[1] = index; | 1186 inputs_[1] = index; |
| 1190 inputs_[2] = value; | 1187 inputs_[2] = value; |
| 1191 } | 1188 } |
| 1192 | 1189 |
| 1193 DECLARE_COMPUTATION(StoreIndexed) | 1190 DECLARE_COMPUTATION(StoreIndexed) |
| 1194 | 1191 |
| 1195 Value* array() const { return inputs_[0]; } | 1192 Value* array() const { return inputs_[0]; } |
| 1196 Value* index() const { return inputs_[1]; } | 1193 Value* index() const { return inputs_[1]; } |
| 1197 Value* value() const { return inputs_[2]; } | 1194 Value* value() const { return inputs_[2]; } |
| 1198 | 1195 |
| 1199 InstanceCallComp* original() const { return original_; } | |
| 1200 | |
| 1201 intptr_t receiver_type() const { return receiver_type_; } | 1196 intptr_t receiver_type() const { return receiver_type_; } |
| 1202 | 1197 |
| 1203 virtual bool CanDeoptimize() const { return true; } | 1198 virtual bool CanDeoptimize() const { return false; } |
| 1204 virtual intptr_t ResultCid() const { return kDynamicCid; } | 1199 virtual intptr_t ResultCid() const { return kDynamicCid; } |
| 1205 | 1200 |
| 1206 private: | 1201 private: |
| 1207 intptr_t receiver_type_; | 1202 intptr_t receiver_type_; |
| 1208 InstanceCallComp* original_; | |
| 1209 | 1203 |
| 1210 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); | 1204 DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); |
| 1211 }; | 1205 }; |
| 1212 | 1206 |
| 1213 | 1207 |
| 1214 // Note overrideable, built-in: value? false : true. | 1208 // Note overrideable, built-in: value? false : true. |
| 1215 class BooleanNegateComp : public TemplateComputation<1> { | 1209 class BooleanNegateComp : public TemplateComputation<1> { |
| 1216 public: | 1210 public: |
| 1217 explicit BooleanNegateComp(Value* value) { | 1211 explicit BooleanNegateComp(Value* value) { |
| 1218 ASSERT(value != NULL); | 1212 ASSERT(value != NULL); |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 ASSERT(right != NULL); | 1710 ASSERT(right != NULL); |
| 1717 inputs_[0] = left; | 1711 inputs_[0] = left; |
| 1718 inputs_[1] = right; | 1712 inputs_[1] = right; |
| 1719 } | 1713 } |
| 1720 | 1714 |
| 1721 DECLARE_COMPUTATION(CheckEitherNonSmi) | 1715 DECLARE_COMPUTATION(CheckEitherNonSmi) |
| 1722 | 1716 |
| 1723 virtual bool CanDeoptimize() const { return true; } | 1717 virtual bool CanDeoptimize() const { return true; } |
| 1724 virtual intptr_t ResultCid() const { return kIllegalCid; } | 1718 virtual intptr_t ResultCid() const { return kIllegalCid; } |
| 1725 | 1719 |
| 1720 virtual bool AttributesEqual(Computation* other) const { return true; } |
| 1721 |
| 1726 virtual bool HasSideEffect() const { return false; } | 1722 virtual bool HasSideEffect() const { return false; } |
| 1727 | 1723 |
| 1728 Value* left() const { return inputs_[0]; } | 1724 Value* left() const { return inputs_[0]; } |
| 1729 | 1725 |
| 1730 Value* right() const { return inputs_[1]; } | 1726 Value* right() const { return inputs_[1]; } |
| 1731 | 1727 |
| 1732 virtual Definition* TryReplace(BindInstr* instr) const; | 1728 virtual Definition* TryReplace(BindInstr* instr) const; |
| 1733 | 1729 |
| 1734 private: | 1730 private: |
| 1735 InstanceCallComp* instance_call_; | 1731 InstanceCallComp* instance_call_; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 intptr_t deopt_id() const { return original_->deopt_id(); } | 2104 intptr_t deopt_id() const { return original_->deopt_id(); } |
| 2109 intptr_t try_index() const { return original_->try_index(); } | 2105 intptr_t try_index() const { return original_->try_index(); } |
| 2110 | 2106 |
| 2111 private: | 2107 private: |
| 2112 InstanceCallComp* original_; | 2108 InstanceCallComp* original_; |
| 2113 | 2109 |
| 2114 DISALLOW_COPY_AND_ASSIGN(CheckSmiComp); | 2110 DISALLOW_COPY_AND_ASSIGN(CheckSmiComp); |
| 2115 }; | 2111 }; |
| 2116 | 2112 |
| 2117 | 2113 |
| 2114 class CheckArrayBoundComp : public TemplateComputation<2> { |
| 2115 public: |
| 2116 CheckArrayBoundComp(Value* array, |
| 2117 Value* index, |
| 2118 intptr_t array_type, |
| 2119 InstanceCallComp* original) |
| 2120 : array_type_(array_type), original_(original) { |
| 2121 ASSERT(array != NULL); |
| 2122 ASSERT(index != NULL); |
| 2123 inputs_[0] = array; |
| 2124 inputs_[1] = index; |
| 2125 } |
| 2126 |
| 2127 DECLARE_COMPUTATION(CheckArrayBound) |
| 2128 |
| 2129 virtual bool CanDeoptimize() const { return true; } |
| 2130 virtual intptr_t ResultCid() const { return kIllegalCid; } |
| 2131 |
| 2132 virtual bool AttributesEqual(Computation* other) const; |
| 2133 |
| 2134 virtual bool HasSideEffect() const { return false; } |
| 2135 |
| 2136 Value* array() const { return inputs_[0]; } |
| 2137 Value* index() const { return inputs_[1]; } |
| 2138 |
| 2139 intptr_t array_type() const { return array_type_; } |
| 2140 |
| 2141 intptr_t deopt_id() const { return original_->deopt_id(); } |
| 2142 intptr_t try_index() const { return original_->try_index(); } |
| 2143 |
| 2144 private: |
| 2145 intptr_t array_type_; |
| 2146 InstanceCallComp* original_; |
| 2147 |
| 2148 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundComp); |
| 2149 }; |
| 2150 |
| 2151 |
| 2118 #undef DECLARE_COMPUTATION | 2152 #undef DECLARE_COMPUTATION |
| 2119 | 2153 |
| 2120 | 2154 |
| 2121 // Implementation of type testers and cast functins. | 2155 // Implementation of type testers and cast functins. |
| 2122 #define DEFINE_COMPUTATION_PREDICATE(ShortName, ClassName) \ | 2156 #define DEFINE_COMPUTATION_PREDICATE(ShortName, ClassName) \ |
| 2123 bool Computation::Is##ShortName() const { \ | 2157 bool Computation::Is##ShortName() const { \ |
| 2124 return computation_kind() == k##ShortName; \ | 2158 return computation_kind() == k##ShortName; \ |
| 2125 } \ | 2159 } \ |
| 2126 const ClassName* Computation::As##ShortName() const { \ | 2160 const ClassName* Computation::As##ShortName() const { \ |
| 2127 if (!Is##ShortName()) return NULL; \ | 2161 if (!Is##ShortName()) return NULL; \ |
| (...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3390 ForwardInstructionIterator* current_iterator_; | 3424 ForwardInstructionIterator* current_iterator_; |
| 3391 | 3425 |
| 3392 private: | 3426 private: |
| 3393 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3427 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3394 }; | 3428 }; |
| 3395 | 3429 |
| 3396 | 3430 |
| 3397 } // namespace dart | 3431 } // namespace dart |
| 3398 | 3432 |
| 3399 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3433 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |