From 91ed586ec291fe455d6ac81d566548b49695b6bf Mon Sep 17 00:00:00 2001 From: dcarney Date: Thu, 11 Dec 2014 06:08:06 -0800 Subject: [PATCH] [turbofan] update SpillRange to use ZoneVector R=bmeurer@chromium.org BUG= Review URL: https://codereview.chromium.org/793323002 Cr-Commit-Position: refs/heads/master@{#25777} --- src/compiler/graph-visualizer.cc | 5 +- src/compiler/register-allocator.cc | 87 +++++++++++++++--------------- src/compiler/register-allocator.h | 46 ++++++++-------- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/src/compiler/graph-visualizer.cc b/src/compiler/graph-visualizer.cc index 81ed99efd4..e018c7ac19 100644 --- a/src/compiler/graph-visualizer.cc +++ b/src/compiler/graph-visualizer.cc @@ -725,9 +725,8 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) { } } else if (range->IsSpilled()) { int index = -1; - if (range->TopLevel()->GetSpillRange() != nullptr && - range->TopLevel()->GetSpillRange()->id() != -1) { - index = range->TopLevel()->GetSpillRange()->id(); + if (range->TopLevel()->HasSpillRange()) { + index = kMaxInt; // This hasn't been set yet. } else { index = range->TopLevel()->GetSpillOperand()->index(); } diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc index 0775de969e..a4f3c6ef0a 100644 --- a/src/compiler/register-allocator.cc +++ b/src/compiler/register-allocator.cc @@ -710,8 +710,8 @@ LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) { LiveRange* RegisterAllocator::LiveRangeFor(int index) { - if (index >= static_cast(live_ranges_.size())) { - live_ranges_.resize(index + 1, nullptr); + if (index >= static_cast(live_ranges().size())) { + live_ranges().resize(index + 1, nullptr); } auto result = live_ranges()[index]; if (result == nullptr) { @@ -819,14 +819,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 { @@ -836,54 +835,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(); - } +bool SpillRange::TryMerge(SpillRange* other) { + if (Kind() != other->Kind() || IsIntersectingWith(other)) return false; - MergeDisjointIntervals(other->use_interval_, zone); - other->use_interval_ = nullptr; - - 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); - } - - live_ranges_.AddAll(other->live_ranges_, zone); - other->live_ranges_.Clear(); - - return true; + auto max = LifetimePosition::MaxPosition(); + if (End().Value() < other->End().Value() && + other->End().Value() != max.Value()) { + end_position_ = other->End(); } - return false; + other->end_position_ = max; + + MergeDisjointIntervals(other->use_interval_); + other->use_interval_ = nullptr; + + for (auto range : other->live_ranges()) { + DCHECK(range->GetSpillRange() == other); + range->SetSpillRange(this); + } + + 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) { @@ -892,11 +895,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; @@ -920,7 +921,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); } } } @@ -956,9 +957,7 @@ void RegisterAllocator::CommitAssignment() { SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { DCHECK(FLAG_turbo_reuse_spill_slots); - int spill_id = static_cast(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; } @@ -1008,11 +1007,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++; } } @@ -1033,12 +1030,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()); diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h index 3ed9860995..19cac29326 100644 --- a/src/compiler/register-allocator.h +++ b/src/compiler/register-allocator.h @@ -105,7 +105,7 @@ class LifetimePosition FINAL { class UseInterval FINAL : public ZoneObject { public: UseInterval(LifetimePosition start, LifetimePosition end) - : start_(start), end_(end), next_(NULL) { + : start_(start), end_(end), next_(nullptr) { DCHECK(start.Value() < end.Value()); } @@ -148,7 +148,7 @@ class UsePosition FINAL : public ZoneObject { InstructionOperand* hint); InstructionOperand* operand() const { return operand_; } - bool HasOperand() const { return operand_ != NULL; } + bool HasOperand() const { return operand_ != nullptr; } InstructionOperand* hint() const { return hint_; } bool HasHint() const; @@ -184,15 +184,15 @@ class LiveRange FINAL : public ZoneObject { UseInterval* first_interval() const { return first_interval_; } UsePosition* first_pos() const { return first_pos_; } LiveRange* parent() const { return parent_; } - LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } + LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } const LiveRange* TopLevel() const { - return (parent_ == NULL) ? this : parent_; + return (parent_ == nullptr) ? this : parent_; } LiveRange* next() const { return next_; } - bool IsChild() const { return parent() != NULL; } + bool IsChild() const { return parent() != nullptr; } int id() const { return id_; } bool IsFixed() const { return id_ < 0; } - bool IsEmpty() const { return first_interval() == NULL; } + bool IsEmpty() const { return first_interval() == nullptr; } InstructionOperand* CreateAssignedOperand(Zone* zone) const; int assigned_register() const { return assigned_register_; } int spill_start_index() const { return spill_start_index_; } @@ -245,9 +245,9 @@ class LiveRange FINAL : public ZoneObject { } InstructionOperand* FirstHint() const { UsePosition* pos = first_pos_; - while (pos != NULL && !pos->HasHint()) pos = pos->next(); - if (pos != NULL) return pos->hint(); - return NULL; + while (pos != nullptr && !pos->HasHint()) pos = pos->next(); + if (pos != nullptr) return pos->hint(); + return nullptr; } LifetimePosition Start() const { @@ -345,26 +345,28 @@ class LiveRange FINAL : public ZoneObject { }; -class SpillRange : public ZoneObject { +class SpillRange FINAL : public ZoneObject { public: - SpillRange(LiveRange* range, int id, Zone* zone); - bool TryMerge(SpillRange* other, Zone* zone); + SpillRange(LiveRange* range, Zone* zone); + + UseInterval* interval() const { return use_interval_; } + RegisterKind Kind() const { return live_ranges_[0]->Kind(); } + bool IsEmpty() const { return live_ranges_.empty(); } + bool TryMerge(SpillRange* other); void SetOperand(InstructionOperand* op); - bool IsEmpty() { return live_ranges_.length() == 0; } - int id() const { return id_; } - UseInterval* interval() { return use_interval_; } - RegisterKind Kind() const { return live_ranges_.at(0)->Kind(); } - LifetimePosition End() const { return end_position_; } - bool IsIntersectingWith(SpillRange* other); private: - int id_; - ZoneList live_ranges_; + LifetimePosition End() const { return end_position_; } + ZoneVector& live_ranges() { return live_ranges_; } + bool IsIntersectingWith(SpillRange* other) const; + // Merge intervals, making sure the use intervals are sorted + void MergeDisjointIntervals(UseInterval* other); + + ZoneVector live_ranges_; UseInterval* use_interval_; LifetimePosition end_position_; - // Merge intervals, making sure the use intervals are sorted - void MergeDisjointIntervals(UseInterval* other, Zone* zone); + DISALLOW_COPY_AND_ASSIGN(SpillRange); };