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

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

Issue 14872002: Improve load forwarding: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 7 years, 7 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_optimizer.h ('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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 OS::Print("Removing %s\n", current->DebugName()); 295 OS::Print("Removing %s\n", current->DebugName());
296 } else { 296 } else {
297 ASSERT(!current_defn->HasUses()); 297 ASSERT(!current_defn->HasUses());
298 OS::Print("Removing v%"Pd".\n", current_defn->ssa_temp_index()); 298 OS::Print("Removing v%"Pd".\n", current_defn->ssa_temp_index());
299 } 299 }
300 } 300 }
301 iterator->RemoveCurrentFromGraph(); 301 iterator->RemoveCurrentFromGraph();
302 } 302 }
303 303
304 304
305 void FlowGraphOptimizer::Canonicalize() { 305 bool FlowGraphOptimizer::Canonicalize() {
306 bool changed = false;
306 for (intptr_t i = 0; i < block_order_.length(); ++i) { 307 for (intptr_t i = 0; i < block_order_.length(); ++i) {
307 BlockEntryInstr* entry = block_order_[i]; 308 BlockEntryInstr* entry = block_order_[i];
308 entry->Accept(this); 309 entry->Accept(this);
309 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 310 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
310 Instruction* current = it.Current(); 311 Instruction* current = it.Current();
311 Instruction* replacement = current->Canonicalize(this); 312 Instruction* replacement = current->Canonicalize(this);
312 if (replacement != current) { 313 if (replacement != current) {
313 // For non-definitions Canonicalize should return either NULL or 314 // For non-definitions Canonicalize should return either NULL or
314 // this. 315 // this.
315 ASSERT((replacement == NULL) || current->IsDefinition()); 316 ASSERT((replacement == NULL) || current->IsDefinition());
316 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_); 317 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_);
318 changed = true;
317 } 319 }
318 } 320 }
319 } 321 }
322 return changed;
320 } 323 }
321 324
322 325
323 void FlowGraphOptimizer::InsertConversion(Representation from, 326 void FlowGraphOptimizer::InsertConversion(Representation from,
324 Representation to, 327 Representation to,
325 Value* use, 328 Value* use,
326 Instruction* insert_before, 329 Instruction* insert_before,
327 Instruction* deopt_target) { 330 Instruction* deopt_target) {
328 Definition* converted = NULL; 331 Definition* converted = NULL;
329 if ((from == kTagged) && (to == kUnboxedMint)) { 332 if ((from == kTagged) && (to == kUnboxedMint)) {
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 callee_receiver->IsParameter() && 1236 callee_receiver->IsParameter() &&
1234 (callee_receiver->AsParameter()->index() == 0)) { 1237 (callee_receiver->AsParameter()->index() == 0)) {
1235 const String& field_name = 1238 const String& field_name =
1236 String::Handle(Field::NameFromGetter(call->function_name())); 1239 String::Handle(Field::NameFromGetter(call->function_name()));
1237 return CHA::HasOverride(Class::Handle(function.Owner()), field_name); 1240 return CHA::HasOverride(Class::Handle(function.Owner()), field_name);
1238 } 1241 }
1239 return true; 1242 return true;
1240 } 1243 }
1241 1244
1242 1245
1243 void FlowGraphOptimizer::AddToGuardedFields(Field* field) { 1246 void FlowGraphOptimizer::AddToGuardedFields(const Field& field) {
1244 if ((field->guarded_cid() == kDynamicCid) || 1247 if ((field.guarded_cid() == kDynamicCid) ||
1245 (field->guarded_cid() == kIllegalCid)) { 1248 (field.guarded_cid() == kIllegalCid)) {
1246 return; 1249 return;
1247 } 1250 }
1248 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { 1251 for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
1249 if ((*guarded_fields_)[j]->raw() == field->raw()) { 1252 if ((*guarded_fields_)[j]->raw() == field.raw()) {
1250 return; 1253 return;
1251 } 1254 }
1252 } 1255 }
1253 guarded_fields_->Add(field); 1256 guarded_fields_->Add(&field);
1254 } 1257 }
1255 1258
1256 1259
1257 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { 1260 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
1258 ASSERT(call->HasICData()); 1261 ASSERT(call->HasICData());
1259 const ICData& ic_data = *call->ic_data(); 1262 const ICData& ic_data = *call->ic_data();
1260 Function& target = Function::Handle(); 1263 Function& target = Function::Handle();
1261 GrowableArray<intptr_t> class_ids; 1264 GrowableArray<intptr_t> class_ids;
1262 ic_data.GetCheckAt(0, &class_ids, &target); 1265 ic_data.GetCheckAt(0, &class_ids, &target);
1263 ASSERT(class_ids.length() == 1); 1266 ASSERT(class_ids.length() == 1);
1264 // Inline implicit instance getter. 1267 // Inline implicit instance getter.
1265 const String& field_name = 1268 const String& field_name =
1266 String::Handle(Field::NameFromGetter(call->function_name())); 1269 String::Handle(Field::NameFromGetter(call->function_name()));
1267 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); 1270 const Field& field = Field::ZoneHandle(GetField(class_ids[0], field_name));
1268 ASSERT(!field.IsNull()); 1271 ASSERT(!field.IsNull());
1269 1272
1270 if (InstanceCallNeedsClassCheck(call)) { 1273 if (InstanceCallNeedsClassCheck(call)) {
1271 AddReceiverCheck(call); 1274 AddReceiverCheck(call);
1272 } 1275 }
1273 LoadFieldInstr* load = new LoadFieldInstr( 1276 LoadFieldInstr* load = new LoadFieldInstr(
1274 new Value(call->ArgumentAt(0)), 1277 new Value(call->ArgumentAt(0)),
1275 field.Offset(), 1278 field.Offset(),
1276 AbstractType::ZoneHandle(field.type()), 1279 AbstractType::ZoneHandle(field.type()),
1277 field.is_final()); 1280 field.is_final());
1281 load->set_field(&field);
1278 if (field.guarded_cid() != kIllegalCid) { 1282 if (field.guarded_cid() != kIllegalCid) {
1279 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 1283 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
1280 load->set_result_cid(field.guarded_cid()); 1284 load->set_result_cid(field.guarded_cid());
1281 } 1285 }
1282 Field* the_field = &Field::ZoneHandle(field.raw()); 1286 AddToGuardedFields(field);
1283 load->set_field(the_field);
1284 AddToGuardedFields(the_field);
1285 } 1287 }
1286 load->set_field_name(String::Handle(field.name()).ToCString()); 1288 load->set_field_name(String::Handle(field.name()).ToCString());
1287 1289
1288 // Discard the environment from the original instruction because the load 1290 // Discard the environment from the original instruction because the load
1289 // can't deoptimize. 1291 // can't deoptimize.
1290 call->RemoveEnvironment(); 1292 call->RemoveEnvironment();
1291 ReplaceCall(call, load); 1293 ReplaceCall(call, load);
1292 1294
1293 if (load->result_cid() != kDynamicCid) { 1295 if (load->result_cid() != kDynamicCid) {
1294 // Reset value types if guarded_cid was used. 1296 // Reset value types if guarded_cid was used.
(...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 public: 3285 public:
3284 Alias(const Alias& other) : ValueObject(), alias_(other.alias_) { } 3286 Alias(const Alias& other) : ValueObject(), alias_(other.alias_) { }
3285 3287
3286 // All indexed load/stores alias each other. 3288 // All indexed load/stores alias each other.
3287 // TODO(vegorov): incorporate type of array into alias to disambiguate 3289 // TODO(vegorov): incorporate type of array into alias to disambiguate
3288 // different typed data and normal arrays. 3290 // different typed data and normal arrays.
3289 static Alias Indexes() { 3291 static Alias Indexes() {
3290 return Alias(kIndexesAlias); 3292 return Alias(kIndexesAlias);
3291 } 3293 }
3292 3294
3293 // Field load/stores alias each other when field offset matches. 3295 // Field load/stores alias each other only when they access the same field.
3294 // TODO(vegorov): use field information to disambiguate load/stores into 3296 // AliasedSet assigns ids to a combination of instance and field during
3295 // different fields that by accident share offset. 3297 // the optimization phase.
3296 static Alias Field(intptr_t offset_in_bytes) { 3298 static Alias Field(intptr_t id) {
3299 ASSERT(id >= kFirstFieldAlias);
3300 return Alias(id * 2 + 1);
3301 }
3302
3303 // VMField load/stores alias each other when field offset matches.
3304 // TODO(vegorov) storing a context variable does not alias loading array
3305 // length.
3306 static Alias VMField(intptr_t offset_in_bytes) {
3297 const intptr_t idx = offset_in_bytes / kWordSize; 3307 const intptr_t idx = offset_in_bytes / kWordSize;
3298 ASSERT(idx >= kFirstFieldAlias); 3308 ASSERT(idx >= kFirstFieldAlias);
3299 return Alias(idx * 2); 3309 return Alias(idx * 2);
3300 } 3310 }
3301 3311
3302 // Static field load/stores alias each other.
3303 // AliasedSet assigns ids to static fields during optimization phase.
3304 static Alias StaticField(intptr_t id) {
3305 ASSERT(id >= kFirstFieldAlias);
3306 return Alias(id * 2 + 1);
3307 }
3308
3309 // Current context load/stores alias each other. 3312 // Current context load/stores alias each other.
3310 static Alias CurrentContext() { 3313 static Alias CurrentContext() {
3311 return Alias(kCurrentContextAlias); 3314 return Alias(kCurrentContextAlias);
3312 } 3315 }
3313 3316
3314 // Operation does not alias anything. 3317 // Operation does not alias anything.
3315 static Alias None() { 3318 static Alias None() {
3316 return Alias(kNoneAlias); 3319 return Alias(kNoneAlias);
3317 } 3320 }
3318 3321
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 max_field_id_(0) { } 3354 max_field_id_(0) { }
3352 3355
3353 Alias ComputeAliasForLoad(Definition* defn) { 3356 Alias ComputeAliasForLoad(Definition* defn) {
3354 if (defn->IsLoadIndexed()) { 3357 if (defn->IsLoadIndexed()) {
3355 // We are assuming that LoadField is never used to load the first word. 3358 // We are assuming that LoadField is never used to load the first word.
3356 return Alias::Indexes(); 3359 return Alias::Indexes();
3357 } 3360 }
3358 3361
3359 LoadFieldInstr* load_field = defn->AsLoadField(); 3362 LoadFieldInstr* load_field = defn->AsLoadField();
3360 if (load_field != NULL) { 3363 if (load_field != NULL) {
3361 return Alias::Field(load_field->offset_in_bytes()); 3364 if (load_field->field() != NULL) {
3365 Definition* instance = load_field->instance()->definition();
3366 return Alias::Field(GetInstanceFieldId(instance, *load_field->field()));
3367 } else {
3368 return Alias::VMField(load_field->offset_in_bytes());
3369 }
3362 } 3370 }
3363 3371
3364 if (defn->IsCurrentContext()) { 3372 if (defn->IsCurrentContext()) {
3365 return Alias::CurrentContext(); 3373 return Alias::CurrentContext();
3366 } 3374 }
3367 3375
3368 LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField(); 3376 LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField();
3369 if (load_static_field != NULL) { 3377 if (load_static_field != NULL) {
3370 return Alias::StaticField(GetFieldId(load_static_field->field())); 3378 return Alias::Field(GetFieldId(kAnyInstance, load_static_field->field()));
3371 } 3379 }
3372 3380
3373 UNREACHABLE(); 3381 UNREACHABLE();
3374 return Alias::None(); 3382 return Alias::None();
3375 } 3383 }
3376 3384
3377 Alias ComputeAliasForStore(Instruction* instr) { 3385 Alias ComputeAliasForStore(Instruction* instr) {
3378 if (instr->IsStoreIndexed()) { 3386 if (instr->IsStoreIndexed()) {
3379 return Alias::Indexes(); 3387 return Alias::Indexes();
3380 } 3388 }
3381 3389
3382 StoreInstanceFieldInstr* store_instance_field = 3390 StoreInstanceFieldInstr* store_instance_field =
3383 instr->AsStoreInstanceField(); 3391 instr->AsStoreInstanceField();
3384 if (store_instance_field != NULL) { 3392 if (store_instance_field != NULL) {
3385 return Alias::Field(store_instance_field->field().Offset()); 3393 Definition* instance = store_instance_field->instance()->definition();
3394 return Alias::Field(GetInstanceFieldId(instance,
3395 store_instance_field->field()));
3386 } 3396 }
3387 3397
3388 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField(); 3398 StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
3389 if (store_vm_field != NULL) { 3399 if (store_vm_field != NULL) {
3390 return Alias::Field(store_vm_field->offset_in_bytes()); 3400 return Alias::VMField(store_vm_field->offset_in_bytes());
3391 } 3401 }
3392 3402
3393 if (instr->IsStoreContext() || instr->IsChainContext()) { 3403 if (instr->IsStoreContext() || instr->IsChainContext()) {
3394 return Alias::CurrentContext(); 3404 return Alias::CurrentContext();
3395 } 3405 }
3396 3406
3397 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField(); 3407 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
3398 if (store_static_field != NULL) { 3408 if (store_static_field != NULL) {
3399 return Alias::StaticField(GetFieldId(store_static_field->field())); 3409 return Alias::Field(GetStaticFieldId(store_static_field->field()));
3400 } 3410 }
3401 3411
3402 return Alias::None(); 3412 return Alias::None();
3403 } 3413 }
3404 3414
3405 bool Contains(const Alias alias) { 3415 bool Contains(const Alias alias) {
3406 const intptr_t idx = alias.ToIndex(); 3416 const intptr_t idx = alias.ToIndex();
3407 return (idx < sets_.length()) && (sets_[idx] != NULL); 3417 return (idx < sets_.length()) && (sets_[idx] != NULL);
3408 } 3418 }
3409 3419
(...skipping 21 matching lines...) Expand all
3431 3441
3432 private: 3442 private:
3433 const intptr_t max_expr_id_; 3443 const intptr_t max_expr_id_;
3434 3444
3435 // Maps alias index to a set of ssa indexes corresponding to loads with the 3445 // Maps alias index to a set of ssa indexes corresponding to loads with the
3436 // given alias. 3446 // given alias.
3437 GrowableArray<BitVector*> sets_; 3447 GrowableArray<BitVector*> sets_;
3438 3448
3439 // Get id assigned to the given field. Assign a new id if the field is seen 3449 // Get id assigned to the given field. Assign a new id if the field is seen
3440 // for the first time. 3450 // for the first time.
3441 intptr_t GetFieldId(const Field& field) { 3451 intptr_t GetFieldId(intptr_t instance_id, const Field& field) {
3442 intptr_t id = field_ids_.Lookup(&field); 3452 intptr_t id = field_ids_.Lookup(FieldIdPair::Key(instance_id, &field));
3443 if (id == 0) { 3453 if (id == 0) {
3444 id = ++max_field_id_; 3454 id = ++max_field_id_;
3445 field_ids_.Insert(FieldIdPair(&field, id)); 3455 field_ids_.Insert(FieldIdPair(FieldIdPair::Key(instance_id, &field), id));
3446 } 3456 }
3447 return id; 3457 return id;
3448 } 3458 }
3449 3459
3460 enum {
3461 kAnyInstance = -1
3462 };
3463
3464 // Get or create an identifier for an instance field belonging to the
3465 // given instance.
3466 // The space of identifiers assigned to instance fields is split into
3467 // parts based on the instance that contains the field.
3468 // If compiler can prove that instance has a single SSA name in the compiled
3469 // function then we use that SSA name to distinguish fields of this object
3470 // from the same fields in other objects.
3471 // If multiple SSA names can point to the same object then we use
3472 // kAnyInstance instead of a concrete SSA name.
3473 intptr_t GetInstanceFieldId(Definition* defn, const Field& field) {
3474 ASSERT(!field.is_static());
3475
3476 intptr_t instance_id = kAnyInstance;
3477
3478 AllocateObjectInstr* alloc = defn->AsAllocateObject();
3479 if ((alloc != NULL) && !CanBeAliased(alloc)) {
3480 instance_id = alloc->ssa_temp_index();
3481 ASSERT(instance_id != kAnyInstance);
3482 }
3483
3484 return GetFieldId(instance_id, field);
3485 }
3486
3487 // Get or create an identifier for a static field.
3488 intptr_t GetStaticFieldId(const Field& field) {
3489 ASSERT(field.is_static());
3490 return GetFieldId(kAnyInstance, field);
3491 }
3492
3493 // Returns true if the result of AllocateObject can be aliased by some
3494 // other SSA variable and false otherwise. Currently simply checks if
3495 // this value is stored in a field, escapes to another function or
3496 // participates in a phi.
3497 bool CanBeAliased(AllocateObjectInstr* alloc) {
3498 if (alloc->identity() == AllocateObjectInstr::kUnknown) {
3499 bool escapes = false;
3500 for (Value* use = alloc->input_use_list();
3501 use != NULL;
3502 use = use->next_use()) {
3503 Instruction* instr = use->instruction();
3504 if (instr->IsPushArgument() ||
3505 (instr->IsStoreVMField() && (use->use_index() != 0)) ||
3506 (instr->IsStoreInstanceField() && (use->use_index() != 0)) ||
3507 (instr->IsStoreStaticField()) ||
3508 (instr->IsPhi())) {
3509 escapes = true;
3510 break;
3511 }
3512
3513 alloc->set_identity(escapes ? AllocateObjectInstr::kAliased
3514 : AllocateObjectInstr::kNotAliased);
3515 }
3516 }
3517
3518 return alloc->identity() != AllocateObjectInstr::kNotAliased;
3519 }
3520
3450 class FieldIdPair { 3521 class FieldIdPair {
3451 public: 3522 public:
3452 typedef const Field* Key; 3523 struct Key {
3524 Key(intptr_t instance_id, const Field* field)
3525 : instance_id_(instance_id), field_(field) { }
3526
3527 intptr_t instance_id_;
3528 const Field* field_;
3529 };
3530
3453 typedef intptr_t Value; 3531 typedef intptr_t Value;
3454 typedef FieldIdPair Pair; 3532 typedef FieldIdPair Pair;
3455 3533
3456 FieldIdPair(Key key, Value value) : key_(key), value_(value) { } 3534 FieldIdPair(Key key, Value value) : key_(key), value_(value) { }
3457 3535
3458 static Key KeyOf(Pair kv) { 3536 static Key KeyOf(Pair kv) {
3459 return kv.key_; 3537 return kv.key_;
3460 } 3538 }
3461 3539
3462 static Value ValueOf(Pair kv) { 3540 static Value ValueOf(Pair kv) {
3463 return kv.value_; 3541 return kv.value_;
3464 } 3542 }
3465 3543
3466 static intptr_t Hashcode(Key key) { 3544 static intptr_t Hashcode(Key key) {
3467 return String::Handle(key->name()).Hash(); 3545 return String::Handle(key.field_->name()).Hash();
3468 } 3546 }
3469 3547
3470 static inline bool IsKeyEqual(Pair kv, Key key) { 3548 static inline bool IsKeyEqual(Pair kv, Key key) {
3471 return KeyOf(kv)->raw() == key->raw(); 3549 return (KeyOf(kv).field_->raw() == key.field_->raw()) &&
3550 (KeyOf(kv).instance_id_ == key.instance_id_);
3472 } 3551 }
3473 3552
3474 private: 3553 private:
3475 Key key_; 3554 Key key_;
3476 Value value_; 3555 Value value_;
3477 }; 3556 };
3478 3557
3479 // Table mapping static field to their id used during optimization pass. 3558 // Table mapping static field to their id used during optimization pass.
3480 DirectChainedHashMap<FieldIdPair> field_ids_; 3559 DirectChainedHashMap<FieldIdPair> field_ids_;
3481 intptr_t max_field_id_; 3560 intptr_t max_field_id_;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3534 if (key->IsLoadIndexed()) { 3613 if (key->IsLoadIndexed()) {
3535 LoadIndexedInstr* load_indexed = key->AsLoadIndexed(); 3614 LoadIndexedInstr* load_indexed = key->AsLoadIndexed();
3536 object = load_indexed->array()->definition()->ssa_temp_index(); 3615 object = load_indexed->array()->definition()->ssa_temp_index();
3537 location = load_indexed->index()->definition()->ssa_temp_index(); 3616 location = load_indexed->index()->definition()->ssa_temp_index();
3538 } else if (key->IsStoreIndexed()) { 3617 } else if (key->IsStoreIndexed()) {
3539 StoreIndexedInstr* store_indexed = key->AsStoreIndexed(); 3618 StoreIndexedInstr* store_indexed = key->AsStoreIndexed();
3540 object = store_indexed->array()->definition()->ssa_temp_index(); 3619 object = store_indexed->array()->definition()->ssa_temp_index();
3541 location = store_indexed->index()->definition()->ssa_temp_index(); 3620 location = store_indexed->index()->definition()->ssa_temp_index();
3542 } else if (key->IsLoadField()) { 3621 } else if (key->IsLoadField()) {
3543 LoadFieldInstr* load_field = key->AsLoadField(); 3622 LoadFieldInstr* load_field = key->AsLoadField();
3544 object = load_field->value()->definition()->ssa_temp_index(); 3623 object = load_field->instance()->definition()->ssa_temp_index();
3545 location = load_field->offset_in_bytes(); 3624 location = load_field->offset_in_bytes();
3546 } else if (key->IsStoreInstanceField()) { 3625 } else if (key->IsStoreInstanceField()) {
3547 StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField(); 3626 StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
3548 object = store_field->instance()->definition()->ssa_temp_index(); 3627 object = store_field->instance()->definition()->ssa_temp_index();
3549 location = store_field->field().Offset(); 3628 location = store_field->field().Offset();
3550 } else if (key->IsStoreVMField()) { 3629 } else if (key->IsStoreVMField()) {
3551 StoreVMFieldInstr* store_field = key->AsStoreVMField(); 3630 StoreVMFieldInstr* store_field = key->AsStoreVMField();
3552 object = store_field->dest()->definition()->ssa_temp_index(); 3631 object = store_field->dest()->definition()->ssa_temp_index();
3553 location = store_field->offset_in_bytes(); 3632 location = store_field->offset_in_bytes();
3554 } else if (key->IsLoadStaticField()) { 3633 } else if (key->IsLoadStaticField()) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3590 } 3669 }
3591 3670
3592 if (kv->IsCurrentContext()) { 3671 if (kv->IsCurrentContext()) {
3593 return key->IsStoreContext() || key->IsChainContext(); 3672 return key->IsStoreContext() || key->IsChainContext();
3594 } 3673 }
3595 3674
3596 ASSERT(kv->IsLoadField()); 3675 ASSERT(kv->IsLoadField());
3597 LoadFieldInstr* load_field = kv->AsLoadField(); 3676 LoadFieldInstr* load_field = kv->AsLoadField();
3598 if (key->IsStoreVMField()) { 3677 if (key->IsStoreVMField()) {
3599 StoreVMFieldInstr* store_field = key->AsStoreVMField(); 3678 StoreVMFieldInstr* store_field = key->AsStoreVMField();
3600 return load_field->value()->Equals(store_field->dest()) && 3679 return load_field->instance()->Equals(store_field->dest()) &&
3601 (load_field->offset_in_bytes() == store_field->offset_in_bytes()); 3680 (load_field->offset_in_bytes() == store_field->offset_in_bytes());
3602 } else if (key->IsStoreInstanceField()) { 3681 } else if (key->IsStoreInstanceField()) {
3603 StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField(); 3682 StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
3604 return load_field->value()->Equals(store_field->instance()) && 3683 return load_field->instance()->Equals(store_field->instance()) &&
3605 (load_field->offset_in_bytes() == store_field->field().Offset()); 3684 (load_field->offset_in_bytes() == store_field->field().Offset());
3606 } 3685 }
3607 3686
3608 return false; 3687 return false;
3609 } 3688 }
3610 }; 3689 };
3611 3690
3612 3691
3613 static AliasedSet* NumberLoadExpressions( 3692 static AliasedSet* NumberLoadExpressions(
3614 FlowGraph* graph, 3693 FlowGraph* graph,
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4720 } 4799 }
4721 4800
4722 4801
4723 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { 4802 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) {
4724 SetValue(instr, non_constant_); 4803 SetValue(instr, non_constant_);
4725 } 4804 }
4726 4805
4727 4806
4728 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { 4807 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
4729 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && 4808 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
4730 (instr->value()->definition()->IsCreateArray())) { 4809 (instr->instance()->definition()->IsCreateArray())) {
4731 const intptr_t length = 4810 const intptr_t length =
4732 instr->value()->definition()->AsCreateArray()->num_elements(); 4811 instr->instance()->definition()->AsCreateArray()->num_elements();
4733 const Object& result = Smi::ZoneHandle(Smi::New(length)); 4812 const Object& result = Smi::ZoneHandle(Smi::New(length));
4734 SetValue(instr, result); 4813 SetValue(instr, result);
4735 return; 4814 return;
4736 } 4815 }
4737 4816
4738 if (instr->IsImmutableLengthLoad()) { 4817 if (instr->IsImmutableLengthLoad()) {
4739 ConstantInstr* constant = instr->value()->definition()->AsConstant(); 4818 ConstantInstr* constant = instr->instance()->definition()->AsConstant();
4740 if (constant != NULL) { 4819 if (constant != NULL) {
4741 if (constant->value().IsString()) { 4820 if (constant->value().IsString()) {
4742 SetValue(instr, Smi::ZoneHandle( 4821 SetValue(instr, Smi::ZoneHandle(
4743 Smi::New(String::Cast(constant->value()).Length()))); 4822 Smi::New(String::Cast(constant->value()).Length())));
4744 return; 4823 return;
4745 } 4824 }
4746 if (constant->value().IsArray()) { 4825 if (constant->value().IsArray()) {
4747 SetValue(instr, Smi::ZoneHandle( 4826 SetValue(instr, Smi::ZoneHandle(
4748 Smi::New(Array::Cast(constant->value()).Length()))); 4827 Smi::New(Array::Cast(constant->value()).Length())));
4749 return; 4828 return;
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
5672 if (changed) { 5751 if (changed) {
5673 // We may have changed the block order and the dominator tree. 5752 // We may have changed the block order and the dominator tree.
5674 flow_graph->DiscoverBlocks(); 5753 flow_graph->DiscoverBlocks();
5675 GrowableArray<BitVector*> dominance_frontier; 5754 GrowableArray<BitVector*> dominance_frontier;
5676 flow_graph->ComputeDominators(&dominance_frontier); 5755 flow_graph->ComputeDominators(&dominance_frontier);
5677 } 5756 }
5678 } 5757 }
5679 5758
5680 5759
5681 } // namespace dart 5760 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698