[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}
This commit is contained in:
dcarney 2014-12-11 06:08:06 -08:00 committed by Commit bot
parent 7e9ca491a4
commit 91ed586ec2
3 changed files with 68 additions and 70 deletions

View File

@ -725,9 +725,8 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) {
} }
} else if (range->IsSpilled()) { } else if (range->IsSpilled()) {
int index = -1; int index = -1;
if (range->TopLevel()->GetSpillRange() != nullptr && if (range->TopLevel()->HasSpillRange()) {
range->TopLevel()->GetSpillRange()->id() != -1) { index = kMaxInt; // This hasn't been set yet.
index = range->TopLevel()->GetSpillRange()->id();
} else { } else {
index = range->TopLevel()->GetSpillOperand()->index(); index = range->TopLevel()->GetSpillOperand()->index();
} }

View File

@ -710,8 +710,8 @@ LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) {
LiveRange* RegisterAllocator::LiveRangeFor(int index) { LiveRange* RegisterAllocator::LiveRangeFor(int index) {
if (index >= static_cast<int>(live_ranges_.size())) { if (index >= static_cast<int>(live_ranges().size())) {
live_ranges_.resize(index + 1, nullptr); live_ranges().resize(index + 1, nullptr);
} }
auto result = live_ranges()[index]; auto result = live_ranges()[index];
if (result == nullptr) { if (result == nullptr) {
@ -819,14 +819,13 @@ static bool AreUseIntervalsIntersecting(UseInterval* interval1,
} }
SpillRange::SpillRange(LiveRange* range, int id, Zone* zone) SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) {
: id_(id), live_ranges_(1, zone), end_position_(range->End()) {
auto src = range->first_interval(); auto src = range->first_interval();
UseInterval* result = nullptr; UseInterval* result = nullptr;
UseInterval* node = nullptr; UseInterval* node = nullptr;
// Copy the nodes // Copy the nodes
while (src != nullptr) { 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) { if (result == nullptr) {
result = new_node; result = new_node;
} else { } else {
@ -836,54 +835,58 @@ SpillRange::SpillRange(LiveRange* range, int id, Zone* zone)
src = src->next(); src = src->next();
} }
use_interval_ = result; use_interval_ = result;
live_ranges_.Add(range, zone); live_ranges().push_back(range);
end_position_ = node->end();
DCHECK(!range->HasSpillRange()); DCHECK(!range->HasSpillRange());
range->SetSpillRange(this); range->SetSpillRange(this);
} }
bool SpillRange::IsIntersectingWith(SpillRange* other) { bool SpillRange::IsIntersectingWith(SpillRange* other) const {
if (End().Value() <= other->use_interval_->start().Value() || if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
other->End().Value() <= use_interval_->start().Value()) { this->End().Value() <= other->use_interval_->start().Value() ||
other->End().Value() <= this->use_interval_->start().Value()) {
return false; return false;
} }
return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
} }
bool SpillRange::TryMerge(SpillRange* other, Zone* zone) { bool SpillRange::TryMerge(SpillRange* other) {
if (Kind() == other->Kind() && if (Kind() != other->Kind() || IsIntersectingWith(other)) return false;
!AreUseIntervalsIntersecting(use_interval_, other->use_interval_)) {
if (End().Value() < other->End().Value()) { auto max = LifetimePosition::MaxPosition();
if (End().Value() < other->End().Value() &&
other->End().Value() != max.Value()) {
end_position_ = other->End(); end_position_ = other->End();
} }
other->end_position_ = max;
MergeDisjointIntervals(other->use_interval_, zone); MergeDisjointIntervals(other->use_interval_);
other->use_interval_ = nullptr; other->use_interval_ = nullptr;
for (int i = 0; i < other->live_ranges_.length(); i++) { for (auto range : other->live_ranges()) {
DCHECK(other->live_ranges_.at(i)->GetSpillRange() == other); DCHECK(range->GetSpillRange() == other);
other->live_ranges_.at(i)->SetSpillRange(this); range->SetSpillRange(this);
} }
live_ranges_.AddAll(other->live_ranges_, zone); live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
other->live_ranges_.Clear(); other->live_ranges().end());
other->live_ranges().clear();
return true; return true;
} }
return false;
}
void SpillRange::SetOperand(InstructionOperand* op) { void SpillRange::SetOperand(InstructionOperand* op) {
for (int i = 0; i < live_ranges_.length(); i++) { for (auto range : live_ranges()) {
DCHECK(live_ranges_.at(i)->GetSpillRange() == this); DCHECK(range->GetSpillRange() == this);
live_ranges_.at(i)->CommitSpillOperand(op); range->CommitSpillOperand(op);
} }
} }
void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) { void SpillRange::MergeDisjointIntervals(UseInterval* other) {
UseInterval* tail = nullptr; UseInterval* tail = nullptr;
auto current = use_interval_; auto current = use_interval_;
while (other != nullptr) { while (other != nullptr) {
@ -892,11 +895,9 @@ void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) {
current->start().Value() > other->start().Value()) { current->start().Value() > other->start().Value()) {
std::swap(current, other); std::swap(current, other);
} }
// Check disjointness // Check disjointness
DCHECK(other == nullptr || DCHECK(other == nullptr ||
current->end().Value() <= other->start().Value()); current->end().Value() <= other->start().Value());
// Append the 'current' node to the result accumulator and move forward // Append the 'current' node to the result accumulator and move forward
if (tail == nullptr) { if (tail == nullptr) {
use_interval_ = current; use_interval_ = current;
@ -920,7 +921,7 @@ void RegisterAllocator::ReuseSpillSlots() {
for (size_t j = i + 1; j < spill_ranges().size(); j++) { for (size_t j = i + 1; j < spill_ranges().size(); j++) {
auto other = spill_ranges()[j]; auto other = spill_ranges()[j];
if (!other->IsEmpty()) { if (!other->IsEmpty()) {
range->TryMerge(other, local_zone()); range->TryMerge(other);
} }
} }
} }
@ -956,9 +957,7 @@ void RegisterAllocator::CommitAssignment() {
SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
DCHECK(FLAG_turbo_reuse_spill_slots); DCHECK(FLAG_turbo_reuse_spill_slots);
int spill_id = static_cast<int>(spill_ranges().size()); auto spill_range = new (local_zone()) SpillRange(range, local_zone());
auto spill_range =
new (local_zone()) SpillRange(range, spill_id, local_zone());
spill_ranges().push_back(spill_range); spill_ranges().push_back(spill_range);
return spill_range; return spill_range;
} }
@ -1008,13 +1007,11 @@ bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
int op = phi->operands()[i]; int op = phi->operands()[i];
auto op_range = LiveRangeFor(op); auto op_range = LiveRangeFor(op);
auto op_spill = op_range->GetSpillRange(); auto op_spill = op_range->GetSpillRange();
if (op_spill != nullptr) { if (op_spill != nullptr &&
if (op_spill->id() == first_op_spill->id() || (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) {
first_op_spill->TryMerge(op_spill, local_zone())) {
num_merged++; num_merged++;
} }
} }
}
// Only continue if enough operands could be merged to the // Only continue if enough operands could be merged to the
// same spill slot. // same spill slot.
@ -1033,12 +1030,12 @@ bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos); auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
if (pos == nullptr) { if (pos == nullptr) {
auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
CHECK(first_op_spill->TryMerge(spill_range, local_zone())); CHECK(first_op_spill->TryMerge(spill_range));
Spill(range); Spill(range);
return true; return true;
} else if (pos->pos().Value() > range->Start().NextInstruction().Value()) { } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) {
auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); 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()); SpillBetween(range, range->Start(), pos->pos());
if (!AllocationOk()) return false; if (!AllocationOk()) return false;
DCHECK(UnhandledIsSorted()); DCHECK(UnhandledIsSorted());

