Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_optimizer.cc (revision 23072) |
| +++ runtime/vm/flow_graph_optimizer.cc (working copy) |
| @@ -3415,8 +3415,6 @@ |
| void LICM::Hoist(ForwardInstructionIterator* it, |
| BlockEntryInstr* pre_header, |
| Instruction* current) { |
| - // TODO(fschneider): Avoid repeated deoptimization when |
| - // speculatively hoisting checks. |
| if (FLAG_trace_optimization) { |
| OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", |
| current->DebugName(), |
| @@ -3472,7 +3470,7 @@ |
| } |
| // Host CheckSmi instruction and make this phi smi one. |
| - Hoist(it, pre_header, current); |
| + if (MayHoist(current, pre_header)) Hoist(it, pre_header, current); |
| // Replace value we are checking with phi's input. |
| current->value()->BindTo(phi->InputAt(non_smi_input)->definition()); |
| @@ -3491,6 +3489,31 @@ |
| } |
| +bool LICM::MayHoist(Instruction* instr, BlockEntryInstr* pre_header) { |
| + // TODO(fschneider): Enable hoisting of Assert-instructions |
| + // if it safe to do. |
| + if (instr->IsAssertAssignable()) return false; |
| + if (instr->IsAssertBoolean()) return false; |
| + |
| + if (instr->CanDeoptimize()) { |
| + intptr_t target_deopt_id = |
| + pre_header->last_instruction()->AsGoto()->GetDeoptId(); |
| + const Function& function = flow_graph_->parsed_function().function(); |
| + const Array& deopt_history = Array::Handle(function.deopt_history()); |
| + if (deopt_history.IsNull()) return true; |
| + |
| + for (intptr_t i = 0; i < deopt_history.Length(); ++i) { |
| + const Object& obj = Object::Handle(deopt_history.At(i)); |
| + if (obj.IsNull()) continue; |
|
Kevin Millikin (Google)
2013/05/24 11:39:21
If you just delete this line, I think the result i
Florian Schneider
2013/05/24 11:53:02
Done.
|
| + if (obj.IsSmi() && Smi::Cast(obj).Value() == target_deopt_id) { |
|
Kevin Millikin (Google)
2013/05/24 11:39:21
Can it be non-smi (other than null)? The Smi::Cas
Florian Schneider
2013/05/24 11:53:02
Done.
|
| + return false; |
| + } |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| void LICM::Optimize() { |
| const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| flow_graph()->loop_headers(); |
| @@ -3525,11 +3548,7 @@ |
| break; |
| } |
| } |
| - if (inputs_loop_invariant && |
| - !current->IsAssertAssignable() && |
| - !current->IsAssertBoolean()) { |
| - // TODO(fschneider): Enable hoisting of Assert-instructions |
| - // if it safe to do. |
| + if (inputs_loop_invariant && MayHoist(current, pre_header)) { |
| Hoist(&it, pre_header, current); |
| } else if (current->IsCheckSmi() && |
| current->InputAt(0)->definition()->IsPhi()) { |