diff options
| -rw-r--r-- | compiler/optimizing/register_allocator.cc | 19 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 19 |
3 files changed, 26 insertions, 14 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index cecc210cbf..9911f8b574 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -213,7 +213,7 @@ void RegisterAllocator::ProcessInstruction(HInstruction* instruction) { LiveInterval* interval = LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimInt); temp_intervals_.Add(interval); - interval->AddRange(position, position + 1); + interval->AddTempUse(instruction, i); unhandled_core_intervals_.Add(interval); break; } @@ -222,7 +222,7 @@ void RegisterAllocator::ProcessInstruction(HInstruction* instruction) { LiveInterval* interval = LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimDouble); temp_intervals_.Add(interval); - interval->AddRange(position, position + 1); + interval->AddTempUse(instruction, i); if (codegen_->NeedsTwoRegisters(Primitive::kPrimDouble)) { interval->AddHighInterval(true); LiveInterval* high = interval->GetHighInterval(); @@ -1695,8 +1695,6 @@ void RegisterAllocator::Resolve() { } // Assign temp locations. - HInstruction* current = nullptr; - size_t temp_index = 0; for (size_t i = 0; i < temp_intervals_.Size(); ++i) { LiveInterval* temp = temp_intervals_.Get(i); if (temp->IsHighInterval()) { @@ -1704,25 +1702,20 @@ void RegisterAllocator::Resolve() { continue; } HInstruction* at = liveness_.GetTempUser(temp); - if (at != current) { - temp_index = 0; - current = at; - } + size_t temp_index = liveness_.GetTempIndex(temp); LocationSummary* locations = at->GetLocations(); switch (temp->GetType()) { case Primitive::kPrimInt: - locations->SetTempAt( - temp_index++, Location::RegisterLocation(temp->GetRegister())); + locations->SetTempAt(temp_index, Location::RegisterLocation(temp->GetRegister())); break; case Primitive::kPrimDouble: if (codegen_->NeedsTwoRegisters(Primitive::kPrimDouble)) { Location location = Location::FpuRegisterPairLocation( temp->GetRegister(), temp->GetHighInterval()->GetRegister()); - locations->SetTempAt(temp_index++, location); + locations->SetTempAt(temp_index, location); } else { - locations->SetTempAt( - temp_index++, Location::FpuRegisterLocation(temp->GetRegister())); + locations->SetTempAt(temp_index, Location::FpuRegisterLocation(temp->GetRegister())); } break; diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 56ccd717cf..0f3973e5fb 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -318,6 +318,8 @@ static int RegisterOrLowRegister(Location location) { int LiveInterval::FindFirstRegisterHint(size_t* free_until) const { DCHECK(!IsHighInterval()); + if (IsTemp()) return kNoRegister; + if (GetParent() == this && defined_by_ != nullptr) { // This is the first interval for the instruction. Try to find // a register based on its definition. diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h index b57029d1a7..bc78dc2e76 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -180,6 +180,15 @@ class LiveInterval : public ArenaObject<kArenaAllocMisc> { // This interval is the result of a split. bool IsSplit() const { return parent_ != this; } + void AddTempUse(HInstruction* instruction, size_t temp_index) { + DCHECK(IsTemp()); + DCHECK(first_use_ == nullptr) << "A temporary can only have one user"; + size_t position = instruction->GetLifetimePosition(); + first_use_ = new (allocator_) UsePosition( + instruction, temp_index, /* is_environment */ false, position, first_use_); + AddRange(position, position + 1); + } + void AddUse(HInstruction* instruction, size_t input_index, bool is_environment) { // Set the use within the instruction. size_t position = instruction->GetLifetimePosition() + 1; @@ -856,7 +865,15 @@ class SsaLivenessAnalysis : public ValueObject { HInstruction* GetTempUser(LiveInterval* temp) const { // A temporary shares the same lifetime start as the instruction that requires it. DCHECK(temp->IsTemp()); - return GetInstructionFromPosition(temp->GetStart() / 2); + HInstruction* user = GetInstructionFromPosition(temp->GetStart() / 2); + DCHECK_EQ(user, temp->GetFirstUse()->GetUser()); + return user; + } + + size_t GetTempIndex(LiveInterval* temp) const { + // We use the input index to store the index of the temporary in the user's temporary list. + DCHECK(temp->IsTemp()); + return temp->GetFirstUse()->GetInputIndex(); } size_t GetMaxLifetimePosition() const { |