diff options
-rw-r--r-- | compiler/optimizing/locations.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 54 |
2 files changed, 45 insertions, 13 deletions
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h index 9ce8d351a9..ebca1cc4d0 100644 --- a/compiler/optimizing/locations.h +++ b/compiler/optimizing/locations.h @@ -151,6 +151,10 @@ class Location : public ValueObject { return GetKind() == kFpuRegisterPair; } + bool IsRegisterKind() const { + return IsRegister() || IsFpuRegister() || IsRegisterPair() || IsFpuRegisterPair(); + } + int reg() const { DCHECK(IsRegister() || IsFpuRegister()); return GetPayload(); diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 2a8473524f..bebb73ba22 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -311,7 +311,12 @@ bool SsaLivenessAnalysis::UpdateLiveIn(const HBasicBlock& block) { return live_in->UnionIfNotIn(live_out, kill); } +static int RegisterOrLowRegister(Location location) { + return location.IsPair() ? location.low() : location.reg(); +} + int LiveInterval::FindFirstRegisterHint(size_t* free_until) const { + DCHECK(!IsHighInterval()); if (GetParent() == this && defined_by_ != nullptr) { // This is the first interval for the instruction. Try to find // a register based on its definition. @@ -333,8 +338,12 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until) const { if (user->IsPhi()) { // If the phi has a register, try to use the same. Location phi_location = user->GetLiveInterval()->ToLocation(); - if (SameRegisterKind(phi_location) && free_until[phi_location.reg()] >= use_position) { - return phi_location.reg(); + if (phi_location.IsRegisterKind()) { + DCHECK(SameRegisterKind(phi_location)); + int reg = RegisterOrLowRegister(phi_location); + if (free_until[reg] >= use_position) { + return reg; + } } const GrowableArray<HBasicBlock*>& predecessors = user->GetBlock()->GetPredecessors(); // If the instruction dies at the phi assignment, we can try having the @@ -347,8 +356,11 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until) const { HInstruction* input = user->InputAt(i); Location location = input->GetLiveInterval()->GetLocationAt( predecessors.Get(i)->GetLifetimeEnd() - 1); - if (location.IsRegister() && free_until[location.reg()] >= use_position) { - return location.reg(); + if (location.IsRegisterKind()) { + int reg = RegisterOrLowRegister(location); + if (free_until[reg] >= use_position) { + return reg; + } } } } @@ -359,8 +371,12 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until) const { // We use the user's lifetime position - 1 (and not `use_position`) because the // register is blocked at the beginning of the user. size_t position = user->GetLifetimePosition() - 1; - if (SameRegisterKind(expected) && free_until[expected.reg()] >= position) { - return expected.reg(); + if (expected.IsRegisterKind()) { + DCHECK(SameRegisterKind(expected)); + int reg = RegisterOrLowRegister(expected); + if (free_until[reg] >= position) { + return reg; + } } } } @@ -382,8 +398,9 @@ int LiveInterval::FindHintAtDefinition() const { // If the input dies at the end of the predecessor, we know its register can // be reused. Location input_location = input_interval.ToLocation(); - if (SameRegisterKind(input_location)) { - return input_location.reg(); + if (input_location.IsRegisterKind()) { + DCHECK(SameRegisterKind(input_location)); + return RegisterOrLowRegister(input_location); } } } @@ -398,8 +415,9 @@ int LiveInterval::FindHintAtDefinition() const { // If the input dies at the start of this instruction, we know its register can // be reused. Location location = input_interval.ToLocation(); - if (SameRegisterKind(location)) { - return location.reg(); + if (location.IsRegisterKind()) { + DCHECK(SameRegisterKind(location)); + return RegisterOrLowRegister(location); } } } @@ -408,9 +426,19 @@ int LiveInterval::FindHintAtDefinition() const { } bool LiveInterval::SameRegisterKind(Location other) const { - return IsFloatingPoint() - ? other.IsFpuRegister() - : other.IsRegister(); + if (IsFloatingPoint()) { + if (IsLowInterval() || IsHighInterval()) { + return other.IsFpuRegisterPair(); + } else { + return other.IsFpuRegister(); + } + } else { + if (IsLowInterval() || IsHighInterval()) { + return other.IsRegisterPair(); + } else { + return other.IsRegister(); + } + } } bool LiveInterval::NeedsTwoSpillSlots() const { |