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

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

Issue 15779006: Add deoptimization history to optimized functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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
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 3397 matching lines...) Expand 10 before | Expand all | Expand 10 after
3408 3408
3409 3409
3410 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { 3410 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) {
3411 ASSERT(flow_graph->is_licm_allowed()); 3411 ASSERT(flow_graph->is_licm_allowed());
3412 } 3412 }
3413 3413
3414 3414
3415 void LICM::Hoist(ForwardInstructionIterator* it, 3415 void LICM::Hoist(ForwardInstructionIterator* it,
3416 BlockEntryInstr* pre_header, 3416 BlockEntryInstr* pre_header,
3417 Instruction* current) { 3417 Instruction* current) {
3418 // TODO(fschneider): Avoid repeated deoptimization when
3419 // speculatively hoisting checks.
3420 if (FLAG_trace_optimization) { 3418 if (FLAG_trace_optimization) {
3421 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", 3419 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n",
3422 current->DebugName(), 3420 current->DebugName(),
3423 current->GetDeoptId(), 3421 current->GetDeoptId(),
3424 current->GetBlock()->block_id(), 3422 current->GetBlock()->block_id(),
3425 pre_header->block_id()); 3423 pre_header->block_id());
3426 } 3424 }
3427 // Move the instruction out of the loop. 3425 // Move the instruction out of the loop.
3428 current->RemoveEnvironment(); 3426 current->RemoveEnvironment();
3429 it->RemoveCurrentFromGraph(); 3427 it->RemoveCurrentFromGraph();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3465 } 3463 }
3466 } 3464 }
3467 } 3465 }
3468 3466
3469 if ((non_smi_input == kNotFound) || 3467 if ((non_smi_input == kNotFound) ||
3470 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) { 3468 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) {
3471 return; 3469 return;
3472 } 3470 }
3473 3471
3474 // Host CheckSmi instruction and make this phi smi one. 3472 // Host CheckSmi instruction and make this phi smi one.
3475 Hoist(it, pre_header, current); 3473 if (MayHoist(current, pre_header)) Hoist(it, pre_header, current);
3476 3474
3477 // Replace value we are checking with phi's input. 3475 // Replace value we are checking with phi's input.
3478 current->value()->BindTo(phi->InputAt(non_smi_input)->definition()); 3476 current->value()->BindTo(phi->InputAt(non_smi_input)->definition());
3479 3477
3480 phi->UpdateType(CompileType::FromCid(kSmiCid)); 3478 phi->UpdateType(CompileType::FromCid(kSmiCid));
3481 } 3479 }
3482 3480
3483 3481
3484 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets, 3482 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets,
3485 intptr_t loop_header_index, 3483 intptr_t loop_header_index,
3486 Instruction* instr) { 3484 Instruction* instr) {
3487 return (sets != NULL) && 3485 return (sets != NULL) &&
3488 instr->HasExprId() && 3486 instr->HasExprId() &&
3489 ((*sets)[loop_header_index] != NULL) && 3487 ((*sets)[loop_header_index] != NULL) &&
3490 (*sets)[loop_header_index]->Contains(instr->expr_id()); 3488 (*sets)[loop_header_index]->Contains(instr->expr_id());
3491 } 3489 }
3492 3490
3493 3491
3492 bool LICM::MayHoist(Instruction* instr, BlockEntryInstr* pre_header) {
3493 // TODO(fschneider): Enable hoisting of Assert-instructions
3494 // if it safe to do.
3495 if (instr->IsAssertAssignable()) return false;
3496 if (instr->IsAssertBoolean()) return false;
3497
3498 if (instr->CanDeoptimize()) {
3499 intptr_t target_deopt_id =
3500 pre_header->last_instruction()->AsGoto()->GetDeoptId();
3501 const Function& function = flow_graph_->parsed_function().function();
3502 const Array& deopt_history = Array::Handle(function.deopt_history());
3503 if (deopt_history.IsNull()) return true;
3504
3505 Smi& deopt_id = Smi::Handle();
3506 for (intptr_t i = 0; i < deopt_history.Length(); ++i) {
3507 deopt_id ^= deopt_history.At(i);
3508 if (!deopt_id.IsNull() && (deopt_id.Value() == target_deopt_id)) {
3509 return false;
3510 }
3511 }
3512 }
3513 return true;
3514 }
3515
3516
3494 void LICM::Optimize() { 3517 void LICM::Optimize() {
3495 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = 3518 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers =
3496 flow_graph()->loop_headers(); 3519 flow_graph()->loop_headers();
3497 3520
3498 ZoneGrowableArray<BitVector*>* loop_invariant_loads = 3521 ZoneGrowableArray<BitVector*>* loop_invariant_loads =
3499 flow_graph()->loop_invariant_loads(); 3522 flow_graph()->loop_invariant_loads();
3500 3523
3501 BlockEffects* block_effects = flow_graph()->block_effects(); 3524 BlockEffects* block_effects = flow_graph()->block_effects();
3502 3525
3503 for (intptr_t i = 0; i < loop_headers.length(); ++i) { 3526 for (intptr_t i = 0; i < loop_headers.length(); ++i) {
(...skipping 14 matching lines...) Expand all
3518 block_effects->CanBeMovedTo(current, pre_header)) || 3541 block_effects->CanBeMovedTo(current, pre_header)) ||
3519 IsLoopInvariantLoad(loop_invariant_loads, i, current)) { 3542 IsLoopInvariantLoad(loop_invariant_loads, i, current)) {
3520 bool inputs_loop_invariant = true; 3543 bool inputs_loop_invariant = true;
3521 for (int i = 0; i < current->InputCount(); ++i) { 3544 for (int i = 0; i < current->InputCount(); ++i) {
3522 Definition* input_def = current->InputAt(i)->definition(); 3545 Definition* input_def = current->InputAt(i)->definition();
3523 if (!input_def->GetBlock()->Dominates(pre_header)) { 3546 if (!input_def->GetBlock()->Dominates(pre_header)) {
3524 inputs_loop_invariant = false; 3547 inputs_loop_invariant = false;
3525 break; 3548 break;
3526 } 3549 }
3527 } 3550 }
3528 if (inputs_loop_invariant && 3551 if (inputs_loop_invariant && MayHoist(current, pre_header)) {
3529 !current->IsAssertAssignable() &&
3530 !current->IsAssertBoolean()) {
3531 // TODO(fschneider): Enable hoisting of Assert-instructions
3532 // if it safe to do.
3533 Hoist(&it, pre_header, current); 3552 Hoist(&it, pre_header, current);
3534 } else if (current->IsCheckSmi() && 3553 } else if (current->IsCheckSmi() &&
3535 current->InputAt(0)->definition()->IsPhi()) { 3554 current->InputAt(0)->definition()->IsPhi()) {
3536 TryHoistCheckSmiThroughPhi( 3555 TryHoistCheckSmiThroughPhi(
3537 &it, header, pre_header, current->AsCheckSmi()); 3556 &it, header, pre_header, current->AsCheckSmi());
3538 } 3557 }
3539 } 3558 }
3540 } 3559 }
3541 } 3560 }
3542 } 3561 }
(...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after
6511 6530
6512 // Insert materializations at environment uses. 6531 // Insert materializations at environment uses.
6513 const Class& cls = Class::Handle(alloc->constructor().Owner()); 6532 const Class& cls = Class::Handle(alloc->constructor().Owner());
6514 for (intptr_t i = 0; i < exits.length(); i++) { 6533 for (intptr_t i = 0; i < exits.length(); i++) {
6515 CreateMaterializationAt(exits[i], alloc, cls, *fields); 6534 CreateMaterializationAt(exits[i], alloc, cls, *fields);
6516 } 6535 }
6517 } 6536 }
6518 6537
6519 6538
6520 } // namespace dart 6539 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698