[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()) {
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();
}

View File

@ -710,8 +710,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) {
@ -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<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;
}
@ -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());

View File

@ -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<LiveRange*> live_ranges_;
LifetimePosition End() const { return end_position_; }
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_;
LifetimePosition end_position_;
// Merge intervals, making sure the use intervals are sorted
void MergeDisjointIntervals(UseInterval* other, Zone* zone);
DISALLOW_COPY_AND_ASSIGN(SpillRange);
};