Index: src/compiler/register-allocator.cc |
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc |
index e01fe1ff35f8d12fdb1cad9499b6377d00659acc..9bfb97c53cd9729885f9693026b708d7561fa050 100644 |
--- a/src/compiler/register-allocator.cc |
+++ b/src/compiler/register-allocator.cc |
@@ -708,8 +708,8 @@ LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) { |
LiveRange* RegisterAllocator::LiveRangeFor(int index) { |
- if (index >= static_cast<int>(live_ranges_.size())) { |
- live_ranges_.resize(index + 1, nullptr); |
+ if (index >= static_cast<int>(live_ranges().size())) { |
+ live_ranges().resize(index + 1, nullptr); |
} |
auto result = live_ranges()[index]; |
if (result == nullptr) { |
@@ -817,14 +817,13 @@ static bool AreUseIntervalsIntersecting(UseInterval* interval1, |
} |
-SpillRange::SpillRange(LiveRange* range, int id, Zone* zone) |
- : id_(id), live_ranges_(1, zone), end_position_(range->End()) { |
+SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) { |
auto src = range->first_interval(); |
UseInterval* result = nullptr; |
UseInterval* node = nullptr; |
// Copy the nodes |
while (src != nullptr) { |
- UseInterval* new_node = new (zone) UseInterval(src->start(), src->end()); |
+ auto new_node = new (zone) UseInterval(src->start(), src->end()); |
if (result == nullptr) { |
result = new_node; |
} else { |
@@ -834,54 +833,58 @@ SpillRange::SpillRange(LiveRange* range, int id, Zone* zone) |
src = src->next(); |
} |
use_interval_ = result; |
- live_ranges_.Add(range, zone); |
+ live_ranges().push_back(range); |
+ end_position_ = node->end(); |
DCHECK(!range->HasSpillRange()); |
range->SetSpillRange(this); |
} |
-bool SpillRange::IsIntersectingWith(SpillRange* other) { |
- if (End().Value() <= other->use_interval_->start().Value() || |
- other->End().Value() <= use_interval_->start().Value()) { |
+bool SpillRange::IsIntersectingWith(SpillRange* other) const { |
+ if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || |
+ this->End().Value() <= other->use_interval_->start().Value() || |
+ other->End().Value() <= this->use_interval_->start().Value()) { |
return false; |
} |
return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); |
} |
-bool SpillRange::TryMerge(SpillRange* other, Zone* zone) { |
- if (Kind() == other->Kind() && |
- !AreUseIntervalsIntersecting(use_interval_, other->use_interval_)) { |
- if (End().Value() < other->End().Value()) { |
- end_position_ = other->End(); |
- } |
- |
- MergeDisjointIntervals(other->use_interval_, zone); |
- other->use_interval_ = nullptr; |
+bool SpillRange::TryMerge(SpillRange* other) { |
+ if (Kind() != other->Kind() || IsIntersectingWith(other)) return false; |
- for (int i = 0; i < other->live_ranges_.length(); i++) { |
- DCHECK(other->live_ranges_.at(i)->GetSpillRange() == other); |
- other->live_ranges_.at(i)->SetSpillRange(this); |
- } |
+ auto max = LifetimePosition::MaxPosition(); |
+ if (End().Value() < other->End().Value() && |
+ other->End().Value() != max.Value()) { |
+ end_position_ = other->End(); |
+ } |
+ other->end_position_ = max; |
- live_ranges_.AddAll(other->live_ranges_, zone); |
- other->live_ranges_.Clear(); |
+ MergeDisjointIntervals(other->use_interval_); |
+ other->use_interval_ = nullptr; |
- return true; |
+ for (auto range : other->live_ranges()) { |
+ DCHECK(range->GetSpillRange() == other); |
+ range->SetSpillRange(this); |
} |
- return false; |
+ |
+ live_ranges().insert(live_ranges().end(), other->live_ranges().begin(), |
+ other->live_ranges().end()); |
+ other->live_ranges().clear(); |
+ |
+ return true; |
} |
void SpillRange::SetOperand(InstructionOperand* op) { |
- for (int i = 0; i < live_ranges_.length(); i++) { |
- DCHECK(live_ranges_.at(i)->GetSpillRange() == this); |
- live_ranges_.at(i)->CommitSpillOperand(op); |
+ for (auto range : live_ranges()) { |
+ DCHECK(range->GetSpillRange() == this); |
+ range->CommitSpillOperand(op); |
} |
} |
-void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) { |
+void SpillRange::MergeDisjointIntervals(UseInterval* other) { |
UseInterval* tail = nullptr; |
auto current = use_interval_; |
while (other != nullptr) { |
@@ -890,11 +893,9 @@ void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) { |
current->start().Value() > other->start().Value()) { |
std::swap(current, other); |
} |
- |
// Check disjointness |
DCHECK(other == nullptr || |
current->end().Value() <= other->start().Value()); |
- |
// Append the 'current' node to the result accumulator and move forward |
if (tail == nullptr) { |
use_interval_ = current; |
@@ -918,7 +919,7 @@ void RegisterAllocator::ReuseSpillSlots() { |
for (size_t j = i + 1; j < spill_ranges().size(); j++) { |
auto other = spill_ranges()[j]; |
if (!other->IsEmpty()) { |
- range->TryMerge(other, local_zone()); |
+ range->TryMerge(other); |
} |
} |
} |
@@ -952,9 +953,7 @@ void RegisterAllocator::CommitAssignment() { |
SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { |
DCHECK(FLAG_turbo_reuse_spill_slots); |
- int spill_id = static_cast<int>(spill_ranges().size()); |
- auto spill_range = |
- new (local_zone()) SpillRange(range, spill_id, local_zone()); |
+ auto spill_range = new (local_zone()) SpillRange(range, local_zone()); |
spill_ranges().push_back(spill_range); |
return spill_range; |
} |
@@ -1004,11 +1003,9 @@ bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) { |
int op = phi->operands()[i]; |
auto op_range = LiveRangeFor(op); |
auto op_spill = op_range->GetSpillRange(); |
- if (op_spill != nullptr) { |
- if (op_spill->id() == first_op_spill->id() || |
- first_op_spill->TryMerge(op_spill, local_zone())) { |
- num_merged++; |
- } |
+ if (op_spill != nullptr && |
+ (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) { |
+ num_merged++; |
} |
} |
@@ -1029,12 +1026,12 @@ bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) { |
auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos); |
if (pos == nullptr) { |
auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); |
- CHECK(first_op_spill->TryMerge(spill_range, local_zone())); |
+ CHECK(first_op_spill->TryMerge(spill_range)); |
Spill(range); |
return true; |
} else if (pos->pos().Value() > range->Start().NextInstruction().Value()) { |
auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); |
- CHECK(first_op_spill->TryMerge(spill_range, local_zone())); |
+ CHECK(first_op_spill->TryMerge(spill_range)); |
SpillBetween(range, range->Start(), pos->pos()); |
if (!AllocationOk()) return false; |
DCHECK(UnhandledIsSorted()); |