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

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 10821108: Ensure that we never try to split range at its end position. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments 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/il_printer.cc » ('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 0b3d433059efd792cbd4fc3ea90363ae301b5c39..156b03550fb8fed1fa5e40b03320c6f134cd5350 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -38,11 +38,6 @@ static intptr_t MinPosition(intptr_t a, intptr_t b) {
}
-static bool IsParallelMovePosition(intptr_t pos) {
- return (pos & 1) == 0;
-}
-
-
static bool IsInstructionStartPosition(intptr_t pos) {
return (pos & 1) == 0;
}
@@ -329,14 +324,16 @@ LiveRange* FlowGraphAllocator::GetLiveRange(intptr_t vreg) {
}
+// Block location from the start of the instruction to its end.
void FlowGraphAllocator::BlockLocation(Location loc, intptr_t pos) {
ASSERT(loc.IsRegister());
+ ASSERT(IsInstructionStartPosition(pos));
const Register reg = loc.reg();
if (blocked_cpu_regs_[reg]) return;
if (cpu_regs_[reg].length() == 0) {
cpu_regs_[reg].Add(new LiveRange(kNoVirtualRegister));
}
- cpu_regs_[reg][0]->AddUseInterval(pos, pos + 2);
+ cpu_regs_[reg][0]->AddUseInterval(pos, pos + 1);
}
@@ -480,12 +477,11 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
// join with phis. The phi inputs contribute uses to each predecessor
// block (and the phi outputs contribute definitions in the successor
// block).
- ParallelMoveInstr* parallel_move = goto_instr->previous()->AsParallelMove();
- if (parallel_move == NULL) return goto_instr->previous();
+ if (!goto_instr->HasParallelMove()) return goto_instr->previous();
+ ParallelMoveInstr* parallel_move = goto_instr->parallel_move();
// All uses are recorded at the position of parallel move preceding goto.
const intptr_t pos = goto_instr->lifetime_position();
- ASSERT(parallel_move->lifetime_position() == pos);
JoinEntryInstr* join = goto_instr->successor();
ASSERT(join != NULL);
@@ -526,7 +522,7 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
// Begin backward iteration with the instruction before the parallel
// move.
- return parallel_move->previous();
+ return goto_instr->previous();
}
@@ -560,12 +556,10 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) {
for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) {
BlockEntryInstr* pred = block->PredecessorAt(pred_idx);
- ASSERT(pred->last_instruction()->IsGoto());
- Instruction* move_instr = pred->last_instruction()->previous();
- ASSERT(move_instr->IsParallelMove());
-
+ GotoInstr* goto_instr = pred->last_instruction()->AsGoto();
+ ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove()));
MoveOperands* move =
- move_instr->AsParallelMove()->MoveOperandsAt(move_idx);
+ goto_instr->parallel_move()->MoveOperandsAt(move_idx);
move->set_dest(Location::PrefersRegister());
range->AddUse(pos, move->dest_slot());
}
@@ -679,7 +673,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
// Expected shape of live range:
//
// i i'
- // [-----)
+ // [--)
//
Location temp = locs->temp(j);
@@ -700,7 +694,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
// Expected shape of live range:
//
// i i'
- // [-----)
+ // [--)
//
for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
@@ -747,7 +741,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
// Fixed output location. Expected shape of live range:
//
// i i' j j'
- // register [-----)
+ // register [--)
// output [-------
//
BlockLocation(*out, pos);
@@ -758,7 +752,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
// that will be allocated for this output's live range.
// Special case: fixed output followed by a fixed input last use.
UsePosition* use = range->first_use();
- if (use->pos() == (pos + 2)) {
+ if (use->pos() == (pos + 1)) {
ASSERT(use->location_slot()->IsUnallocated());
*(use->location_slot()) = *out;
@@ -769,11 +763,11 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
// Shorten live range to the point of definition, this might make the range
// empty (if the only use immediately follows). If range is not empty add
// move from a fixed register to an unallocated location.
- range->DefineAt(pos + 2);
+ range->DefineAt(pos + 1);
if (range->Start() == range->End()) return;
- MoveOperands* move = AddMoveAt(pos + 2, Location::PrefersRegister(), *out);
- range->AddUse(pos + 2, move->dest_slot());
+ MoveOperands* move = AddMoveAt(pos + 1, Location::PrefersRegister(), *out);
+ range->AddUse(pos + 1, move->dest_slot());
} else if (output_same_as_first_input) {
// Output register will contain a value of the first input at instruction's
// start. Expected shape of live ranges:
@@ -898,26 +892,12 @@ void FlowGraphAllocator::NumberInstructions() {
Instruction* last = block->PredecessorAt(i)->last_instruction();
ASSERT(last->IsGoto());
- ParallelMoveInstr* move =
- CreateParallelMoveBefore(last, last->lifetime_position());
+ ParallelMoveInstr* move = last->AsGoto()->GetParallelMove();
// Populate the ParallelMove with empty moves.
for (intptr_t j = 0; j < phi_count; j++) {
move->AddMove(Location::NoLocation(), Location::NoLocation());
}
-
- // Replace Goto instruction with the corresponding move in
- // the array of instructions. This is done to ensure that
- // this parallel move will be treated as a normal instruction
- // by AddMoveAt for the purpose of live ranges connections (i.e.
- // a separate move will be inserted by AddMoveAt)
- // This move can't be reused by AddMoveAt to insert
- // moves at Goto position because such range connecting moves might
- // come into a conflict with phi connecting moves due to implicit
- // interference: phi-value's liferange starts only at successor block
- // but the move is actually performed at the predecessor.
- ASSERT(instructions_[last->lifetime_position() / 2] == last);
- instructions_[last->lifetime_position() / 2] = move;
}
}
}
@@ -930,7 +910,7 @@ Instruction* FlowGraphAllocator::InstructionAt(intptr_t pos) const {
bool FlowGraphAllocator::IsBlockEntry(intptr_t pos) const {
- return InstructionAt(pos)->IsBlockEntry();
+ return IsInstructionStartPosition(pos) && InstructionAt(pos)->IsBlockEntry();
}
@@ -1042,6 +1022,7 @@ LiveRange* LiveRange::SplitAt(intptr_t split_pos) {
UseInterval* interval = finger_.first_pending_use_interval();
ASSERT(interval->start() < split_pos);
+ ASSERT(split_pos < End());
// Corner case. We need to start over to find previous interval.
if (interval->start() == split_pos) interval = first_use_interval_;
@@ -1100,9 +1081,6 @@ LiveRange* LiveRange::SplitAt(intptr_t split_pos) {
TRACE_ALLOC((" split sibling [%d, %d)\n",
next_sibling_->Start(), next_sibling_->End()));
- // Split sibling can only start at a parallel move.
- ASSERT(IsParallelMovePosition(next_sibling_->Start()));
-
last_use_interval_ = last_before_split;
last_use_interval_->next_ = NULL;
return next_sibling_;
@@ -1121,6 +1099,11 @@ LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range,
to = ToInstructionStart(to);
}
+ // Splitting at the end is not allowed as it produces an empty
+ // live range.
+ if (to == range->End()) to -= 1;
+ ASSERT(from <= to);
+
return range->SplitAt(to);
}
@@ -1423,8 +1406,9 @@ bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated,
MoveOperands* FlowGraphAllocator::AddMoveAt(intptr_t pos,
Location to,
Location from) {
+ ASSERT(!IsBlockEntry(pos));
+
Instruction* instr = InstructionAt(pos);
- ASSERT(!instr->IsBlockEntry());
ParallelMoveInstr* parallel_move = NULL;
if (IsInstructionStartPosition(pos)) {
@@ -1610,11 +1594,10 @@ void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* range,
Instruction* last = source_block->last_instruction();
if (last->SuccessorCount() == 1) {
- CreateParallelMoveBefore(last, last->lifetime_position())->
- AddMove(target, source);
+ ASSERT(last->IsGoto());
+ last->AsGoto()->GetParallelMove()->AddMove(target, source);
} else {
- CreateParallelMoveAfter(target_block, target_block->start_pos())->
- AddMove(target, source);
+ target_block->GetParallelMove()->AddMove(target, source);
}
}
@@ -1628,6 +1611,11 @@ void FlowGraphAllocator::ResolveControlFlow() {
while (range->next_sibling() != NULL) {
LiveRange* sibling = range->next_sibling();
+ TRACE_ALLOC(("connecting [%d, %d) [%s] to [%d, %d) [%s]\n",
+ range->Start(), range->End(),
+ range->assigned_location().Name(),
+ sibling->Start(), sibling->End(),
+ sibling->assigned_location().Name()));
if ((range->End() == sibling->Start()) &&
!range->assigned_location().Equals(sibling->assigned_location()) &&
!IsBlockEntry(range->End())) {
« no previous file with comments | « no previous file | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698