View File

@ -105,7 +105,7 @@ class LifetimePosition FINAL {
class UseInterval FINAL : public ZoneObject { class UseInterval FINAL : public ZoneObject {
public: public:
UseInterval(LifetimePosition start, LifetimePosition end) UseInterval(LifetimePosition start, LifetimePosition end)
: start_(start), end_(end), next_(NULL) { : start_(start), end_(end), next_(nullptr) {
DCHECK(start.Value() < end.Value()); DCHECK(start.Value() < end.Value());
} }
@ -148,7 +148,7 @@ class UsePosition FINAL : public ZoneObject {
InstructionOperand* hint); InstructionOperand* hint);
InstructionOperand* operand() const { return operand_; } InstructionOperand* operand() const { return operand_; }
bool HasOperand() const { return operand_ != NULL; } bool HasOperand() const { return operand_ != nullptr; }
InstructionOperand* hint() const { return hint_; } InstructionOperand* hint() const { return hint_; }
bool HasHint() const; bool HasHint() const;
@ -184,15 +184,15 @@ class LiveRange FINAL : public ZoneObject {
UseInterval* first_interval() const { return first_interval_; } UseInterval* first_interval() const { return first_interval_; }
UsePosition* first_pos() const { return first_pos_; } UsePosition* first_pos() const { return first_pos_; }
LiveRange* parent() const { return parent_; } LiveRange* parent() const { return parent_; }
LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; }
const LiveRange* TopLevel() const { const LiveRange* TopLevel() const {
return (parent_ == NULL) ? this : parent_; return (parent_ == nullptr) ? this : parent_;
} }
LiveRange* next() const { return next_; } LiveRange* next() const { return next_; }
bool IsChild() const { return parent() != NULL; } bool IsChild() const { return parent() != nullptr; }
int id() const { return id_; } int id() const { return id_; }
bool IsFixed() const { return id_ < 0; } 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; InstructionOperand* CreateAssignedOperand(Zone* zone) const;
int assigned_register() const { return assigned_register_; } int assigned_register() const { return assigned_register_; }
int spill_start_index() const { return spill_start_index_; } int spill_start_index() const { return spill_start_index_; }
@ -245,9 +245,9 @@ class LiveRange FINAL : public ZoneObject {
} }
InstructionOperand* FirstHint() const { InstructionOperand* FirstHint() const {
UsePosition* pos = first_pos_; UsePosition* pos = first_pos_;
while (pos != NULL && !pos->HasHint()) pos = pos->next(); while (pos != nullptr && !pos->HasHint()) pos = pos->next();
if (pos != NULL) return pos->hint(); if (pos != nullptr) return pos->hint();
return NULL; return nullptr;
} }
LifetimePosition Start() const { LifetimePosition Start() const {
@ -345,26 +345,28 @@ class LiveRange FINAL : public ZoneObject {
}; };
class SpillRange : public ZoneObject { class SpillRange FINAL : public ZoneObject {
public: public:
SpillRange(LiveRange* range, int id, Zone* zone); SpillRange(LiveRange* range, Zone* zone);
bool TryMerge(SpillRange* other, 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); 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: private:
int id_; LifetimePosition End() const { return end_position_; }
ZoneList<LiveRange*> live_ranges_; ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
bool IsIntersectingWith(SpillRange* other) const;
// Merge intervals, making sure the use intervals are sorted
void MergeDisjointIntervals(UseInterval* other);
ZoneVector<LiveRange*> live_ranges_;
UseInterval* use_interval_; UseInterval* use_interval_;
LifetimePosition end_position_; LifetimePosition end_position_;
// Merge intervals, making sure the use intervals are sorted DISALLOW_COPY_AND_ASSIGN(SpillRange);
void MergeDisjointIntervals(UseInterval* other, Zone* zone);
}; };