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

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

Issue 28633003: Fix bugs in load elimination and type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 4109 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 // Indexed location. 4120 // Indexed location.
4121 kIndexed, 4121 kIndexed,
4122 4122
4123 // Current context. 4123 // Current context.
4124 kContext 4124 kContext
4125 }; 4125 };
4126 4126
4127 Place(const Place& other) 4127 Place(const Place& other)
4128 : ValueObject(), 4128 : ValueObject(),
4129 kind_(other.kind_), 4129 kind_(other.kind_),
4130 representation_(other.representation_),
4130 instance_(other.instance_), 4131 instance_(other.instance_),
4131 raw_selector_(other.raw_selector_), 4132 raw_selector_(other.raw_selector_),
4132 id_(other.id_) { 4133 id_(other.id_) {
4133 } 4134 }
4134 4135
4135 // Construct a place from instruction if instruction accesses any place. 4136 // Construct a place from instruction if instruction accesses any place.
4136 // Otherwise constructs kNone place. 4137 // Otherwise constructs kNone place.
4137 Place(Instruction* instr, bool* is_load) 4138 Place(Instruction* instr, bool* is_load)
4138 : kind_(kNone), instance_(NULL), raw_selector_(0), id_(0) { 4139 : kind_(kNone),
4140 representation_(kNoRepresentation),
4141 instance_(NULL),
4142 raw_selector_(0),
4143 id_(0) {
4139 switch (instr->tag()) { 4144 switch (instr->tag()) {
4140 case Instruction::kLoadField: { 4145 case Instruction::kLoadField: {
4141 LoadFieldInstr* load_field = instr->AsLoadField(); 4146 LoadFieldInstr* load_field = instr->AsLoadField();
4147 representation_ = load_field->representation();
4142 instance_ = OriginalDefinition(load_field->instance()->definition()); 4148 instance_ = OriginalDefinition(load_field->instance()->definition());
4143 if (load_field->field() != NULL) { 4149 if (load_field->field() != NULL) {
4144 kind_ = kField; 4150 kind_ = kField;
4145 field_ = load_field->field(); 4151 field_ = load_field->field();
4146 } else { 4152 } else {
4147 kind_ = kVMField; 4153 kind_ = kVMField;
4148 offset_in_bytes_ = load_field->offset_in_bytes(); 4154 offset_in_bytes_ = load_field->offset_in_bytes();
4149 } 4155 }
4150 *is_load = true; 4156 *is_load = true;
4151 break; 4157 break;
4152 } 4158 }
4153 4159
4154 case Instruction::kStoreInstanceField: { 4160 case Instruction::kStoreInstanceField: {
4155 StoreInstanceFieldInstr* store_instance_field = 4161 StoreInstanceFieldInstr* store_instance_field =
4156 instr->AsStoreInstanceField(); 4162 instr->AsStoreInstanceField();
4157 kind_ = kField; 4163 kind_ = kField;
4164 // Value is at input index 1.
4165 representation_ = store_instance_field->RequiredInputRepresentation(1);
srdjan 2013/10/21 17:42:35 Please factor repeated use of 0, 1 and 2 into cons
4158 instance_ = 4166 instance_ =
4159 OriginalDefinition(store_instance_field->instance()->definition()); 4167 OriginalDefinition(store_instance_field->instance()->definition());
4160 field_ = &store_instance_field->field(); 4168 field_ = &store_instance_field->field();
4161 break; 4169 break;
4162 } 4170 }
4163 4171
4164 case Instruction::kStoreVMField: { 4172 case Instruction::kStoreVMField: {
4165 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField(); 4173 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
4166 kind_ = kVMField; 4174 kind_ = kVMField;
4175 // Value is at input index 0.
4176 representation_ = store_vm_field->RequiredInputRepresentation(0);
4167 instance_ = OriginalDefinition(store_vm_field->dest()->definition()); 4177 instance_ = OriginalDefinition(store_vm_field->dest()->definition());
4168 offset_in_bytes_ = store_vm_field->offset_in_bytes(); 4178 offset_in_bytes_ = store_vm_field->offset_in_bytes();
4169 break; 4179 break;
4170 } 4180 }
4171 4181
4172 case Instruction::kLoadStaticField: 4182 case Instruction::kLoadStaticField:
4173 kind_ = kField; 4183 kind_ = kField;
4184 representation_ = instr->AsLoadStaticField()->representation();
4174 field_ = &instr->AsLoadStaticField()->StaticField(); 4185 field_ = &instr->AsLoadStaticField()->StaticField();
4175 *is_load = true; 4186 *is_load = true;
4176 break; 4187 break;
4177 4188
4178 case Instruction::kStoreStaticField: 4189 case Instruction::kStoreStaticField:
4179 kind_ = kField; 4190 kind_ = kField;
4191 // Value is at input index 0.
4192 representation_ =
4193 instr->AsStoreStaticField()->RequiredInputRepresentation(0);
4180 field_ = &instr->AsStoreStaticField()->field(); 4194 field_ = &instr->AsStoreStaticField()->field();
4181 break; 4195 break;
4182 4196
4183 case Instruction::kLoadIndexed: { 4197 case Instruction::kLoadIndexed: {
4184 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed(); 4198 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed();
4185 kind_ = kIndexed; 4199 kind_ = kIndexed;
4200 representation_ = load_indexed->representation();
4186 instance_ = OriginalDefinition(load_indexed->array()->definition()); 4201 instance_ = OriginalDefinition(load_indexed->array()->definition());
4187 index_ = load_indexed->index()->definition(); 4202 index_ = load_indexed->index()->definition();
4188 *is_load = true; 4203 *is_load = true;
4189 break; 4204 break;
4190 } 4205 }
4191 4206
4192 case Instruction::kStoreIndexed: { 4207 case Instruction::kStoreIndexed: {
4193 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed(); 4208 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
4194 kind_ = kIndexed; 4209 kind_ = kIndexed;
4210 // Value is at input index 2.
4211 representation_ = store_indexed->RequiredInputRepresentation(2);
4195 instance_ = OriginalDefinition(store_indexed->array()->definition()); 4212 instance_ = OriginalDefinition(store_indexed->array()->definition());
4196 index_ = store_indexed->index()->definition(); 4213 index_ = store_indexed->index()->definition();
4197 break; 4214 break;
4198 } 4215 }
4199 4216
4200 case Instruction::kCurrentContext: 4217 case Instruction::kCurrentContext:
4201 kind_ = kContext; 4218 kind_ = kContext;
4219 ASSERT(instr->AsCurrentContext()->representation() == kTagged);
4220 representation_ = kTagged;
4202 *is_load = true; 4221 *is_load = true;
4203 break; 4222 break;
4204 4223
4205 case Instruction::kStoreContext: 4224 case Instruction::kStoreContext:
4206 kind_ = kContext; 4225 kind_ = kContext;
4226 ASSERT(instr->AsStoreContext()->RequiredInputRepresentation(0) ==
4227 kTagged);
4228 representation_ = kTagged;
4207 break; 4229 break;
4208 4230
4209 default: 4231 default:
4210 break; 4232 break;
4211 } 4233 }
4212 } 4234 }
4213 4235
4214 intptr_t id() const { return id_; } 4236 intptr_t id() const { return id_; }
4215 void set_id(intptr_t id) { id_ = id; } 4237 void set_id(intptr_t id) { id_ = id; }
4216 4238
4217 Kind kind() const { return kind_; } 4239 Kind kind() const { return kind_; }
4218 4240
4241 Representation representation() const { return representation_; }
4242
4219 Definition* instance() const { 4243 Definition* instance() const {
4220 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); 4244 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
4221 return instance_; 4245 return instance_;
4222 } 4246 }
4223 4247
4224 void set_instance(Definition* def) { 4248 void set_instance(Definition* def) {
4225 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); 4249 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
4226 instance_ = OriginalDefinition(def); 4250 instance_ = OriginalDefinition(def);
4227 } 4251 }
4228 4252
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4274 UNREACHABLE(); 4298 UNREACHABLE();
4275 return "<?>"; 4299 return "<?>";
4276 } 4300 }
4277 4301
4278 bool IsFinalField() const { 4302 bool IsFinalField() const {
4279 return (kind() == kField) && field().is_final(); 4303 return (kind() == kField) && field().is_final();
4280 } 4304 }
4281 4305
4282 intptr_t Hashcode() const { 4306 intptr_t Hashcode() const {
4283 return (kind_ * 63 + reinterpret_cast<intptr_t>(instance_)) * 31 + 4307 return (kind_ * 63 + reinterpret_cast<intptr_t>(instance_)) * 31 +
4284 FieldHashcode(); 4308 representation_ * 15 + FieldHashcode();
4285 } 4309 }
4286 4310
4287 bool Equals(Place* other) const { 4311 bool Equals(Place* other) const {
4288 return (kind_ == other->kind_) && 4312 return (kind_ == other->kind_) &&
4313 (representation_ == other->representation_) &&
4289 (instance_ == other->instance_) && 4314 (instance_ == other->instance_) &&
4290 SameField(other); 4315 SameField(other);
4291 } 4316 }
4292 4317
4293 // Create a zone allocated copy of this place. 4318 // Create a zone allocated copy of this place.
4294 static Place* Wrap(const Place& place); 4319 static Place* Wrap(const Place& place);
4295 4320
4296 private: 4321 private:
4297 static Definition* OriginalDefinition(Definition* defn) { 4322 static Definition* OriginalDefinition(Definition* defn) {
4298 while (defn->IsRedefinition()) { 4323 while (defn->IsRedefinition()) {
4299 defn = defn->AsRedefinition()->value()->definition(); 4324 defn = defn->AsRedefinition()->value()->definition();
4300 } 4325 }
4301 return defn; 4326 return defn;
4302 } 4327 }
4303 4328
4304 bool SameField(Place* other) const { 4329 bool SameField(Place* other) const {
4305 return (kind_ == kField) ? (field().raw() == other->field().raw()) 4330 return (kind_ == kField) ? (field().raw() == other->field().raw())
4306 : (offset_in_bytes_ == other->offset_in_bytes_); 4331 : (offset_in_bytes_ == other->offset_in_bytes_);
4307 } 4332 }
4308 4333
4309 intptr_t FieldHashcode() const { 4334 intptr_t FieldHashcode() const {
4310 return (kind_ == kField) ? reinterpret_cast<intptr_t>(field().raw()) 4335 return (kind_ == kField) ? reinterpret_cast<intptr_t>(field().raw())
4311 : offset_in_bytes_; 4336 : offset_in_bytes_;
4312 } 4337 }
4313 4338
4314 Kind kind_; 4339 Kind kind_;
4340 Representation representation_;
4315 Definition* instance_; 4341 Definition* instance_;
4316 union { 4342 union {
4317 intptr_t raw_selector_; 4343 intptr_t raw_selector_;
4318 const Field* field_; 4344 const Field* field_;
4319 intptr_t offset_in_bytes_; 4345 intptr_t offset_in_bytes_;
4320 Definition* index_; 4346 Definition* index_;
4321 }; 4347 };
4322 4348
4323 intptr_t id_; 4349 intptr_t id_;
4324 }; 4350 };
(...skipping 3407 matching lines...) Expand 10 before | Expand all | Expand 10 after
7732 } 7758 }
7733 7759
7734 // Insert materializations at environment uses. 7760 // Insert materializations at environment uses.
7735 for (intptr_t i = 0; i < exits.length(); i++) { 7761 for (intptr_t i = 0; i < exits.length(); i++) {
7736 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7762 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7737 } 7763 }
7738 } 7764 }
7739 7765
7740 7766
7741 } // namespace dart 7767 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698