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

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

Issue 179443004: VM: Replace StoreVMField with StoreInstanceField. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/vm/flow_graph_inliner.cc ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 const String& field_name = 2209 const String& field_name =
2210 String::Handle(Field::NameFromGetter(call->function_name())); 2210 String::Handle(Field::NameFromGetter(call->function_name()));
2211 const Field& field = Field::ZoneHandle(GetField(class_ids[0], field_name)); 2211 const Field& field = Field::ZoneHandle(GetField(class_ids[0], field_name));
2212 ASSERT(!field.IsNull()); 2212 ASSERT(!field.IsNull());
2213 2213
2214 if (InstanceCallNeedsClassCheck(call)) { 2214 if (InstanceCallNeedsClassCheck(call)) {
2215 AddReceiverCheck(call); 2215 AddReceiverCheck(call);
2216 } 2216 }
2217 LoadFieldInstr* load = new LoadFieldInstr( 2217 LoadFieldInstr* load = new LoadFieldInstr(
2218 new Value(call->ArgumentAt(0)), 2218 new Value(call->ArgumentAt(0)),
2219 field.Offset(), 2219 &field,
2220 AbstractType::ZoneHandle(field.type()), 2220 AbstractType::ZoneHandle(field.type()),
2221 field.is_final()); 2221 field.is_final());
2222 load->set_field(&field);
2223 if (field.guarded_cid() != kIllegalCid) { 2222 if (field.guarded_cid() != kIllegalCid) {
2224 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 2223 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
2225 load->set_result_cid(field.guarded_cid()); 2224 load->set_result_cid(field.guarded_cid());
2226 } 2225 }
2227 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field); 2226 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
2228 } 2227 }
2229 2228
2230 // Discard the environment from the original instruction because the load 2229 // Discard the environment from the original instruction because the load
2231 // can't deoptimize. 2230 // can't deoptimize.
2232 call->RemoveEnvironment(); 2231 call->RemoveEnvironment();
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2685 ic_data.GetCheckAt(0, &class_ids, &target); 2684 ic_data.GetCheckAt(0, &class_ids, &target);
2686 MethodRecognizer::Kind recognized_kind = 2685 MethodRecognizer::Kind recognized_kind =
2687 MethodRecognizer::RecognizeKind(target); 2686 MethodRecognizer::RecognizeKind(target);
2688 2687
2689 if ((recognized_kind == MethodRecognizer::kGrowableArraySetData) && 2688 if ((recognized_kind == MethodRecognizer::kGrowableArraySetData) &&
2690 (ic_data.NumberOfChecks() == 1) && 2689 (ic_data.NumberOfChecks() == 1) &&
2691 (class_ids[0] == kGrowableObjectArrayCid)) { 2690 (class_ids[0] == kGrowableObjectArrayCid)) {
2692 // This is an internal method, no need to check argument types. 2691 // This is an internal method, no need to check argument types.
2693 Definition* array = call->ArgumentAt(0); 2692 Definition* array = call->ArgumentAt(0);
2694 Definition* value = call->ArgumentAt(1); 2693 Definition* value = call->ArgumentAt(1);
2695 StoreVMFieldInstr* store = new StoreVMFieldInstr( 2694 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr(
2695 GrowableObjectArray::data_offset(),
2696 new Value(array), 2696 new Value(array),
2697 GrowableObjectArray::data_offset(),
2698 new Value(value), 2697 new Value(value),
2699 Type::ZoneHandle()); 2698 kEmitStoreBarrier);
2700 ReplaceCall(call, store); 2699 ReplaceCall(call, store);
2701 return true; 2700 return true;
2702 } 2701 }
2703 2702
2704 if ((recognized_kind == MethodRecognizer::kGrowableArraySetLength) && 2703 if ((recognized_kind == MethodRecognizer::kGrowableArraySetLength) &&
2705 (ic_data.NumberOfChecks() == 1) && 2704 (ic_data.NumberOfChecks() == 1) &&
2706 (class_ids[0] == kGrowableObjectArrayCid)) { 2705 (class_ids[0] == kGrowableObjectArrayCid)) {
2707 // This is an internal method, no need to check argument types nor 2706 // This is an internal method, no need to check argument types nor
2708 // range. 2707 // range.
2709 Definition* array = call->ArgumentAt(0); 2708 Definition* array = call->ArgumentAt(0);
2710 Definition* value = call->ArgumentAt(1); 2709 Definition* value = call->ArgumentAt(1);
2711 StoreVMFieldInstr* store = new StoreVMFieldInstr( 2710 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr(
2711 GrowableObjectArray::length_offset(),
2712 new Value(array), 2712 new Value(array),
2713 GrowableObjectArray::length_offset(),
2714 new Value(value), 2713 new Value(value),
2715 Type::ZoneHandle()); 2714 kEmitStoreBarrier);
2716 ReplaceCall(call, store); 2715 ReplaceCall(call, store);
2717 return true; 2716 return true;
2718 } 2717 }
2719 2718
2720 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) || 2719 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
2721 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) && 2720 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
2722 (ic_data.NumberOfChecks() == 1) && 2721 (ic_data.NumberOfChecks() == 1) &&
2723 ((class_ids[0] == kOneByteStringCid) || 2722 ((class_ids[0] == kOneByteStringCid) ||
2724 (class_ids[0] == kTwoByteStringCid))) { 2723 (class_ids[0] == kTwoByteStringCid))) {
2725 return TryReplaceInstanceCallWithInline(call); 2724 return TryReplaceInstanceCallWithInline(call);
(...skipping 2230 matching lines...) Expand 10 before | Expand all | Expand 10 after
4956 field_ = load_field->field(); 4955 field_ = load_field->field();
4957 } else { 4956 } else {
4958 kind_ = kVMField; 4957 kind_ = kVMField;
4959 offset_in_bytes_ = load_field->offset_in_bytes(); 4958 offset_in_bytes_ = load_field->offset_in_bytes();
4960 } 4959 }
4961 *is_load = true; 4960 *is_load = true;
4962 break; 4961 break;
4963 } 4962 }
4964 4963
4965 case Instruction::kStoreInstanceField: { 4964 case Instruction::kStoreInstanceField: {
4966 StoreInstanceFieldInstr* store_instance_field = 4965 StoreInstanceFieldInstr* store =
4967 instr->AsStoreInstanceField(); 4966 instr->AsStoreInstanceField();
4968 kind_ = kField; 4967 representation_ = store->RequiredInputRepresentation(
4969 representation_ = store_instance_field-> 4968 StoreInstanceFieldInstr::kValuePos);
4970 RequiredInputRepresentation(StoreInstanceFieldInstr::kValuePos); 4969 instance_ = OriginalDefinition(store->instance()->definition());
4971 instance_ = 4970 if (!store->field().IsNull()) {
4972 OriginalDefinition(store_instance_field->instance()->definition()); 4971 kind_ = kField;
4973 field_ = &store_instance_field->field(); 4972 field_ = &store->field();
4974 break; 4973 } else {
4975 } 4974 kind_ = kVMField;
4976 4975 offset_in_bytes_ = store->offset_in_bytes();
4977 case Instruction::kStoreVMField: { 4976 }
4978 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
4979 kind_ = kVMField;
4980 representation_ = store_vm_field->
4981 RequiredInputRepresentation(StoreVMFieldInstr::kValuePos);
4982 instance_ = OriginalDefinition(store_vm_field->dest()->definition());
4983 offset_in_bytes_ = store_vm_field->offset_in_bytes();
4984 break; 4977 break;
4985 } 4978 }
4986 4979
4987 case Instruction::kLoadStaticField: 4980 case Instruction::kLoadStaticField:
4988 kind_ = kField; 4981 kind_ = kField;
4989 representation_ = instr->AsLoadStaticField()->representation(); 4982 representation_ = instr->AsLoadStaticField()->representation();
4990 field_ = &instr->AsLoadStaticField()->StaticField(); 4983 field_ = &instr->AsLoadStaticField()->StaticField();
4991 *is_load = true; 4984 *is_load = true;
4992 break; 4985 break;
4993 4986
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
5258 return Alias::ConstantIndex(GetIndexId(Smi::Cast(index).Value())); 5251 return Alias::ConstantIndex(GetIndexId(Smi::Cast(index).Value()));
5259 } 5252 }
5260 } 5253 }
5261 return Alias::Indexes(); 5254 return Alias::Indexes();
5262 } 5255 }
5263 5256
5264 StoreInstanceFieldInstr* store_instance_field = 5257 StoreInstanceFieldInstr* store_instance_field =
5265 instr->AsStoreInstanceField(); 5258 instr->AsStoreInstanceField();
5266 if (store_instance_field != NULL) { 5259 if (store_instance_field != NULL) {
5267 Definition* instance = store_instance_field->instance()->definition(); 5260 Definition* instance = store_instance_field->instance()->definition();
5268 return Alias::Field(GetInstanceFieldId(instance, 5261 if (!store_instance_field->field().IsNull()) {
5269 store_instance_field->field())); 5262 return Alias::Field(GetInstanceFieldId(instance,
5270 } 5263 store_instance_field->field()));
5271 5264 }
5272 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField(); 5265 return Alias::VMField(store_instance_field->offset_in_bytes());
5273 if (store_vm_field != NULL) {
5274 return Alias::VMField(store_vm_field->offset_in_bytes());
5275 } 5266 }
5276 5267
5277 if (instr->IsStoreContext()) { 5268 if (instr->IsStoreContext()) {
5278 return Alias::CurrentContext(); 5269 return Alias::CurrentContext();
5279 } 5270 }
5280 5271
5281 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField(); 5272 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
5282 if (store_static_field != NULL) { 5273 if (store_static_field != NULL) {
5283 return Alias::Field(GetStaticFieldId(store_static_field->field())); 5274 return Alias::Field(GetStaticFieldId(store_static_field->field()));
5284 } 5275 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
5368 // this value is stored in a field, escapes to another function or 5359 // this value is stored in a field, escapes to another function or
5369 // participates in a phi. 5360 // participates in a phi.
5370 static bool CanBeAliased(AllocateObjectInstr* alloc) { 5361 static bool CanBeAliased(AllocateObjectInstr* alloc) {
5371 if (alloc->identity() == AllocateObjectInstr::kUnknown) { 5362 if (alloc->identity() == AllocateObjectInstr::kUnknown) {
5372 bool escapes = false; 5363 bool escapes = false;
5373 for (Value* use = alloc->input_use_list(); 5364 for (Value* use = alloc->input_use_list();
5374 use != NULL; 5365 use != NULL;
5375 use = use->next_use()) { 5366 use = use->next_use()) {
5376 Instruction* instr = use->instruction(); 5367 Instruction* instr = use->instruction();
5377 if (instr->IsPushArgument() || 5368 if (instr->IsPushArgument() ||
5378 (instr->IsStoreVMField()
5379 && (use->use_index() != StoreVMFieldInstr::kObjectPos)) ||
5380 (instr->IsStoreInstanceField() 5369 (instr->IsStoreInstanceField()
5381 && (use->use_index() != StoreInstanceFieldInstr::kInstancePos)) || 5370 && (use->use_index() != StoreInstanceFieldInstr::kInstancePos)) ||
5382 instr->IsStoreStaticField() || 5371 instr->IsStoreStaticField() ||
5383 instr->IsPhi() || 5372 instr->IsPhi() ||
5384 instr->IsAssertAssignable() || 5373 instr->IsAssertAssignable() ||
5385 instr->IsRedefinition()) { 5374 instr->IsRedefinition()) {
5386 escapes = true; 5375 escapes = true;
5387 break; 5376 break;
5388 } 5377 }
5389 } 5378 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
5570 static Definition* GetStoredValue(Instruction* instr) { 5559 static Definition* GetStoredValue(Instruction* instr) {
5571 if (instr->IsStoreIndexed()) { 5560 if (instr->IsStoreIndexed()) {
5572 return instr->AsStoreIndexed()->value()->definition(); 5561 return instr->AsStoreIndexed()->value()->definition();
5573 } 5562 }
5574 5563
5575 StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField(); 5564 StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField();
5576 if (store_instance_field != NULL) { 5565 if (store_instance_field != NULL) {
5577 return store_instance_field->value()->definition(); 5566 return store_instance_field->value()->definition();
5578 } 5567 }
5579 5568
5580 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
5581 if (store_vm_field != NULL) {
5582 return store_vm_field->value()->definition();
5583 }
5584
5585 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField(); 5569 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
5586 if (store_static_field != NULL) { 5570 if (store_static_field != NULL) {
5587 return store_static_field->value()->definition(); 5571 return store_static_field->value()->definition();
5588 } 5572 }
5589 5573
5590 if (instr->IsStoreContext()) { 5574 if (instr->IsStoreContext()) {
5591 return instr->InputAt(0)->definition(); 5575 return instr->InputAt(0)->definition();
5592 } 5576 }
5593 5577
5594 UNREACHABLE(); // Should only be called for supported store instructions. 5578 UNREACHABLE(); // Should only be called for supported store instructions.
(...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after
7320 SetValue(instr, Smi::ZoneHandle( 7304 SetValue(instr, Smi::ZoneHandle(
7321 Smi::New(Array::Cast(constant->value()).Length()))); 7305 Smi::New(Array::Cast(constant->value()).Length())));
7322 return; 7306 return;
7323 } 7307 }
7324 } 7308 }
7325 } 7309 }
7326 SetValue(instr, non_constant_); 7310 SetValue(instr, non_constant_);
7327 } 7311 }
7328 7312
7329 7313
7330 void ConstantPropagator::VisitStoreVMField(StoreVMFieldInstr* instr) {
7331 SetValue(instr, instr->value()->definition()->constant_value());
7332 }
7333
7334
7335 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { 7314 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
7336 const Object& object = 7315 const Object& object =
7337 instr->instantiator()->definition()->constant_value(); 7316 instr->instantiator()->definition()->constant_value();
7338 if (IsNonConstant(object)) { 7317 if (IsNonConstant(object)) {
7339 SetValue(instr, non_constant_); 7318 SetValue(instr, non_constant_);
7340 return; 7319 return;
7341 } 7320 }
7342 if (IsConstant(object)) { 7321 if (IsConstant(object)) {
7343 if (instr->type().IsTypeParameter()) { 7322 if (instr->type().IsTypeParameter()) {
7344 if (object.IsNull()) { 7323 if (object.IsNull()) {
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
7980 // Replace constant-valued instructions without observable side 7959 // Replace constant-valued instructions without observable side
7981 // effects. Do this for smis only to avoid having to copy other 7960 // effects. Do this for smis only to avoid having to copy other
7982 // objects into the heap's old generation. 7961 // objects into the heap's old generation.
7983 if ((defn != NULL) && 7962 if ((defn != NULL) &&
7984 IsConstant(defn->constant_value()) && 7963 IsConstant(defn->constant_value()) &&
7985 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) && 7964 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) &&
7986 !defn->IsConstant() && 7965 !defn->IsConstant() &&
7987 !defn->IsPushArgument() && 7966 !defn->IsPushArgument() &&
7988 !defn->IsStoreIndexed() && 7967 !defn->IsStoreIndexed() &&
7989 !defn->IsStoreInstanceField() && 7968 !defn->IsStoreInstanceField() &&
7990 !defn->IsStoreStaticField() && 7969 !defn->IsStoreStaticField()) {
7991 !defn->IsStoreVMField()) {
7992 if (FLAG_trace_constant_propagation) { 7970 if (FLAG_trace_constant_propagation) {
7993 OS::Print("Constant v%" Pd " = %s\n", 7971 OS::Print("Constant v%" Pd " = %s\n",
7994 defn->ssa_temp_index(), 7972 defn->ssa_temp_index(),
7995 defn->constant_value().ToCString()); 7973 defn->constant_value().ToCString());
7996 } 7974 }
7997 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); 7975 ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
7998 defn->ReplaceUsesWith(constant); 7976 defn->ReplaceUsesWith(constant);
7999 i.RemoveCurrentFromGraph(); 7977 i.RemoveCurrentFromGraph();
8000 } 7978 }
8001 } 7979 }
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
8571 AllocateObjectInstr* alloc, 8549 AllocateObjectInstr* alloc,
8572 const Class& cls, 8550 const Class& cls,
8573 const ZoneGrowableArray<const Field*>& fields) { 8551 const ZoneGrowableArray<const Field*>& fields) {
8574 ZoneGrowableArray<Value*>* values = 8552 ZoneGrowableArray<Value*>* values =
8575 new ZoneGrowableArray<Value*>(fields.length()); 8553 new ZoneGrowableArray<Value*>(fields.length());
8576 8554
8577 // Insert load instruction for every field. 8555 // Insert load instruction for every field.
8578 for (intptr_t i = 0; i < fields.length(); i++) { 8556 for (intptr_t i = 0; i < fields.length(); i++) {
8579 const Field* field = fields[i]; 8557 const Field* field = fields[i];
8580 LoadFieldInstr* load = new LoadFieldInstr(new Value(alloc), 8558 LoadFieldInstr* load = new LoadFieldInstr(new Value(alloc),
8581 field->Offset(), 8559 field,
8582 AbstractType::ZoneHandle()); 8560 AbstractType::ZoneHandle());
8583 load->set_field(field);
8584 flow_graph_->InsertBefore( 8561 flow_graph_->InsertBefore(
8585 exit, load, NULL, Definition::kValue); 8562 exit, load, NULL, Definition::kValue);
8586 values->Add(new Value(load)); 8563 values->Add(new Value(load));
8587 } 8564 }
8588 8565
8589 MaterializeObjectInstr* mat = new MaterializeObjectInstr(cls, fields, values); 8566 MaterializeObjectInstr* mat = new MaterializeObjectInstr(cls, fields, values);
8590 flow_graph_->InsertBefore(exit, mat, NULL, Definition::kValue); 8567 flow_graph_->InsertBefore(exit, mat, NULL, Definition::kValue);
8591 8568
8592 // Replace all mentions of this allocation with a newly inserted 8569 // Replace all mentions of this allocation with a newly inserted
8593 // MaterializeObject instruction. 8570 // MaterializeObject instruction.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
8645 } 8622 }
8646 8623
8647 // Insert materializations at environment uses. 8624 // Insert materializations at environment uses.
8648 for (intptr_t i = 0; i < exits.length(); i++) { 8625 for (intptr_t i = 0; i < exits.length(); i++) {
8649 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8626 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8650 } 8627 }
8651 } 8628 }
8652 8629
8653 8630
8654 } // namespace dart 8631 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.cc ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698