mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 825447 - Populate safepoints directly in backtracking register allocator, r=jandem.
This commit is contained in:
parent
d045dbdfe2
commit
8545f79247
@ -140,7 +140,7 @@ BacktrackingAllocator::go()
|
||||
if (IonSpewEnabled(IonSpew_RegAlloc))
|
||||
dumpAllocations();
|
||||
|
||||
return resolveControlFlow() && reifyAllocations();
|
||||
return resolveControlFlow() && reifyAllocations() && populateSafepoints();
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1021,6 +1021,8 @@ BacktrackingAllocator::reifyAllocations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addLiveRegistersForInterval(reg, interval);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1028,6 +1030,79 @@ BacktrackingAllocator::reifyAllocations()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BacktrackingAllocator::populateSafepoints()
|
||||
{
|
||||
size_t firstSafepoint = 0;
|
||||
|
||||
for (uint32_t i = 0; i < vregs.numVirtualRegisters(); i++) {
|
||||
BacktrackingVirtualRegister *reg = &vregs[i];
|
||||
|
||||
if (!reg->def() || (!IsTraceable(reg) && !IsNunbox(reg)))
|
||||
continue;
|
||||
|
||||
firstSafepoint = findFirstSafepoint(reg->getInterval(0), firstSafepoint);
|
||||
if (firstSafepoint >= graph.numSafepoints())
|
||||
break;
|
||||
|
||||
// Find the furthest endpoint.
|
||||
CodePosition end = reg->getInterval(0)->end();
|
||||
for (size_t j = 1; j < reg->numIntervals(); j++)
|
||||
end = Max(end, reg->getInterval(j)->end());
|
||||
|
||||
for (size_t j = firstSafepoint; j < graph.numSafepoints(); j++) {
|
||||
LInstruction *ins = graph.getSafepoint(j);
|
||||
|
||||
// Stop processing safepoints if we know we're out of this virtual
|
||||
// register's range.
|
||||
if (end < inputOf(ins))
|
||||
break;
|
||||
|
||||
// Include temps but not instruction outputs. Also make sure MUST_REUSE_INPUT
|
||||
// is not used with gcthings or nunboxes, or we would have to add the input reg
|
||||
// to this safepoint.
|
||||
if (ins == reg->ins() && !reg->isTemp()) {
|
||||
DebugOnly<LDefinition*> def = reg->def();
|
||||
JS_ASSERT_IF(def->policy() == LDefinition::MUST_REUSE_INPUT,
|
||||
def->type() == LDefinition::GENERAL || def->type() == LDefinition::DOUBLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
|
||||
LiveInterval *interval = reg->intervalFor(inputOf(ins));
|
||||
if (!interval)
|
||||
continue;
|
||||
|
||||
LAllocation *a = interval->getAllocation();
|
||||
if (a->isGeneralReg() && ins->isCall())
|
||||
continue;
|
||||
|
||||
switch (reg->type()) {
|
||||
case LDefinition::OBJECT:
|
||||
safepoint->addGcPointer(*a);
|
||||
break;
|
||||
#ifdef JS_NUNBOX32
|
||||
case LDefinition::TYPE:
|
||||
safepoint->addNunboxType(i, *a);
|
||||
break;
|
||||
case LDefinition::PAYLOAD:
|
||||
safepoint->addNunboxPayload(i, *a);
|
||||
break;
|
||||
#else
|
||||
case LDefinition::BOX:
|
||||
safepoint->addBoxedValue(*a);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
JS_NOT_REACHED("Bad register type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BacktrackingAllocator::dumpRegisterGroups()
|
||||
{
|
||||
|
@ -201,6 +201,7 @@ class BacktrackingAllocator : public LiveRangeAllocator<BacktrackingVirtualRegis
|
||||
|
||||
bool resolveControlFlow();
|
||||
bool reifyAllocations();
|
||||
bool populateSafepoints();
|
||||
|
||||
void dumpRegisterGroups();
|
||||
void dumpLiveness();
|
||||
|
@ -1001,13 +1001,17 @@ CompileBackEnd(MIRGenerator *mir)
|
||||
}
|
||||
|
||||
case RegisterAllocator_Backtracking: {
|
||||
#ifdef DEBUG
|
||||
integrity.record();
|
||||
#endif
|
||||
|
||||
BacktrackingAllocator regalloc(mir, &lirgen, *lir);
|
||||
if (!regalloc.go())
|
||||
return NULL;
|
||||
if (!integrity.check(true))
|
||||
return NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
integrity.check(false);
|
||||
#endif
|
||||
|
||||
IonSpewPass("Allocate Registers [Backtracking]");
|
||||
break;
|
||||
|
@ -422,31 +422,7 @@ LinearScanAllocator::reifyAllocations()
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the live register sets for all non-call safepoints.
|
||||
LAllocation *a = interval->getAllocation();
|
||||
if (a->isRegister()) {
|
||||
// Don't add output registers to the safepoint.
|
||||
CodePosition start = interval->start();
|
||||
if (interval->index() == 0 && !reg->isTemp())
|
||||
start = start.next();
|
||||
|
||||
size_t i = findFirstNonCallSafepoint(start);
|
||||
for (; i < graph.numNonCallSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getNonCallSafepoint(i);
|
||||
CodePosition pos = inputOf(ins);
|
||||
|
||||
// Safepoints are sorted, so we can shortcut out of this loop
|
||||
// if we go out of range.
|
||||
if (interval->end() < pos)
|
||||
break;
|
||||
|
||||
if (!interval->covers(pos))
|
||||
continue;
|
||||
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
safepoint->addLiveRegister(a->toRegister());
|
||||
}
|
||||
}
|
||||
addLiveRegistersForInterval(reg, interval);
|
||||
}} // Iteration over virtual register intervals.
|
||||
|
||||
// Set the graph overall stack height
|
||||
@ -455,31 +431,6 @@ LinearScanAllocator::reifyAllocations()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Finds the first safepoint that is within range of an interval.
|
||||
size_t
|
||||
LinearScanAllocator::findFirstSafepoint(LiveInterval *interval, size_t startFrom)
|
||||
{
|
||||
size_t i = startFrom;
|
||||
for (; i < graph.numSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getSafepoint(i);
|
||||
if (interval->start() <= inputOf(ins))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t
|
||||
LinearScanAllocator::findFirstNonCallSafepoint(CodePosition from)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; i < graph.numNonCallSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getNonCallSafepoint(i);
|
||||
if (from <= inputOf(ins))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline bool
|
||||
LinearScanAllocator::isSpilledAt(LiveInterval *interval, CodePosition pos)
|
||||
{
|
||||
|
@ -110,8 +110,6 @@ class LinearScanAllocator : public LiveRangeAllocator<LinearScanVirtualRegister>
|
||||
bool canCoexist(LiveInterval *a, LiveInterval *b);
|
||||
bool moveInputAlloc(CodePosition pos, LAllocation *from, LAllocation *to);
|
||||
void setIntervalRequirement(LiveInterval *interval);
|
||||
size_t findFirstSafepoint(LiveInterval *interval, size_t firstSafepoint);
|
||||
size_t findFirstNonCallSafepoint(CodePosition from);
|
||||
bool isSpilledAt(LiveInterval *interval, CodePosition pos);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -603,6 +603,48 @@ class LiveRangeAllocator : public RegisterAllocator
|
||||
LMoveGroup *moves = getMoveGroupAfter(pos);
|
||||
return addMove(moves, from, to);
|
||||
}
|
||||
|
||||
void addLiveRegistersForInterval(VirtualRegister *reg, LiveInterval *interval)
|
||||
{
|
||||
// Fill in the live register sets for all non-call safepoints.
|
||||
LAllocation *a = interval->getAllocation();
|
||||
if (!a->isRegister())
|
||||
return;
|
||||
|
||||
// Don't add output registers to the safepoint.
|
||||
CodePosition start = interval->start();
|
||||
if (interval->index() == 0 && !reg->isTemp())
|
||||
start = start.next();
|
||||
|
||||
size_t i = findFirstNonCallSafepoint(start);
|
||||
for (; i < graph.numNonCallSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getNonCallSafepoint(i);
|
||||
CodePosition pos = inputOf(ins);
|
||||
|
||||
// Safepoints are sorted, so we can shortcut out of this loop
|
||||
// if we go out of range.
|
||||
if (interval->end() < pos)
|
||||
break;
|
||||
|
||||
if (!interval->covers(pos))
|
||||
continue;
|
||||
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
safepoint->addLiveRegister(a->toRegister());
|
||||
}
|
||||
}
|
||||
|
||||
// Finds the first safepoint that is within range of an interval.
|
||||
size_t findFirstSafepoint(LiveInterval *interval, size_t startFrom)
|
||||
{
|
||||
size_t i = startFrom;
|
||||
for (; i < graph.numSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getSafepoint(i);
|
||||
if (interval->start() <= inputOf(ins))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ion
|
||||
|
@ -336,6 +336,17 @@ class RegisterAllocator
|
||||
LMoveGroup *getMoveGroupAfter(CodePosition pos) {
|
||||
return getMoveGroupAfter(pos.ins());
|
||||
}
|
||||
|
||||
size_t findFirstNonCallSafepoint(CodePosition from)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; i < graph.numNonCallSafepoints(); i++) {
|
||||
LInstruction *ins = graph.getNonCallSafepoint(i);
|
||||
if (from <= inputOf(ins))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ion
|
||||
|
Loading…
Reference in New Issue
Block a user