diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-12-01 12:04:49 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-12-01 12:04:49 +0000 |
commit | 672db0289de1dec9513da14153f315fecb78649e (patch) | |
tree | 1093b4dc9f5142155b7c4bb9f9a5a9797d50e47f /compiler/optimizing | |
parent | 5a57dae02941c59233aa6f80ac160ab1af1e4844 (diff) | |
parent | 5976857e65d3d0e7be0c4e3183e9483c85a76bb8 (diff) | |
download | android_art-672db0289de1dec9513da14153f315fecb78649e.tar.gz android_art-672db0289de1dec9513da14153f315fecb78649e.tar.bz2 android_art-672db0289de1dec9513da14153f315fecb78649e.zip |
Merge "Fix insertion of parallel move when connecting siblings."
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index b074c9aa8e..a6c06359a0 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -96,6 +96,25 @@ void RegisterAllocator::AllocateRegisters() { ValidateInternal(true); processing_core_registers_ = false; ValidateInternal(true); + // Check that the linear order is still correct with regards to lifetime positions. + // Since only parallel moves have been inserted during the register allocation, + // these checks are mostly for making sure these moves have been added correctly. + size_t current_liveness = 0; + for (HLinearOrderIterator it(liveness_); !it.Done(); it.Advance()) { + HBasicBlock* block = it.Current(); + for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) { + HInstruction* instruction = inst_it.Current(); + DCHECK_LE(current_liveness, instruction->GetLifetimePosition()); + current_liveness = instruction->GetLifetimePosition(); + } + for (HInstructionIterator inst_it(block->GetInstructions()); + !inst_it.Done(); + inst_it.Advance()) { + HInstruction* instruction = inst_it.Current(); + DCHECK_LE(current_liveness, instruction->GetLifetimePosition()) << instruction->DebugName(); + current_liveness = instruction->GetLifetimePosition(); + } + } } } @@ -928,11 +947,18 @@ void RegisterAllocator::InsertParallelMoveAt(size_t position, } else { // Move must happen before the first instruction of the block. at = liveness_.GetInstructionFromPosition((position + 1) / 2); - move = at->AsParallelMove(); - if (move == nullptr || move->GetLifetimePosition() < position) { + // Note that parallel moves may have already been inserted, so we explicitly + // ask for the first instruction of the block: `GetInstructionFromPosition` does + // not contain the moves. + at = at->GetBlock()->GetFirstInstruction(); + if (at->GetLifetimePosition() != position) { + DCHECK_GT(at->GetLifetimePosition(), position); move = new (allocator_) HParallelMove(allocator_); move->SetLifetimePosition(position); at->GetBlock()->InsertInstructionBefore(move, at); + } else { + DCHECK(at->IsParallelMove()); + move = at->AsParallelMove(); } } } else if (IsInstructionEnd(position)) { @@ -987,10 +1013,11 @@ void RegisterAllocator::InsertParallelMoveAtExitOf(HBasicBlock* block, HParallelMove* move; // This is a parallel move for connecting blocks. We need to differentiate // it with moves for connecting siblings in a same block, and output moves. + size_t position = last->GetLifetimePosition(); if (previous == nullptr || !previous->IsParallelMove() - || previous->AsParallelMove()->GetLifetimePosition() != block->GetLifetimeEnd()) { + || previous->AsParallelMove()->GetLifetimePosition() != position) { move = new (allocator_) HParallelMove(allocator_); - move->SetLifetimePosition(block->GetLifetimeEnd()); + move->SetLifetimePosition(position); block->InsertInstructionBefore(move, last); } else { move = previous->AsParallelMove(); |