Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_optimizer.cc (revision 10694) |
| +++ runtime/vm/flow_graph_optimizer.cc (working copy) |
| @@ -584,9 +584,35 @@ |
| BindInstr* instr) { |
| if (FLAG_eliminate_type_checks && |
| !comp->is_eliminated() && |
| - !comp->dst_type().IsMalformed() && |
| comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) { |
| comp->eliminate(); |
| +#if 0 |
| + UseVal* use = comp->value()->AsUse(); |
| + // TODO(regis): Handle constant input value (not a definition). |
| + if (use != NULL) { |
| + Definition* result = use->definition(); |
| + ASSERT(result != NULL); |
| + // Replace uses and remove the current instructions via the iterator. |
| + instr->ReplaceUsesWith(result); |
| + ASSERT(current_iterator()->Current()->AsBind() == instr); |
| + current_iterator()->RemoveCurrentFromGraph(); |
| + instr->RemoveInputUses(); |
| + if (result->use_list() == NULL) { |
| + // Remove the definition of the input as well, since it has no uses. |
|
Kevin Millikin (Google)
2012/08/15 09:04:25
This is not really safe if it happens, because it
regis
2012/08/15 17:25:27
Thanks! I removed the code removing the unused inp
|
| + current_iterator()->RemoveCurrentFromGraph(); |
| + } |
| + |
| + // TODO(regis): The above instruction removal results in an assert fault: |
|
Kevin Millikin (Google)
2012/08/15 09:04:25
We should just skip this optimization if we're usi
regis
2012/08/15 17:25:27
Done. That takes care of the assert fault.
|
| + // ../runtime/vm/flow_graph_compiler.cc:754: error: expected: |
| + // val->AsUse()->definition() == registers_[src] |
| + |
| + if (FLAG_trace_optimization) { |
| + OS::Print("Replacing v%d with v%d\n", |
| + instr->ssa_temp_index(), |
| + result->ssa_temp_index()); |
| + } |
| + } |
| +#endif |
|
srdjan
2012/08/15 02:07:31
Removed dead code before submitting
regis
2012/08/15 17:25:27
The code is now enabled and working.
|
| if (FLAG_trace_type_check_elimination) { |
| FlowGraphPrinter::PrintTypeCheck(parsed_function(), |
| comp->token_pos(), |
| @@ -603,8 +629,13 @@ |
| BindInstr* instr) { |
| if (FLAG_eliminate_type_checks && |
| !comp->is_eliminated() && |
| + !comp->value()->IsConstantNull() && |
| comp->value()->CompileTypeIsMoreSpecificThan( |
| Type::Handle(Type::BoolInterface()))) { |
| + // TODO(regis): This optimization may not be correct, since a value of |
| + // compile time type bool may still be null at run time. In this case, |
| + // the bool expression will evaluate to false without throwing a dynamic |
| + // type error. |
| comp->eliminate(); |
| if (FLAG_trace_type_check_elimination) { |
| const String& name = String::Handle(Symbols::New("boolean expression")); |
| @@ -619,6 +650,32 @@ |
| } |
| +void FlowGraphTypePropagator::VisitInstanceOf(InstanceOfComp* comp, |
| + BindInstr* instr) { |
| + // We can only eliminate an 'instance of' test when the checked value is |
| + // a constant time constant. Indeed, a variable of the proper compile time |
| + // type may still hold null at run time and therefore fail the test. |
| + // We do not bother checking for Object destination type, since the graph |
| + // builder did already. |
| + if (FLAG_eliminate_type_checks && |
| + comp->value()->IsConstant() && |
| + !comp->value()->IsConstantNull() && |
| + comp->value()->CompileTypeIsMoreSpecificThan(comp->type())) { |
| + // Remove instr from graph and replace uses with use of true or false. |
| + UNIMPLEMENTED(); // TODO(regis): We never encounter this case so far. |
| + if (FLAG_trace_type_check_elimination) { |
| + const String& name = String::Handle(Symbols::New("InstanceOf")); |
| + FlowGraphPrinter::PrintTypeCheck(parsed_function(), |
| + comp->token_pos(), |
| + comp->value(), |
| + comp->type(), |
| + name, |
| + /* eliminated = */ true); |
|
srdjan
2012/08/15 02:07:31
You cannot eliminate instance of using CompileType
regis
2012/08/15 17:25:27
I will be able to remove a non-constant value once
|
| + } |
| + } |
| +} |
| + |
| + |
| void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { |
| if (graph_entry->start_env() == NULL) { |
| return; |
| @@ -654,11 +711,16 @@ |
| // PhiInstr's are handled as part of JoinEntryInstr. |
| // Visit computation and possibly eliminate type check. |
| bind->computation()->Accept(this, bind); |
| - // Cache propagated computation type. |
| - AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); |
| - bool changed = bind->SetPropagatedType(type); |
| - if (changed) { |
| - still_changing_ = true; |
| + // The current bind may have been removed from the graph. |
|
srdjan
2012/08/15 02:07:31
Can this happen, since you are not removing instru
regis
2012/08/15 17:25:27
I am now.
|
| + if (current_iterator()->Current()->AsBind() == bind) { |
| + // Current bind was not removed. |
| + // Cache propagated computation type. |
| + AbstractType& computation_type = |
| + AbstractType::Handle(bind->computation()->CompileType()); |
| + bool changed = bind->SetPropagatedType(computation_type); |
| + if (changed) { |
| + still_changing_ = true; |
| + } |
| } |
| } |