Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10828319: Cleanup handling of NullType in type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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_ = &it;
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698