diff options
Diffstat (limited to 'compiler/optimizing/ssa_liveness_analysis.h')
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h index dc98864d9b..346753b775 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -150,9 +150,7 @@ class UsePosition : public ArenaObject<kArenaAllocSsaLiveness> { if (GetIsEnvironment()) return false; if (IsSynthesized()) return false; Location location = GetUser()->GetLocations()->InAt(GetInputIndex()); - return location.IsUnallocated() - && (location.GetPolicy() == Location::kRequiresRegister - || location.GetPolicy() == Location::kRequiresFpuRegister); + return location.IsUnallocated() && location.RequiresRegisterKind(); } private: @@ -481,6 +479,10 @@ class LiveInterval : public ArenaObject<kArenaAllocSsaLiveness> { return last_range_->GetEnd(); } + size_t GetLength() const { + return GetEnd() - GetStart(); + } + size_t FirstRegisterUseAfter(size_t position) const { if (is_temp_) { return position == GetStart() ? position : kNoLifetime; @@ -504,10 +506,16 @@ class LiveInterval : public ArenaObject<kArenaAllocSsaLiveness> { return kNoLifetime; } + // Returns the location of the first register use for this live interval, + // including a register definition if applicable. size_t FirstRegisterUse() const { return FirstRegisterUseAfter(GetStart()); } + // Whether the interval requires a register rather than a stack location. + // If needed for performance, this could be cached. + bool RequiresRegister() const { return FirstRegisterUse() != kNoLifetime; } + size_t FirstUseAfter(size_t position) const { if (is_temp_) { return position == GetStart() ? position : kNoLifetime; @@ -693,6 +701,10 @@ class LiveInterval : public ArenaObject<kArenaAllocSsaLiveness> { stream << " is_high: " << IsHighInterval(); } + // Same as Dump, but adds context such as the instruction defining this interval, and + // the register currently assigned to this interval. + void DumpWithContext(std::ostream& stream, const CodeGenerator& codegen) const; + LiveInterval* GetNextSibling() const { return next_sibling_; } LiveInterval* GetLastSibling() { LiveInterval* result = this; @@ -871,6 +883,33 @@ class LiveInterval : public ArenaObject<kArenaAllocSsaLiveness> { range_search_start_ = first_range_; } + bool DefinitionRequiresRegister() const { + DCHECK(IsParent()); + LocationSummary* locations = defined_by_->GetLocations(); + Location location = locations->Out(); + // This interval is the first interval of the instruction. If the output + // of the instruction requires a register, we return the position of that instruction + // as the first register use. + if (location.IsUnallocated()) { + if ((location.GetPolicy() == Location::kRequiresRegister) + || (location.GetPolicy() == Location::kSameAsFirstInput + && (locations->InAt(0).IsRegister() + || locations->InAt(0).IsRegisterPair() + || locations->InAt(0).GetPolicy() == Location::kRequiresRegister))) { + return true; + } else if ((location.GetPolicy() == Location::kRequiresFpuRegister) + || (location.GetPolicy() == Location::kSameAsFirstInput + && (locations->InAt(0).IsFpuRegister() + || locations->InAt(0).IsFpuRegisterPair() + || locations->InAt(0).GetPolicy() == Location::kRequiresFpuRegister))) { + return true; + } + } else if (location.IsRegister() || location.IsRegisterPair()) { + return true; + } + return false; + } + private: LiveInterval(ArenaAllocator* allocator, Primitive::Type type, @@ -925,33 +964,6 @@ class LiveInterval : public ArenaObject<kArenaAllocSsaLiveness> { return range; } - bool DefinitionRequiresRegister() const { - DCHECK(IsParent()); - LocationSummary* locations = defined_by_->GetLocations(); - Location location = locations->Out(); - // This interval is the first interval of the instruction. If the output - // of the instruction requires a register, we return the position of that instruction - // as the first register use. - if (location.IsUnallocated()) { - if ((location.GetPolicy() == Location::kRequiresRegister) - || (location.GetPolicy() == Location::kSameAsFirstInput - && (locations->InAt(0).IsRegister() - || locations->InAt(0).IsRegisterPair() - || locations->InAt(0).GetPolicy() == Location::kRequiresRegister))) { - return true; - } else if ((location.GetPolicy() == Location::kRequiresFpuRegister) - || (location.GetPolicy() == Location::kSameAsFirstInput - && (locations->InAt(0).IsFpuRegister() - || locations->InAt(0).IsFpuRegisterPair() - || locations->InAt(0).GetPolicy() == Location::kRequiresFpuRegister))) { - return true; - } - } else if (location.IsRegister() || location.IsRegisterPair()) { - return true; - } - return false; - } - bool IsDefiningPosition(size_t position) const { return IsParent() && (position == GetStart()); } |