[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:
parent
7e9ca491a4
commit
91ed586ec2
@ -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();
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user