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

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 }
srdjan 2012/08/15 17:49:56 How about making it virtual and implementing in Us
regis 2012/08/15 22:49:18 Good point. It is a bit more complex than just ret
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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 return Type::DynamicType(); 633 return Type::DynamicType();
623 } 634 }
624 635
625 636
626 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const { 637 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
627 return Type::DynamicType(); 638 return Type::DynamicType();
628 } 639 }
629 640
630 641
631 RawAbstractType* StaticCallComp::CompileType() const { 642 RawAbstractType* StaticCallComp::CompileType() const {
632 return function().result_type(); 643 if (FLAG_enable_type_checks) {
644 return function().result_type();
645 }
646 return Type::DynamicType();
633 } 647 }
634 648
635 649
636 RawAbstractType* LoadLocalComp::CompileType() const { 650 RawAbstractType* LoadLocalComp::CompileType() const {
637 if (FLAG_enable_type_checks) { 651 if (FLAG_enable_type_checks) {
638 return local().type().raw(); 652 return local().type().raw();
639 } 653 }
640 return Type::DynamicType(); 654 return Type::DynamicType();
641 } 655 }
642 656
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 BindInstr* right = right_use->definition()->AsBind(); 1070 BindInstr* right = right_use->definition()->AsBind();
1057 if (right == NULL) return NULL; 1071 if (right == NULL) return NULL;
1058 ConstantVal* right_constant = right->computation()->AsConstant(); 1072 ConstantVal* right_constant = right->computation()->AsConstant();
1059 if (right_constant == NULL) return NULL; 1073 if (right_constant == NULL) return NULL;
1060 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1074 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1061 // Handles e === true. 1075 // Handles e === true.
1062 if ((kind() == Token::kEQ_STRICT) && 1076 if ((kind() == Token::kEQ_STRICT) &&
1063 (right_constant->value().raw() == Bool::True()) && 1077 (right_constant->value().raw() == Bool::True()) &&
1064 left_use->CompileTypeIsMoreSpecificThan( 1078 left_use->CompileTypeIsMoreSpecificThan(
1065 Type::Handle(Type::BoolInterface()))) { 1079 Type::Handle(Type::BoolInterface()))) {
1080 // TODO(regis): I am not sure this optimization is correct.
1081 // Although the compile type of left_use is bool, left_use may be null at
1082 // runtime, e.g. true === f(), with bool f() { bool x; return x }.
1083 // In this case, the optimized strict equal returns null.
srdjan 2012/08/15 17:49:56 See also TODO(srdjan) above
regis 2012/08/15 22:49:18 I removed my TODO, now that the problem is underst
1084
1066 // Remove the constant from the graph. 1085 // Remove the constant from the graph.
1067 right->RemoveFromGraph(); 1086 right->RemoveFromGraph();
1068 // Return left subexpression as the replacement for this instruction. 1087 // Return left subexpression as the replacement for this instruction.
1069 return left; 1088 return left;
1070 } 1089 }
1071 return NULL; 1090 return NULL;
1072 } 1091 }
1073 1092
1074 1093
1075 LocationSummary* StrictCompareComp::MakeLocationSummary() const { 1094 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 if (compiler->is_ssa()) { 1333 if (compiler->is_ssa()) {
1315 ASSERT(locs()->in(0).IsRegister()); 1334 ASSERT(locs()->in(0).IsRegister());
1316 __ PushRegister(locs()->in(0).reg()); 1335 __ PushRegister(locs()->in(0).reg());
1317 } 1336 }
1318 } 1337 }
1319 1338
1320 1339
1321 #undef __ 1340 #undef __
1322 1341
1323 } // namespace dart 1342 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698