Index: runtime/vm/flow_graph.cc |
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc |
index 9f8e9a5871e3256d83d0fe187e6e18babb04b53f..3a214b1c55b7b54108e64645f86f05ca5f05d3c9 100644 |
--- a/runtime/vm/flow_graph.cc |
+++ b/runtime/vm/flow_graph.cc |
@@ -170,7 +170,11 @@ static void VerifyUseListsInInstruction(Instruction* instr) { |
ASSERT(defn == curr->definition()); |
Instruction* instr = curr->instruction(); |
ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index())); |
- ASSERT((instr->IsPhi() && instr->AsPhi()->is_alive()) || |
+ // BlockEntry instructions have environments attached to them but |
+ // have no reliable way to verify if they are still in the graph. |
+ // Thus we just assume they are. |
+ ASSERT(instr->IsBlockEntry() || |
+ (instr->IsPhi() && instr->AsPhi()->is_alive()) || |
(instr->previous() != NULL)); |
prev = curr; |
curr = curr->next_use(); |
@@ -441,6 +445,23 @@ void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
} |
+void FlowGraph::AttachEnvironment(Instruction* instr, |
+ GrowableArray<Definition*>* env) { |
+ Environment* deopt_env = |
+ Environment::From(*env, |
+ num_non_copied_params_, |
+ parsed_function_.function()); |
+ instr->SetEnvironment(deopt_env); |
+ for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) { |
+ Value* use = it.CurrentValue(); |
+ use->definition()->AddEnvUse(use); |
+ } |
+ if (instr->CanDeoptimize()) { |
+ instr->env()->set_deopt_id(instr->deopt_id()); |
+ } |
+} |
+ |
+ |
void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, |
GrowableArray<Definition*>* env, |
GrowableArray<PhiInstr*>* live_phis) { |
@@ -458,25 +479,17 @@ void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, |
} |
} |
+ // Attach environment to the block entry. |
+ AttachEnvironment(block_entry, env); |
+ |
// 2. Process normal instructions. |
+ |
for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { |
Instruction* current = it.Current(); |
- // Attach current environment to the instructions that can deoptimize and |
- // at goto instructions. Optimizations like LICM expect an environment at |
- // gotos. |
- if (current->CanDeoptimize() || current->IsGoto()) { |
- Environment* deopt_env = |
- Environment::From(*env, |
- num_non_copied_params_, |
- parsed_function_.function()); |
- current->SetEnvironment(deopt_env); |
- for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) { |
- Value* use = it.CurrentValue(); |
- use->definition()->AddEnvUse(use); |
- } |
- } |
- if (current->CanDeoptimize()) { |
- current->env()->set_deopt_id(current->deopt_id()); |
+ |
+ // Attach current environment to the instructions that need it. |
+ if (current->NeedsEnvironment()) { |
+ AttachEnvironment(current, env); |
} |
// 2a. Handle uses: |