| 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());
|
|
|