[regalloc] Fix another case where FindOptimalSpillingPos missed ranges

In previous change https://crrev.com/c/2274308 , I attempted to fix an
issue where FindOptimalSpillingPos could sometimes fail to find the
LiveRange that covers the top of the loop. However, I misunderstood how
TopLevelLiveRange::GetChildCovers behaves, so I introduced a different
case where FindOptimalSpillingPos would fail to find the right
LiveRange. This change updates GetChildCovers to do what I had thought
it would do, so it can find the right LiveRange in all cases.

     chromium:1102243

Bug: chromium:1101958, chromium:1101954, chromium:1102257,
Change-Id: If91c642c3f7f5e3a8b4cfaa3b3577865c84afcb6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2288660
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#68758}
This commit is contained in:
Seth Brenith 2020-07-09 05:50:11 -07:00 committed by Commit Bot
parent f468e8e75f
commit 607452dc22
2 changed files with 19 additions and 1 deletions

View File

@ -1149,10 +1149,22 @@ void TopLevelLiveRange::VerifyChildrenInOrder() const {
LiveRange* TopLevelLiveRange::GetChildCovers(LifetimePosition pos) {
LiveRange* child = last_child_covers_;
DCHECK_NE(child, nullptr);
if (pos < child->Start()) {
// Cached value has advanced too far; start from the top.
child = this;
}
LiveRange* previous_child = nullptr;
while (child != nullptr && child->End() <= pos) {
previous_child = child;
child = child->next();
}
last_child_covers_ = child;
// If we've walked past the end, cache the last child instead. This allows
// future calls that are also past the end to be fast, since they will know
// that there is no need to reset the search to the beginning.
last_child_covers_ = child == nullptr ? previous_child : child;
return !child || !child->Covers(pos) ? nullptr : child;
}

View File

@ -952,7 +952,13 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange {
void Verify() const;
void VerifyChildrenInOrder() const;
// Returns the LiveRange covering the given position, or nullptr if no such
// range exists. Uses a linear search through child ranges. The range at the
// previously requested position is cached, so this function will be very fast
// if you call it with a non-decreasing sequence of positions.
LiveRange* GetChildCovers(LifetimePosition pos);
int GetNextChildId() {
return IsSplinter() ? splintered_from()->GetNextChildId()
: ++last_child_id_;