From 8272688499c2232355db34d94057983fd436173d Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Mon, 1 Jun 2015 13:51:57 +0100 Subject: [PATCH] Tweak one hint and one split in the linear scan. - Return a hinted register if it is available. Otherwise another move will be necessary. - Use SplitBetween instead of raw split when a register is not fully available. This will find the best split position. Change-Id: Ie464e536204ab556eb09345fe6426621eb86e5ac --- compiler/optimizing/register_allocator.cc | 4 ++-- compiler/optimizing/ssa_liveness_analysis.cc | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 5e784d731..a381315ba 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -802,9 +802,9 @@ bool RegisterAllocator::TryAllocateFreeReg(LiveInterval* current) { current->SetRegister(reg); if (!current->IsDeadAt(free_until[reg])) { // If the register is only available for a subset of live ranges - // covered by `current`, split `current` at the position where + // covered by `current`, split `current` before the position where // the register is not available anymore. - LiveInterval* split = Split(current, free_until[reg]); + LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]); DCHECK(split != nullptr); AddSorted(unhandled_, split); } diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 250eb04a1..d5f977fee 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -341,6 +341,7 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until, // starts at. If one location is a register we return it as a hint. This // will avoid a move between the two blocks. HBasicBlock* block = liveness.GetBlockFromPosition(GetStart() / 2); + size_t next_register_use = FirstRegisterUse(); for (size_t i = 0; i < block->GetPredecessors().Size(); ++i) { size_t position = block->GetPredecessors().Get(i)->GetLifetimeEnd() - 1; // We know positions above GetStart() do not have a location yet. @@ -348,7 +349,9 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until, LiveInterval* existing = GetParent()->GetSiblingAt(position); if (existing != nullptr && existing->HasRegister() - && (free_until[existing->GetRegister()] > GetStart())) { + // It's worth using that register if it is available until + // the next use. + && (free_until[existing->GetRegister()] >= next_register_use)) { return existing->GetRegister(); } } -- 2.11.0