Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 10808008: Revert "Introduce Goto instructions to the flow graph." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_allocator.cc
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 2ce2f2a1749dc2070eb128aa460d47690543050c..9230dac1452c6c69b3a3881f2052462221db101c 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -385,66 +385,60 @@ void FlowGraphAllocator::BuildLiveRanges() {
range->AddUseInterval(block->start_pos(), block->end_pos());
}
- // Position corresponding to the beginning of the last instruction in the
- // block.
+ // Position corresponding to the end of the last instruction in the block.
intptr_t pos = block->end_pos() - 1;
+
Instruction* current = block->last_instruction();
- // Goto instructions do not contribute liveness information.
- GotoInstr* goto_instr = current->AsGoto();
- if (goto_instr != NULL) {
- current = current->previous();
- // If we have a parallel move here then the successor block must be a
- // join with phis. The phi inputs contribute uses to each predecessor
- // block (and the phi outputs contribute definitions in the successor
- // block).
- //
- // We record those uses at the end of the instruction preceding the
- // parallel move. This position is 'pos', because we do not assign
- // instruction numbers to parallel moves.
+ // If last instruction is a parallel move we need to perform phi resolution.
+ if (current->IsParallelMove()) {
ParallelMoveInstr* parallel_move = current->AsParallelMove();
- if (parallel_move != NULL) {
- JoinEntryInstr* join = goto_instr->successor();
- ASSERT(join != NULL);
-
- // Search for the index of the current block in the predecessors of
- // the join.
- // TODO(kmillikin): record the predecessor index in the goto when
- // building the predecessor list to avoid this search.
- intptr_t pred_idx = 0;
- for (; pred_idx < join->PredecessorCount(); pred_idx++) {
- if (join->PredecessorAt(pred_idx) == block) break;
+ JoinEntryInstr* join = current->next()->AsJoinEntry();
+ ASSERT(join != NULL);
+
+ // Find index of the current block in predecessors of join.
+ intptr_t pred_idx = -1;
+ for (intptr_t j = 0; j < join->PredecessorCount(); j++) {
+ BlockEntryInstr* pred = join->PredecessorAt(j);
+ if (pred == block) {
+ pred_idx = j;
+ break;
}
- ASSERT(pred_idx < join->PredecessorCount());
+ }
+ ASSERT(pred_idx != -1);
- // Record the corresponding phi input use for each phi.
- ZoneGrowableArray<PhiInstr*>* phis = join->phis();
- for (intptr_t move_idx = 0; move_idx < phis->length(); move_idx++) {
- PhiInstr* phi = (*phis)[move_idx];
- if (phi == NULL) continue;
+ // For every phi we have a reserved phi resolution move and we need
+ // to either initialize its source with constant or to register a use, so
+ // that register allocator will populate source slot with location of
+ // the appropriate SSA value.
+ ZoneGrowableArray<PhiInstr*>* phis = join->phis();
+ intptr_t move_idx = 0;
+ for (intptr_t j = 0; j < phis->length(); j++) {
+ PhiInstr* phi = (*phis)[j];
+ if (phi == NULL) continue;
- Value* val = phi->InputAt(pred_idx);
- MoveOperands move = parallel_move->moves()[move_idx];
- if (val->IsUse()) {
- const intptr_t virtual_register =
- val->AsUse()->definition()->ssa_temp_index();
- Location* slot = move.src_slot();
- *slot = Location::RequiresRegister();
- GetLiveRange(virtual_register)->head()->AddUse(NULL, pos, slot);
- } else {
- ASSERT(val->IsConstant());
- move.set_src(Location::Constant(val->AsConstant()->value()));
- }
+ Value* val = phi->InputAt(pred_idx);
+
+ MoveOperands move = parallel_move->moves()[move_idx];
+ if (val->IsUse()) {
+ const intptr_t use = val->AsUse()->definition()->ssa_temp_index();
+ Location* slot = move.src_slot();
+ *slot = Location::RequiresRegister();
+ GetLiveRange(use)->head()->AddUse(NULL, pos, slot);
+ } else {
+ ASSERT(val->IsConstant());
+ move.set_src(Location::Constant(val->AsConstant()->value()));
}
- // Begin backward iteration with the instruction before the parallel
- // move.
- current = current->previous();
+ move_idx++;
}
+
+ current = current->previous();
}
// Now process all instructions in reverse order.
- --pos; // 'pos' is now the start position for the current instruction.
+ // Advance position to the start of the last instruction in the block.
+ pos -= 1;
while (current != block) {
LocationSummary* locs = current->locs();
@@ -568,55 +562,45 @@ void FlowGraphAllocator::BuildLiveRanges() {
}
-// Linearize the control flow graph. The chosen order will be used by the
-// linear-scan register allocator. Number most instructions with a pair of
-// numbers representing lifetime positions. Introduce explicit parallel
-// move instructions in the predecessors of join nodes. The moves are used
-// for phi resolution.
void FlowGraphAllocator::NumberInstructions() {
intptr_t pos = 0;
- // The basic block order is reverse postorder.
const intptr_t block_count = postorder_.length();
for (intptr_t i = block_count - 1; i >= 0; i--) {
BlockEntryInstr* block = postorder_[i];
+
block->set_start_pos(pos);
- block->set_lifetime_position(pos);
pos += 2;
- for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
- Instruction* current = it.Current();
- // Do not assign numbers to parallel moves or goto instructions.
- if (!current->IsParallelMove() && !current->IsGoto()) {
- current->set_lifetime_position(pos);
- pos += 2;
- }
+ Instruction* current = block->next();
+
+ Instruction* last = block->last_instruction();
+ if (!last->IsParallelMove()) last = last->next();
+
+ while (current != last) {
+ current->set_lifetime_position(pos);
+ current = current->next();
+ pos += 2;
}
block->set_end_pos(pos);
// For join entry predecessors create phi resolution moves if
// necessary. They will be populated by the register allocator.
- JoinEntryInstr* join = block->AsJoinEntry();
- if ((join != NULL) && (join->phi_count() > 0)) {
- const intptr_t phi_count = join->phi_count();
+ if (block->IsJoinEntry() && (block->AsJoinEntry()->phi_count() > 0)) {
+ const intptr_t phi_count = block->AsJoinEntry()->phi_count();
for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+ BlockEntryInstr* pred = block->PredecessorAt(i);
+ ASSERT(!pred->last_instruction()->IsParallelMove());
+
ParallelMoveInstr* move = new ParallelMoveInstr();
- // Populate the ParallelMove with empty moves.
+ move->set_next(block);
+ move->set_previous(pred->last_instruction());
+ pred->last_instruction()->set_next(move);
+ pred->set_last_instruction(move);
+
+ // Populate ParallelMove with empty moves.
for (intptr_t j = 0; j < phi_count; j++) {
move->AddMove(Location::NoLocation(), Location::NoLocation());
}
-
- // Insert the move between the last two instructions of the
- // predecessor block (all such blocks have at least two instructions:
- // the block entry and goto instructions.)
- BlockEntryInstr* pred = block->PredecessorAt(i);
- Instruction* next = pred->last_instruction();
- Instruction* previous = next->previous();
- ASSERT(next->IsGoto());
- ASSERT(!previous->IsParallelMove());
- previous->set_next(move);
- move->set_previous(previous);
- move->set_next(next);
- next->set_previous(move);
}
}
}
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698