| 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 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 void ForwardInstructionIterator::RemoveCurrentFromGraph() { | 145 void ForwardInstructionIterator::RemoveCurrentFromGraph() { |
| 146 current_ = current_->RemoveFromGraph(true); // Set current_ to previous. | 146 current_ = current_->RemoveFromGraph(true); // Set current_ to previous. |
| 147 } | 147 } |
| 148 | 148 |
| 149 | 149 |
| 150 // Default implementation of visiting basic blocks. Can be overridden. | 150 // Default implementation of visiting basic blocks. Can be overridden. |
| 151 void FlowGraphVisitor::VisitBlocks() { | 151 void FlowGraphVisitor::VisitBlocks() { |
| 152 ASSERT(current_iterator_ == NULL); |
| 152 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 153 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 153 BlockEntryInstr* entry = block_order_[i]; | 154 BlockEntryInstr* entry = block_order_[i]; |
| 154 entry->Accept(this); | 155 entry->Accept(this); |
| 155 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 156 ForwardInstructionIterator it(entry); |
| 157 current_iterator_ = ⁢ |
| 158 for (; !it.Done(); it.Advance()) { |
| 156 it.Current()->Accept(this); | 159 it.Current()->Accept(this); |
| 157 } | 160 } |
| 161 current_iterator_ = NULL; |
| 158 } | 162 } |
| 159 } | 163 } |
| 160 | 164 |
| 161 | 165 |
| 166 // Returns true if the value is constant null. |
| 167 bool Value::IsConstantNull() const { |
| 168 return IsConstant() && AsConstant()->value().IsNull(); |
| 169 } |
| 170 |
| 171 |
| 162 // Returns true if the compile type of this value is more specific than the | 172 // Returns true if the compile type of this value is more specific than the |
| 163 // given dst_type. | 173 // given dst_type. |
| 164 // TODO(regis): Support a set of compile types for the given value. | 174 // TODO(regis): Support a set of compile types for the given value. |
| 165 bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const { | 175 bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const { |
| 166 ASSERT(!dst_type.IsMalformed()); // Should be tested by caller. | 176 // No type is more specific than a malformed type. |
| 167 ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller. | 177 if (dst_type.IsMalformed()) { |
| 168 ASSERT(!dst_type.IsObjectType()); // Should be tested by caller. | 178 return false; |
| 179 } |
| 169 | 180 |
| 170 // If the value is the null constant, its type (NullType) is more specific | 181 // If the value is the null constant, its type (NullType) is more specific |
| 171 // than the destination type, even if the destination type is the void type, | 182 // than the destination type, even if the destination type is the void type, |
| 172 // since a void function is allowed to return null. | 183 // since a void function is allowed to return null. |
| 173 if (IsConstant() && AsConstant()->value().IsNull()) { | 184 if (IsConstantNull()) { |
| 174 return true; | 185 return true; |
| 175 } | 186 } |
| 176 | 187 |
| 177 // Functions that do not explicitly return a value, implicitly return null, | 188 // Functions that do not explicitly return a value, implicitly return null, |
| 178 // except generative constructors, which return the object being constructed. | 189 // except generative constructors, which return the object being constructed. |
| 179 // It is therefore acceptable for void functions to return null. | 190 // It is therefore acceptable for void functions to return null. |
| 180 // In case of a null constant, we have already returned true above, else we | 191 // In case of a null constant, we have already returned true above, else we |
| 181 // return false here. | 192 // return false here. |
| 182 if (dst_type.IsVoidType()) { | 193 if (dst_type.IsVoidType()) { |
| 183 return false; | 194 return false; |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 BindInstr* right = right_use->definition()->AsBind(); | 1062 BindInstr* right = right_use->definition()->AsBind(); |
| 1052 if (right == NULL) return NULL; | 1063 if (right == NULL) return NULL; |
| 1053 ConstantVal* right_constant = right->computation()->AsConstant(); | 1064 ConstantVal* right_constant = right->computation()->AsConstant(); |
| 1054 if (right_constant == NULL) return NULL; | 1065 if (right_constant == NULL) return NULL; |
| 1055 // TODO(fschneider): Handle other cases: e === false and e !== true/false. | 1066 // TODO(fschneider): Handle other cases: e === false and e !== true/false. |
| 1056 // Handles e === true. | 1067 // Handles e === true. |
| 1057 if ((kind() == Token::kEQ_STRICT) && | 1068 if ((kind() == Token::kEQ_STRICT) && |
| 1058 (right_constant->value().raw() == Bool::True()) && | 1069 (right_constant->value().raw() == Bool::True()) && |
| 1059 left_use->CompileTypeIsMoreSpecificThan( | 1070 left_use->CompileTypeIsMoreSpecificThan( |
| 1060 Type::Handle(Type::BoolInterface()))) { | 1071 Type::Handle(Type::BoolInterface()))) { |
| 1072 // TODO(regis): I am not sure this optimization is correct. |
| 1073 // Although the compile type of left_use is bool, left_use may be null at |
| 1074 // runtime, e.g. true === f(), with bool f() { bool x; return x }. |
| 1075 // In this case, the optimized strict equal returns null. |
| 1076 |
| 1061 // Remove the constant from the graph. | 1077 // Remove the constant from the graph. |
| 1062 right->RemoveFromGraph(); | 1078 right->RemoveFromGraph(); |
| 1063 // Return left subexpression as the replacement for this instruction. | 1079 // Return left subexpression as the replacement for this instruction. |
| 1064 return left; | 1080 return left; |
| 1065 } | 1081 } |
| 1066 return NULL; | 1082 return NULL; |
| 1067 } | 1083 } |
| 1068 | 1084 |
| 1069 | 1085 |
| 1070 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 1086 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 if (compiler->is_ssa()) { | 1325 if (compiler->is_ssa()) { |
| 1310 ASSERT(locs()->in(0).IsRegister()); | 1326 ASSERT(locs()->in(0).IsRegister()); |
| 1311 __ PushRegister(locs()->in(0).reg()); | 1327 __ PushRegister(locs()->in(0).reg()); |
| 1312 } | 1328 } |
| 1313 } | 1329 } |
| 1314 | 1330 |
| 1315 | 1331 |
| 1316 #undef __ | 1332 #undef __ |
| 1317 | 1333 |
| 1318 } // namespace dart | 1334 } // namespace dart |
| OLD | NEW |