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
This commit is contained in:
parent
9f7300043b
commit
ae064fca48
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user