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

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

Issue 16844011: Revert r23330 and r23136 because of a bug with loop invariant code motion. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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/object.h » ('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 3414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3425 3425
3426 3426
3427 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { 3427 LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) {
3428 ASSERT(flow_graph->is_licm_allowed()); 3428 ASSERT(flow_graph->is_licm_allowed());
3429 } 3429 }
3430 3430
3431 3431
3432 void LICM::Hoist(ForwardInstructionIterator* it, 3432 void LICM::Hoist(ForwardInstructionIterator* it,
3433 BlockEntryInstr* pre_header, 3433 BlockEntryInstr* pre_header,
3434 Instruction* current) { 3434 Instruction* current) {
3435 // TODO(fschneider): Avoid repeated deoptimization when
3436 // speculatively hoisting checks.
3435 if (FLAG_trace_optimization) { 3437 if (FLAG_trace_optimization) {
3436 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", 3438 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n",
3437 current->DebugName(), 3439 current->DebugName(),
3438 current->GetDeoptId(), 3440 current->GetDeoptId(),
3439 current->GetBlock()->block_id(), 3441 current->GetBlock()->block_id(),
3440 pre_header->block_id()); 3442 pre_header->block_id());
3441 } 3443 }
3442 // Move the instruction out of the loop. 3444 // Move the instruction out of the loop.
3443 current->RemoveEnvironment(); 3445 current->RemoveEnvironment();
3444 it->RemoveCurrentFromGraph(); 3446 it->RemoveCurrentFromGraph();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3480 } 3482 }
3481 } 3483 }
3482 } 3484 }
3483 3485
3484 if ((non_smi_input == kNotFound) || 3486 if ((non_smi_input == kNotFound) ||
3485 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) { 3487 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) {
3486 return; 3488 return;
3487 } 3489 }
3488 3490
3489 // Host CheckSmi instruction and make this phi smi one. 3491 // Host CheckSmi instruction and make this phi smi one.
3490 if (MayHoist(current, pre_header)) Hoist(it, pre_header, current); 3492 Hoist(it, pre_header, current);
3491 3493
3492 // Replace value we are checking with phi's input. 3494 // Replace value we are checking with phi's input.
3493 current->value()->BindTo(phi->InputAt(non_smi_input)->definition()); 3495 current->value()->BindTo(phi->InputAt(non_smi_input)->definition());
3494 3496
3495 phi->UpdateType(CompileType::FromCid(kSmiCid)); 3497 phi->UpdateType(CompileType::FromCid(kSmiCid));
3496 } 3498 }
3497 3499
3498 3500
3499 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets, 3501 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets,
3500 intptr_t loop_header_index, 3502 intptr_t loop_header_index,
3501 Instruction* instr) { 3503 Instruction* instr) {
3502 return (sets != NULL) && 3504 return (sets != NULL) &&
3503 instr->HasExprId() && 3505 instr->HasExprId() &&
3504 ((*sets)[loop_header_index] != NULL) && 3506 ((*sets)[loop_header_index] != NULL) &&
3505 (*sets)[loop_header_index]->Contains(instr->expr_id()); 3507 (*sets)[loop_header_index]->Contains(instr->expr_id());
3506 } 3508 }
3507 3509
3508 3510
3509 bool LICM::MayHoist(Instruction* instr, BlockEntryInstr* pre_header) {
3510 // TODO(fschneider): Enable hoisting of Assert-instructions
3511 // if it safe to do.
3512 if (instr->IsAssertAssignable()) return false;
3513 if (instr->IsAssertBoolean()) return false;
3514
3515 if (instr->CanDeoptimize()) {
3516 intptr_t target_deopt_id =
3517 pre_header->last_instruction()->AsGoto()->GetDeoptId();
3518 const Function& function = flow_graph_->parsed_function().function();
3519 const Array& deopt_history = Array::Handle(function.deopt_history());
3520 if (deopt_history.IsNull()) return true;
3521
3522 Smi& deopt_id = Smi::Handle();
3523 for (intptr_t i = 0; i < deopt_history.Length(); ++i) {
3524 deopt_id ^= deopt_history.At(i);
3525 if (!deopt_id.IsNull() && (deopt_id.Value() == target_deopt_id)) {
3526 return false;
3527 }
3528 }
3529 }
3530 return true;
3531 }
3532
3533
3534 void LICM::Optimize() { 3511 void LICM::Optimize() {
3535 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = 3512 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers =
3536 flow_graph()->loop_headers(); 3513 flow_graph()->loop_headers();
3537 3514
3538 ZoneGrowableArray<BitVector*>* loop_invariant_loads = 3515 ZoneGrowableArray<BitVector*>* loop_invariant_loads =
3539 flow_graph()->loop_invariant_loads(); 3516 flow_graph()->loop_invariant_loads();
3540 3517
3541 BlockEffects* block_effects = flow_graph()->block_effects(); 3518 BlockEffects* block_effects = flow_graph()->block_effects();
3542 3519
3543 for (intptr_t i = 0; i < loop_headers.length(); ++i) { 3520 for (intptr_t i = 0; i < loop_headers.length(); ++i) {
(...skipping 14 matching lines...) Expand all
3558 block_effects->CanBeMovedTo(current, pre_header)) || 3535 block_effects->CanBeMovedTo(current, pre_header)) ||
3559 IsLoopInvariantLoad(loop_invariant_loads, i, current)) { 3536 IsLoopInvariantLoad(loop_invariant_loads, i, current)) {
3560 bool inputs_loop_invariant = true; 3537 bool inputs_loop_invariant = true;
3561 for (int i = 0; i < current->InputCount(); ++i) { 3538 for (int i = 0; i < current->InputCount(); ++i) {
3562 Definition* input_def = current->InputAt(i)->definition(); 3539 Definition* input_def = current->InputAt(i)->definition();
3563 if (!input_def->GetBlock()->Dominates(pre_header)) { 3540 if (!input_def->GetBlock()->Dominates(pre_header)) {
3564 inputs_loop_invariant = false; 3541 inputs_loop_invariant = false;
3565 break; 3542 break;
3566 } 3543 }
3567 } 3544 }
3568 if (inputs_loop_invariant && MayHoist(current, pre_header)) { 3545 if (inputs_loop_invariant &&
3546 !current->IsAssertAssignable() &&
3547 !current->IsAssertBoolean()) {
3548 // TODO(fschneider): Enable hoisting of Assert-instructions
3549 // if it safe to do.
3569 Hoist(&it, pre_header, current); 3550 Hoist(&it, pre_header, current);
3570 } else if (current->IsCheckSmi() && 3551 } else if (current->IsCheckSmi() &&
3571 current->InputAt(0)->definition()->IsPhi()) { 3552 current->InputAt(0)->definition()->IsPhi()) {
3572 TryHoistCheckSmiThroughPhi( 3553 TryHoistCheckSmiThroughPhi(
3573 &it, header, pre_header, current->AsCheckSmi()); 3554 &it, header, pre_header, current->AsCheckSmi());
3574 } 3555 }
3575 } 3556 }
3576 } 3557 }
3577 } 3558 }
3578 } 3559 }
(...skipping 3010 matching lines...) Expand 10 before | Expand all | Expand 10 after
6589 6570
6590 // Insert materializations at environment uses. 6571 // Insert materializations at environment uses.
6591 const Class& cls = Class::Handle(alloc->constructor().Owner()); 6572 const Class& cls = Class::Handle(alloc->constructor().Owner());
6592 for (intptr_t i = 0; i < exits.length(); i++) { 6573 for (intptr_t i = 0; i < exits.length(); i++) {
6593 CreateMaterializationAt(exits[i], alloc, cls, *fields); 6574 CreateMaterializationAt(exits[i], alloc, cls, *fields);
6594 } 6575 }
6595 } 6576 }
6596 6577
6597 6578
6598 } // namespace dart 6579 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698