Index: runtime/vm/flow_graph.cc |
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc |
index 599fce04311de948c0aa5ab34877a8cc61bdb6b5..5754db5811a9f88ad1c0875b591c3a3a77f56368 100644 |
--- a/runtime/vm/flow_graph.cc |
+++ b/runtime/vm/flow_graph.cc |
@@ -373,25 +373,48 @@ static void VerifyUseListsInInstruction(Instruction* instr) { |
} |
-void FlowGraph::ComputeIsReceiverRecursive(PhiInstr* phi, |
- BitVector* processed) const { |
- if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return; |
- if (processed->Contains(phi->ssa_temp_index())) return; |
- processed->Add(phi->ssa_temp_index()); |
- for (intptr_t i = 0; i < phi->InputCount(); ++i) { |
- Definition* def = phi->InputAt(i)->definition(); |
- if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue; |
- if (!def->IsPhi()) { |
- phi->set_is_receiver(PhiInstr::kNotReceiver); |
- return; |
- } |
- ComputeIsReceiverRecursive(def->AsPhi(), processed); |
- if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) { |
- phi->set_is_receiver(PhiInstr::kNotReceiver); |
- return; |
- } |
- } |
- phi->set_is_receiver(PhiInstr::kReceiver); |
+void FlowGraph::ComputeIsReceiver() const { |
+ GrowableArray<PhiInstr*> worklist; |
+ BitVector* processed = |
+ new(zone()) BitVector(zone(), max_virtual_register_number()); |
+ for (BlockIterator block_it = reverse_postorder_iterator(); |
+ !block_it.Done(); |
+ block_it.Advance()) { |
+ BlockEntryInstr* entry = block_it.Current(); |
+ JoinEntryInstr* join_entry = entry->AsJoinEntry(); |
+ if (join_entry != NULL) { |
+ for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { |
+ PhiInstr* phi = it.Current(); |
+ phi->set_is_receiver(PhiInstr::kReceiver); |
+ for (intptr_t i = 0; i < phi->InputCount(); ++i) { |
+ Definition* def = phi->InputAt(i)->definition(); |
+ if (def->IsParameter() && (def->AsParameter()->index() == 0)) { |
+ continue; |
+ } |
+ if (!def->IsPhi()) { |
+ phi->set_is_receiver(PhiInstr::kNotReceiver); |
+ worklist.Add(phi); |
+ processed->Add(phi->ssa_temp_index()); |
+ break; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ while (!worklist.is_empty()) { |
+ PhiInstr* phi = worklist.RemoveLast(); |
+ for (Value::Iterator it(phi->input_use_list()); |
+ !it.Done(); |
+ it.Advance()) { |
+ PhiInstr* use = it.Current()->instruction()->AsPhi(); |
+ if ((use != NULL) && !processed->Contains(use->ssa_temp_index())) { |
+ use->set_is_receiver(PhiInstr::kNotReceiver); |
+ worklist.Add(use); |
+ processed->Add(use->ssa_temp_index()); |
+ } |
+ } |
+ } |
} |
@@ -403,9 +426,7 @@ bool FlowGraph::IsReceiver(Definition* def) const { |
return (phi->is_receiver() == PhiInstr::kReceiver); |
} |
// Not known if this phi is the receiver yet. Compute it now. |
- BitVector* processed = |
- new(zone()) BitVector(zone(), max_virtual_register_number()); |
- ComputeIsReceiverRecursive(phi, processed); |
+ ComputeIsReceiver(); |
Vyacheslav Egorov (Google)
2016/04/01 11:07:59
I still think it is much better to just fix the ex
|
return (phi->is_receiver() == PhiInstr::kReceiver); |
} |