Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc |
| index 7b8e997150c84ea4da8d6cf68d74312d98a54121..67f7ea2e147c8f49faf2acc06f290251c0973ceb 100644 |
| --- a/runtime/vm/intermediate_language.cc |
| +++ b/runtime/vm/intermediate_language.cc |
| @@ -377,17 +377,6 @@ void ForwardInstructionIterator::RemoveCurrentFromGraph() { |
| void ForwardInstructionIterator::ReplaceCurrentWith(Definition* other) { |
| - Definition* defn = current_->AsDefinition(); |
|
Vyacheslav Egorov (Google)
2013/02/08 16:44:49
This must come back before you will land it.
Kevin Millikin (Google)
2013/02/19 10:49:30
Thanks, it was an inadvertent deletion.
|
| - ASSERT(defn != NULL); |
| - defn->ReplaceUsesWith(other); |
| - ASSERT(other->env() == NULL); |
| - other->set_env(defn->env()); |
| - defn->set_env(NULL); |
| - ASSERT(!other->HasSSATemp()); |
| - if (defn->HasSSATemp()) other->set_ssa_temp_index(defn->ssa_temp_index()); |
| - |
| - other->InsertBefore(current_); // So other will be current. |
| - RemoveCurrentFromGraph(); |
| } |
| @@ -708,22 +697,42 @@ void Instruction::UnuseAllInputs() { |
| void Definition::ReplaceWith(Definition* other, |
| ForwardInstructionIterator* iterator) { |
| + // Record other's input uses. |
| + for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { |
| + Value* input = other->InputAt(i); |
| + input->definition()->AddInputUse(input); |
| + input->set_instruction(other); |
| + input->set_use_index(i); |
| + } |
| + // Take other's environment from this definition. |
| + ASSERT(other->env() == NULL); |
| + intptr_t use_index = 0; |
| + for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { |
| + Value* use = it.CurrentValue(); |
| + use->set_instruction(other); |
| + use->set_use_index(use_index++); |
| + } |
| + other->set_env(env()); |
| + set_env(NULL); |
| + // Replace all uses of this definition with other. |
| + ReplaceUsesWith(other); |
| + // Reuse this instruction's SSA name for other. |
| + ASSERT(!other->HasSSATemp()); |
| + if (HasSSATemp()) other->set_ssa_temp_index(ssa_temp_index()); |
| + // Remove this definition's input uses. |
| + UnuseAllInputs(); |
| + |
| + // Finally remove this definition from the graph. |
| + previous()->LinkTo(other); |
| if ((iterator != NULL) && (this == iterator->Current())) { |
| - iterator->ReplaceCurrentWith(other); |
| + // Remove through the iterator. |
| + other->LinkTo(this); |
| + iterator->RemoveCurrentFromGraph(); |
| } else { |
| - ReplaceUsesWith(other); |
| - ASSERT(other->env() == NULL); |
| - other->set_env(env()); |
| - set_env(NULL); |
| - ASSERT(!other->HasSSATemp()); |
| - if (HasSSATemp()) other->set_ssa_temp_index(ssa_temp_index()); |
| - |
| - previous()->LinkTo(other); |
| other->LinkTo(next()); |
| - |
| - set_previous(NULL); |
| - set_next(NULL); |
| } |
| + set_previous(NULL); |
| + set_next(NULL); |
| } |
| @@ -1753,7 +1762,7 @@ Definition* LoadFieldInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| if (call != NULL && |
| call->is_known_constructor() && |
| call->ResultCid() == kArrayCid) { |
| - return call->ArgumentAt(1)->value()->definition(); |
| + return call->ArgumentAt(1); |
| } |
| return this; |
| } |
| @@ -1828,6 +1837,7 @@ Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| if ((comp->input_use_list()->instruction() == this) && |
| (comp->input_use_list()->next_use() == NULL) && |
| (comp->env_use_list() == NULL)) { |
| + comparison()->UnuseAllInputs(); |
| comp->RemoveFromGraph(); |
| // It is safe to pass a NULL iterator because we're replacing the |
| // comparison wrapped in a BranchInstr which does not modify the |
| @@ -1840,9 +1850,9 @@ Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| if (FLAG_trace_optimization) { |
| OS::Print("Merging comparison v%"Pd"\n", comp->ssa_temp_index()); |
| } |
| - // Clear the comparison's use list, temp index and ssa temp index since |
| - // the value of the comparison is not used outside the branch anymore. |
| - comp->set_input_use_list(NULL); |
| + // Clear the comparison's temp index and ssa temp index since the |
| + // value of the comparison is not used outside the branch anymore. |
| + ASSERT(comp->input_use_list() == NULL); |
| comp->ClearSSATempIndex(); |
| comp->ClearTempIndex(); |
| } |