Chromium Code Reviews| Index: runtime/vm/flow_graph.cc |
| =================================================================== |
| --- runtime/vm/flow_graph.cc (revision 22436) |
| +++ runtime/vm/flow_graph.cc (working copy) |
| @@ -9,6 +9,7 @@ |
| #include "vm/intermediate_language.h" |
| #include "vm/longjump.h" |
| #include "vm/growable_array.h" |
| +#include "vm/il_printer.h" |
|
srdjan
2013/05/07 17:34:05
Remove.
Florian Schneider
2013/05/08 08:57:47
Done.
|
| namespace dart { |
| @@ -327,8 +328,13 @@ |
| const intptr_t block_count = flow_graph_->preorder().length(); |
| for (intptr_t i = 0; i < block_count; i++) { |
| BlockEntryInstr* block = flow_graph_->preorder()[i]; |
| + // All locals are assigned inside try-catch. |
| BitVector* kill = GetKillSet(block); |
| - kill->Intersect(GetLiveOutSet(block)); |
| + if (block->try_index() != CatchClauseNode::kInvalidTryIndex) { |
| + kill->SetAll(); |
| + } else { |
| + kill->Intersect(GetLiveOutSet(block)); |
| + } |
| assigned_vars_.Add(kill); |
| } |
| @@ -373,10 +379,17 @@ |
| for (intptr_t i = 0; i < block_count; i++) { |
| BlockEntryInstr* block = postorder_[i]; |
| + |
|
srdjan
2013/05/07 17:34:05
Two lines space seems too match within a function
Florian Schneider
2013/05/08 08:57:47
Done.
|
| BitVector* kill = kill_[i]; |
| BitVector* live_in = live_in_[i]; |
| last_loads->Clear(); |
| + // Inside try-catch all locals are live. |
| + if (block->try_index() != CatchClauseNode::kInvalidTryIndex) { |
| + live_in->SetAll(); |
| + continue; |
| + } |
| + |
| // Iterate backwards starting at the last instruction. |
| for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| Instruction* current = it.Current(); |
| @@ -385,7 +398,7 @@ |
| if (load != NULL) { |
| const intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| live_in->Add(index); |
| - if (!last_loads->Contains(index)) { |
| + if (!last_loads->Contains(index) && !load->local().always_live()) { |
| last_loads->Add(index); |
| load->mark_last(); |
| } |
| @@ -393,7 +406,7 @@ |
| } |
| StoreLocalInstr* store = current->AsStoreLocal(); |
| - if (store != NULL) { |
| + if (store != NULL && !store->local().always_live()) { |
| const intptr_t index = |
| store->local().BitIndexIn(num_non_copied_params_); |
| if (kill->Contains(index)) { |
| @@ -406,7 +419,9 @@ |
| } |
| kill->Add(index); |
| } |
| - live_in->Remove(index); |
| + if (block->try_index() == CatchClauseNode::kInvalidTryIndex) { |
| + live_in->Remove(index); |
| + } |
| continue; |
| } |
| } |
| @@ -616,11 +631,6 @@ |
| void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, |
| VariableLivenessAnalysis* variable_liveness, |
| ZoneGrowableArray<Definition*>* inlining_parameters) { |
| - // TODO(fschneider): Support catch-entry. |
| - if (graph_entry_->SuccessorCount() > 1) { |
| - Bailout("Catch-entry support in SSA."); |
| - } |
| - |
| // Initial renaming environment. |
| GrowableArray<Definition*> env(variable_count()); |
| @@ -653,9 +663,14 @@ |
| env.Add(constant_null()); |
| } |
| - BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| - ASSERT(normal_entry != NULL); // Must have entry. |
| - RenameRecursive(normal_entry, &env, live_phis, variable_liveness); |
| + if (graph_entry_->SuccessorCount() > 1) { |
| + // Functions with try-catch have a fixed area of stack slots reserved |
| + // so that all local variables are stored at a known location when |
| + // on entry to the catch. |
| + graph_entry_->set_fixed_slot_count( |
| + num_stack_locals() + num_copied_params()); |
| + } |
| + RenameRecursive(graph_entry_, &env, live_phis, variable_liveness); |
| } |
| @@ -689,9 +704,22 @@ |
| if (phi != NULL) { |
| (*env)[i] = phi; |
| phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| + if (block_entry->try_index() != CatchClauseNode::kInvalidTryIndex) { |
| + phi->mark_alive(); |
| + live_phis->Add(phi); |
| + } |
| } |
| } |
| } |
| + } else if (block_entry->IsCatchBlockEntry()) { |
| + // Add real definitions for all locals and parameters. The location of the |
| + // parameters and locals is the same as at function entry. |
| + for (intptr_t i = 0; i < env->length(); ++i) { |
| + ParameterInstr* param = new ParameterInstr(i, block_entry); |
| + param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| + (*env)[i] = param; |
| + block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); |
| + } |
| } |
| // Attach environment to the block entry. |
| @@ -750,7 +778,8 @@ |
| index = store->local().BitIndexIn(num_non_copied_params_); |
| result = store->value()->definition(); |
| - if (variable_liveness->IsStoreAlive(block_entry, store)) { |
| + if (variable_liveness->IsStoreAlive(block_entry, store) || |
| + store->local().always_live()) { |
| (*env)[index] = result; |
| } else { |
| (*env)[index] = constant_null(); |
| @@ -768,7 +797,8 @@ |
| live_phis->Add(phi); |
| } |
| - if (variable_liveness->IsLastLoad(block_entry, load)) { |
| + if (variable_liveness->IsLastLoad(block_entry, load) && |
| + !load->local().always_live()) { |
| (*env)[index] = constant_null(); |
| } |
| } |
| @@ -796,6 +826,7 @@ |
| } |
| } |
| + |
| // 3. Process dominated blocks. |
| for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { |
| BlockEntryInstr* block = block_entry->dominated_blocks()[i]; |