summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/register_allocator.cc11
-rw-r--r--compiler/optimizing/ssa_liveness_analysis.h25
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_;