Index: runtime/vm/flow_graph.cc |
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc |
index bcc18fbd9717e79255e99150ea1f92b0105d0ff1..b8e84b56b0814d0eef3598e73588d0c377661b37 100644 |
--- a/runtime/vm/flow_graph.cc |
+++ b/runtime/vm/flow_graph.cc |
@@ -2056,6 +2056,46 @@ void FlowGraph::TryOptimizePatterns() { |
} |
+// Returns true if use is dominated by the given instruction. |
+// Note: uses that occur at instruction itself are not dominated by it. |
+static bool IsDominatedUse(Instruction* dom, Value* use) { |
+ BlockEntryInstr* dom_block = dom->GetBlock(); |
+ |
+ Instruction* instr = use->instruction(); |
+ |
+ PhiInstr* phi = instr->AsPhi(); |
+ if (phi != NULL) { |
+ return dom_block->Dominates(phi->block()->PredecessorAt(use->use_index())); |
+ } |
+ |
+ BlockEntryInstr* use_block = instr->GetBlock(); |
+ if (use_block == dom_block) { |
+ // Fast path for the case of block entry. |
+ if (dom_block == dom) return true; |
+ |
+ for (Instruction* curr = dom->next(); curr != NULL; curr = curr->next()) { |
+ if (curr == instr) return true; |
+ } |
+ |
+ return false; |
+ } |
+ |
+ return dom_block->Dominates(use_block); |
+} |
+ |
+ |
+void FlowGraph::RenameDominatedUses(Definition* def, |
+ Instruction* dom, |
+ Definition* other) { |
+ for (Value::Iterator it(def->input_use_list()); !it.Done(); it.Advance()) { |
+ Value* use = it.Current(); |
+ if (IsDominatedUse(dom, use)) { |
+ use->BindTo(other); |
+ } |
+ } |
+} |
+ |
+ |
static bool IsPositiveOrZeroSmiConst(Definition* d) { |
ConstantInstr* const_instr = d->AsConstant(); |
if ((const_instr != NULL) && (const_instr->value().IsSmi())) { |