Chromium Code Reviews| Index: vm/flow_graph_builder.cc |
| =================================================================== |
| --- vm/flow_graph_builder.cc (revision 8546) |
| +++ vm/flow_graph_builder.cc (working copy) |
| @@ -59,8 +59,8 @@ |
| void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| ASSERT(is_open()); |
| DeallocateTempIndex(instruction->InputCount()); |
| - if (instruction->IsBindInstr()) { |
| - instruction->AsBindInstr()->set_temp_index(AllocateTempIndex()); |
| + if (instruction->IsDefinition()) { |
| + instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); |
| } |
| if (is_empty()) { |
| entry_ = exit_ = instruction; |
| @@ -2337,6 +2337,11 @@ |
| if (for_optimized) { |
| GrowableArray<BitVector*> dominance_frontier; |
| ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); |
| + InsertPhis(&preorder_block_entries_, |
| + &assigned_vars, |
| + variable_count, |
| + &dominance_frontier); |
| + // TODO(fschneider): Perform SSA renaming. |
| } |
| if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { |
| intptr_t length = postorder_block_entries_.length(); |
| @@ -2445,6 +2450,7 @@ |
| } |
| idom[block_index] = dom_index; |
| (*preorder)[block_index]->set_dominator((*preorder)[dom_index]); |
| + (*preorder)[dom_index]->dominated_blocks()->Add((*preorder)[block_index]); |
| } |
| // 3. Now compute the dominance frontier for all blocks. This is |
| @@ -2481,6 +2487,64 @@ |
| } |
| +void FlowGraphBuilder::InsertPhis(GrowableArray<BlockEntryInstr*>* preorder, |
|
srdjan
2012/06/12 17:34:37
const GrowableArray<BlockEntryInstr>&
Florian Schneider
2012/06/13 10:53:40
Done.
|
| + GrowableArray<BitVector*>* assigned_vars, |
|
srdjan
2012/06/12 17:34:37
const GrowableArray<BitVector>&
Florian Schneider
2012/06/13 10:53:40
Done.
|
| + intptr_t var_count, |
| + GrowableArray<BitVector*>* dom_frontier) { |
|
srdjan
2012/06/12 17:34:37
ditto
Florian Schneider
2012/06/13 10:53:40
Done.
|
| + int block_count = preorder->length(); |
|
srdjan
2012/06/12 17:34:37
const intptr_t
Florian Schneider
2012/06/13 10:53:40
Done.
Florian Schneider
2012/06/13 10:53:40
Done.
|
| + // Map preorder block number to the highest variable index that has a phi |
| + // in that block. Use it to avoid inserting multiple phis for the same |
| + // variable. |
| + int* has_already = new int[block_count]; |
|
srdjan
2012/06/12 17:34:37
Allocation in C++ heap should be avoided (memory l
Florian Schneider
2012/06/13 10:53:40
Done.
|
| + // Map preorder block number to the highest variable index for which the |
| + // block went on the worklist. Use it to avoid adding the same block to |
| + // the worklist more than once for the same variable. |
| + int* work = new int[block_count]; |
| + |
| + // Initialize has_already and work. |
| + for (intptr_t block_index = 0; block_index < block_count; ++block_index) { |
| + has_already[block_index] = -1; |
| + work[block_index] = -1; |
| + } |
| + |
| + // Insert phis for each variable in turn. |
| + GrowableArray<BlockEntryInstr*> worklist; |
| + for (intptr_t var_index = 0; var_index < var_count; ++var_index) { |
| + // Add to the worklist each block containing an assignment. |
| + for (intptr_t block_index = 0; block_index < block_count; ++block_index) { |
| + if ((*assigned_vars)[block_index]->Contains(var_index)) { |
| + work[block_index] = var_index; |
| + worklist.Add((*preorder)[block_index]); |
| + } |
| + } |
| + |
| + while (!worklist.is_empty()) { |
| + BlockEntryInstr* current = worklist.Last(); |
| + worklist.RemoveLast(); |
| + // Ensure a phi for each block in the dominance frontier of current. |
| + for (BitVector::Iterator it((*dom_frontier)[current->preorder_number()]); |
| + !it.Done(); |
| + it.Advance()) { |
| + int index = it.Current(); |
| + if (has_already[index] < var_index) { |
| + BlockEntryInstr* block = (*preorder)[index]; |
| + ASSERT(block->IsJoinEntry()); |
| + block->AsJoinEntry()->InsertPhi(var_index, var_count); |
| + has_already[index] = var_index; |
| + if (work[index] < var_index) { |
| + work[index] = var_index; |
| + worklist.Add(block); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + |
| + delete[] work; |
| + delete[] has_already; |
| +} |
| + |
| + |
| void FlowGraphBuilder::Bailout(const char* reason) { |
| const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| const char* function_name = parsed_function_.function().ToCString(); |