diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 11 | ||||
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 25 |
2 files changed, 27 insertions, 9 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 2fbd051c03..a02b1dacf7 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -1422,7 +1422,6 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { : Location::StackSlot(interval->GetParent()->GetSpillSlot())); } UsePosition* use = current->GetFirstUse(); - SafepointPosition* safepoint_position = interval->GetFirstSafepoint(); // Walk over all siblings, updating locations of use positions, and // connecting them when they are adjacent. @@ -1473,11 +1472,10 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { InsertParallelMoveAt(current->GetEnd(), interval->GetDefinedBy(), source, destination); } - for (; safepoint_position != nullptr; safepoint_position = safepoint_position->GetNext()) { - if (!current->Covers(safepoint_position->GetPosition())) { - DCHECK(next_sibling != nullptr); - break; - } + for (SafepointPosition* safepoint_position = current->GetFirstSafepoint(); + safepoint_position != nullptr; + safepoint_position = safepoint_position->GetNext()) { + DCHECK(current->Covers(safepoint_position->GetPosition())); LocationSummary* locations = safepoint_position->GetLocations(); if ((current->GetType() == Primitive::kPrimNot) && current->GetParent()->HasSpillSlot()) { @@ -1523,7 +1521,6 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { } while (current != nullptr); if (kIsDebugBuild) { - DCHECK(safepoint_position == nullptr); // Following uses can only be environment uses. The location for // these environments will be none. while (use != nullptr) { diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h index 2b51f949d8..98f98a29d1 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -492,6 +492,15 @@ class LiveInterval : public ArenaObject<kArenaAllocMisc> { return defined_by_; } + SafepointPosition* FindSafepointJustBefore(size_t position) const { + for (SafepointPosition* safepoint = first_safepoint_, *previous = nullptr; + safepoint != nullptr; + previous = safepoint, safepoint = safepoint->GetNext()) { + if (safepoint->GetPosition() >= position) return previous; + } + return last_safepoint_; + } + /** * Split this interval at `position`. This interval is changed to: * [start ... position). @@ -510,6 +519,19 @@ class LiveInterval : public ArenaObject<kArenaAllocMisc> { } LiveInterval* new_interval = new (allocator_) LiveInterval(allocator_, type_); + SafepointPosition* new_last_safepoint = FindSafepointJustBefore(position); + if (new_last_safepoint == nullptr) { + new_interval->first_safepoint_ = first_safepoint_; + new_interval->last_safepoint_ = last_safepoint_; + first_safepoint_ = last_safepoint_ = nullptr; + } else if (last_safepoint_ != new_last_safepoint) { + new_interval->last_safepoint_ = last_safepoint_; + new_interval->first_safepoint_ = new_last_safepoint->GetNext(); + DCHECK(new_interval->first_safepoint_ != nullptr); + last_safepoint_ = new_last_safepoint; + last_safepoint_->SetNext(nullptr); + } + new_interval->next_sibling_ = next_sibling_; next_sibling_ = new_interval; new_interval->parent_ = parent_; @@ -748,7 +770,6 @@ class LiveInterval : public ArenaObject<kArenaAllocMisc> { } SafepointPosition* GetFirstSafepoint() const { - DCHECK_EQ(GetParent(), this) << "Only the first sibling lists safepoints"; return first_safepoint_; } @@ -822,7 +843,7 @@ class LiveInterval : public ArenaObject<kArenaAllocMisc> { LiveRange* first_range_; LiveRange* last_range_; - // Safepoints where this interval is live. Only set in the parent interval. + // Safepoints where this interval is live. SafepointPosition* first_safepoint_; SafepointPosition* last_safepoint_; |