Commit cbbfc0ff authored by mtrofin's avatar mtrofin Committed by Commit bot

[turbofan] More efficient splintering.

For live ranges with many use positions, such as those encountered in
some unity asm.js code, this change significantly reduces compile time
(e.g. benchmarks/Compile/slow_nbody1.js: from ~6s to 2s). The
improvement is solely due to regressions (fixed by this CL) due to
splintering.

This CL does not fully address compile time problems for large
functions in Turbofan, but constitutes a step in the right direction.

Review URL: https://codereview.chromium.org/1386253004

Cr-Commit-Position: refs/heads/master@{#31220}
parent 9790e494
...@@ -266,6 +266,7 @@ LiveRange::LiveRange(int relative_id, MachineType machine_type, ...@@ -266,6 +266,7 @@ LiveRange::LiveRange(int relative_id, MachineType machine_type,
current_interval_(nullptr), current_interval_(nullptr),
last_processed_use_(nullptr), last_processed_use_(nullptr),
current_hint_position_(nullptr), current_hint_position_(nullptr),
splitting_pointer_(nullptr),
size_(kInvalidSize), size_(kInvalidSize),
weight_(kInvalidWeight), weight_(kInvalidWeight),
group_(nullptr) { group_(nullptr) {
...@@ -455,8 +456,8 @@ LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { ...@@ -455,8 +456,8 @@ LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
} }
void LiveRange::DetachAt(LifetimePosition position, LiveRange* result, UsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
Zone* zone) { Zone* zone) {
DCHECK(Start() < position); DCHECK(Start() < position);
DCHECK(End() > position); DCHECK(End() > position);
DCHECK(result->IsEmpty()); DCHECK(result->IsEmpty());
...@@ -502,7 +503,10 @@ void LiveRange::DetachAt(LifetimePosition position, LiveRange* result, ...@@ -502,7 +503,10 @@ void LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
// Find the last use position before the split and the first use // Find the last use position before the split and the first use
// position after it. // position after it.
auto use_after = first_pos_; auto use_after =
splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
? first_pos()
: splitting_pointer_;
UsePosition* use_before = nullptr; UsePosition* use_before = nullptr;
if (split_at_start) { if (split_at_start) {
// The split position coincides with the beginning of a use interval (the // The split position coincides with the beginning of a use interval (the
...@@ -540,6 +544,7 @@ void LiveRange::DetachAt(LifetimePosition position, LiveRange* result, ...@@ -540,6 +544,7 @@ void LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
Verify(); Verify();
result->Verify(); result->Verify();
#endif #endif
return use_before;
} }
...@@ -865,7 +870,7 @@ void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, ...@@ -865,7 +870,7 @@ void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
const int kInvalidId = std::numeric_limits<int>::max(); const int kInvalidId = std::numeric_limits<int>::max();
DetachAt(start, result, zone); UsePosition* last = DetachAt(start, result, zone);
LiveRange end_part(kInvalidId, this->machine_type(), nullptr); LiveRange end_part(kInvalidId, this->machine_type(), nullptr);
result->DetachAt(end, &end_part, zone); result->DetachAt(end, &end_part, zone);
...@@ -878,14 +883,11 @@ void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, ...@@ -878,14 +883,11 @@ void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
current_interval_ = last_interval_; current_interval_ = last_interval_;
last_interval_ = end_part.last_interval_; last_interval_ = end_part.last_interval_;
if (first_pos_ == nullptr) { if (first_pos_ == nullptr) {
first_pos_ = end_part.first_pos_; first_pos_ = end_part.first_pos_;
} else { } else {
UsePosition* pos = first_pos_; splitting_pointer_ = last;
for (; pos->next() != nullptr; pos = pos->next()) { if (last != nullptr) last->set_next(end_part.first_pos_);
}
pos->set_next(end_part.first_pos_);
} }
} }
result->next_ = nullptr; result->next_ = nullptr;
......
...@@ -342,7 +342,8 @@ class LiveRange : public ZoneObject { ...@@ -342,7 +342,8 @@ class LiveRange : public ZoneObject {
// live range to the result live range. // live range to the result live range.
// The current range will terminate at position, while result will start from // The current range will terminate at position, while result will start from
// position. // position.
void DetachAt(LifetimePosition position, LiveRange* result, Zone* zone); UsePosition* DetachAt(LifetimePosition position, LiveRange* result,
Zone* zone);
// Detaches at position, and then links the resulting ranges. Returns the // Detaches at position, and then links the resulting ranges. Returns the
// child, which starts at position. // child, which starts at position.
...@@ -425,7 +426,8 @@ class LiveRange : public ZoneObject { ...@@ -425,7 +426,8 @@ class LiveRange : public ZoneObject {
mutable UsePosition* last_processed_use_; mutable UsePosition* last_processed_use_;
// This is used as a cache, it's invalid outside of BuildLiveRanges. // This is used as a cache, it's invalid outside of BuildLiveRanges.
mutable UsePosition* current_hint_position_; mutable UsePosition* current_hint_position_;
// Cache the last position splintering stopped at.
mutable UsePosition* splitting_pointer_;
// greedy: the number of LifetimePositions covered by this range. Used to // greedy: the number of LifetimePositions covered by this range. Used to
// prioritize selecting live ranges for register assignment, as well as // prioritize selecting live ranges for register assignment, as well as
// in weight calculations. // in weight calculations.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment