Commit ae064fca authored by vegorov@chromium.org's avatar vegorov@chromium.org

When spilling live range with not register uses inside the loop try to move...

When spilling live range with not register uses inside the loop try to move spilling out of the loop.

This allows to minimize amount of memory moves on the back edge.

R=danno@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13960 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9f730004
......@@ -196,6 +196,18 @@ UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
}
UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
LifetimePosition start) {
UsePosition* pos = first_pos();
UsePosition* prev = NULL;
while (pos != NULL && pos->pos().Value() < start.Value()) {
if (pos->RegisterIsBeneficial()) prev = pos;
pos = pos->next();
}
return prev;
}
UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) {
UsePosition* pos = NextUsePosition(start);
while (pos != NULL && !pos->RequiresRegister()) {
......@@ -1943,6 +1955,39 @@ void LAllocator::AllocateBlockedReg(LiveRange* current) {
}
LifetimePosition LAllocator::FindOptimalSpillingPos(LiveRange* range,
LifetimePosition pos) {
HBasicBlock* block = GetBlock(pos.InstructionStart());
HBasicBlock* loop_header =
block->IsLoopHeader() ? block : block->parent_loop_header();
if (loop_header == NULL) return pos;
UsePosition* prev_use =
range->PreviousUsePositionRegisterIsBeneficial(pos);
while (loop_header != NULL) {
// We are going to spill live range inside the loop.
// If possible try to move spilling position backwards to loop header.
// This will reduce number of memory moves on the back edge.
LifetimePosition loop_start = LifetimePosition::FromInstructionIndex(
loop_header->first_instruction_index());
if (range->Covers(loop_start)) {
if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) {
// No register beneficial use inside the loop before the pos.
pos = loop_start;
}
}
// Try hoisting out to an outer loop.
loop_header = loop_header->parent_loop_header();
}
return pos;
}
void LAllocator::SplitAndSpillIntersecting(LiveRange* current) {
ASSERT(current->HasRegisterAssigned());
int reg = current->assigned_register();
......@@ -1951,10 +1996,11 @@ void LAllocator::SplitAndSpillIntersecting(LiveRange* current) {
LiveRange* range = active_live_ranges_[i];
if (range->assigned_register() == reg) {
UsePosition* next_pos = range->NextRegisterPosition(current->Start());
LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
if (next_pos == NULL) {
SpillAfter(range, split_pos);
SpillAfter(range, spill_pos);
} else {
SpillBetween(range, split_pos, next_pos->pos());
SpillBetween(range, spill_pos, next_pos->pos());
}
if (!AllocationOk()) return;
ActiveToHandled(range);
......
......@@ -311,6 +311,10 @@ class LiveRange: public ZoneObject {
// Modifies internal state of live range!
UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start);
// Returns use position for which register is beneficial in this live
// range and which precedes start.
UsePosition* PreviousUsePositionRegisterIsBeneficial(LifetimePosition start);
// Can this live range be spilled at this position.
bool CanBeSpilled(LifetimePosition pos);
......@@ -539,6 +543,11 @@ class LAllocator BASE_EMBEDDED {
void SplitAndSpillIntersecting(LiveRange* range);
// If we are trying to spill a range inside the loop try to
// hoist spill position out to the point just before the loop.
LifetimePosition FindOptimalSpillingPos(LiveRange* range,
LifetimePosition pos);
void Spill(LiveRange* range);
bool IsBlockBoundary(LifetimePosition pos);
......
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