| Index: src/compiler/register-allocator.cc
|
| diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
|
| index ebfb932b086be5d3a16cd437a46884f3c418f006..a36ea361208f73c2ee91a2abcb0e6c002eecb313 100644
|
| --- a/src/compiler/register-allocator.cc
|
| +++ b/src/compiler/register-allocator.cc
|
| @@ -427,7 +427,9 @@ LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
|
| child->top_level_ = TopLevel();
|
| child->next_ = next_;
|
| next_ = child;
|
| -
|
| + if (child->next() == nullptr) {
|
| + TopLevel()->set_last_child(child);
|
| + }
|
| return child;
|
| }
|
|
|
| @@ -524,6 +526,7 @@ void LiveRange::AppendAsChild(TopLevelLiveRange* other) {
|
|
|
| other->UpdateParentForAllChildren(TopLevel());
|
| TopLevel()->UpdateSpillRangePostMerge(other);
|
| + TopLevel()->set_last_child(other->last_child());
|
| }
|
|
|
|
|
| @@ -666,7 +669,9 @@ TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type)
|
| spill_operand_(nullptr),
|
| spills_at_definition_(nullptr),
|
| spilled_in_deferred_blocks_(false),
|
| - spill_start_index_(kMaxInt) {
|
| + spill_start_index_(kMaxInt),
|
| + last_child_(this),
|
| + last_insertion_point_(this) {
|
| bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
|
| }
|
|
|
| @@ -882,22 +887,15 @@ void TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
|
| }
|
|
|
|
|
| -LiveRange* TopLevelLiveRange::GetLastChild() {
|
| - LiveRange* ret = this;
|
| - for (; ret->next() != nullptr; ret = ret->next()) {
|
| - }
|
| - return ret;
|
| -}
|
| -
|
| -
|
| void TopLevelLiveRange::Merge(TopLevelLiveRange* other,
|
| RegisterAllocationData* data) {
|
| DCHECK(Start() < other->Start());
|
| + DCHECK(other->splintered_from() == this);
|
|
|
| data->live_ranges()[other->vreg()] = nullptr;
|
|
|
| - LiveRange* last_other = other->GetLastChild();
|
| - LiveRange* last_me = GetLastChild();
|
| + LiveRange* last_other = other->last_child();
|
| + LiveRange* last_me = last_child();
|
|
|
| // Simple case: we just append at the end.
|
| if (last_me->End() <= other->Start()) return last_me->AppendAsChild(other);
|
| @@ -906,28 +904,32 @@ void TopLevelLiveRange::Merge(TopLevelLiveRange* other,
|
|
|
| // In the more general case, we need to find the ranges between which to
|
| // insert.
|
| - LiveRange* insertion_point = this;
|
| - for (; insertion_point->next() != nullptr &&
|
| - insertion_point->next()->Start() <= other->Start();
|
| - insertion_point = insertion_point->next()) {
|
| + if (other->Start() < last_insertion_point_->Start()) {
|
| + last_insertion_point_ = this;
|
| + }
|
| +
|
| + for (; last_insertion_point_->next() != nullptr &&
|
| + last_insertion_point_->next()->Start() <= other->Start();
|
| + last_insertion_point_ = last_insertion_point_->next()) {
|
| }
|
|
|
| // When we splintered the original range, we reconstituted the original range
|
| // into one range without children, but with discontinuities. To merge the
|
| // splinter back in, we need to split the range - or a child obtained after
|
| // register allocation splitting.
|
| - LiveRange* after = insertion_point->next();
|
| - if (insertion_point->End() > other->Start()) {
|
| + LiveRange* after = last_insertion_point_->next();
|
| + if (last_insertion_point_->End() > other->Start()) {
|
| LiveRange* new_after =
|
| - insertion_point->SplitAt(other->Start(), data->allocation_zone());
|
| - new_after->set_spilled(insertion_point->spilled());
|
| + last_insertion_point_->SplitAt(other->Start(), data->allocation_zone());
|
| + new_after->set_spilled(last_insertion_point_->spilled());
|
| if (!new_after->spilled())
|
| - new_after->set_assigned_register(insertion_point->assigned_register());
|
| + new_after->set_assigned_register(
|
| + last_insertion_point_->assigned_register());
|
| after = new_after;
|
| }
|
|
|
| last_other->next_ = after;
|
| - insertion_point->next_ = other;
|
| + last_insertion_point_->next_ = other;
|
| other->UpdateParentForAllChildren(TopLevel());
|
| TopLevel()->UpdateSpillRangePostMerge(other);
|
| }
|
|
|