[turbofan] Merge group spill ranges.

Akin to linear scan's TryReuseSpillForPhi, we attempt to merge the
spill ranges of grouped live ranges (which are phi inputs and output),
to avoid inefficient slot-to-slot moves.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30833}
This commit is contained in:
mtrofin 2015-09-18 09:01:52 -07:00 committed by Commit bot
parent 90e1a0ddb3
commit 7864c35a76
2 changed files with 32 additions and 0 deletions

View File

@ -479,11 +479,37 @@ void GreedyAllocator::AllocateRegisters() {
} }
allocations_.clear(); allocations_.clear();
TryReuseSpillRangesForGroups();
TRACE("End allocating function %s with the Greedy Allocator\n", TRACE("End allocating function %s with the Greedy Allocator\n",
data()->debug_name()); data()->debug_name());
} }
void GreedyAllocator::TryReuseSpillRangesForGroups() {
for (TopLevelLiveRange* top : data()->live_ranges()) {
if (!CanProcessRange(top) || !top->is_phi() || top->group() == nullptr) {
continue;
}
SpillRange* spill_range = nullptr;
for (LiveRange* member : top->group()->ranges()) {
if (!member->TopLevel()->HasSpillRange()) continue;
SpillRange* member_range = member->TopLevel()->GetSpillRange();
if (spill_range == nullptr) {
spill_range = member_range;
} else {
// This may not always succeed, because we group non-conflicting ranges
// that may have been splintered, and the splinters may cause conflicts
// in the spill ranges.
// TODO(mtrofin): should the splinters own their own spill ranges?
spill_range->TryMerge(member_range);
}
}
}
}
float GreedyAllocator::GetMaximumConflictingWeight( float GreedyAllocator::GetMaximumConflictingWeight(
unsigned reg_id, const LiveRange* range, float competing_weight) const { unsigned reg_id, const LiveRange* range, float competing_weight) const {
float ret = LiveRange::kInvalidWeight; float ret = LiveRange::kInvalidWeight;

View File

@ -179,6 +179,12 @@ class GreedyAllocator final : public RegisterAllocator {
// - the portion after the call. // - the portion after the call.
LiveRange* GetRemainderAfterSplittingAroundFirstCall(LiveRange* range); LiveRange* GetRemainderAfterSplittingAroundFirstCall(LiveRange* range);
// While we attempt to merge spill ranges later on in the allocation pipeline,
// we want to ensure group elements get merged. Waiting until later may hinder
// merge-ability, since the pipeline merger (being naive) may create conflicts
// between spill ranges of group members.
void TryReuseSpillRangesForGroups();
// Necessary heuristic: spill when all else failed. // Necessary heuristic: spill when all else failed.
void SpillRangeAsLastResort(LiveRange* range); void SpillRangeAsLastResort(LiveRange* range);