Bug 905091 part 1 - Fix Ion regalloc to not insert movegroups between an instruction and its OsiPoint. r=bhackett

This commit is contained in:
Jan de Mooij 2013-08-15 16:14:41 +02:00
parent a887a977e6
commit ff5d640943
4 changed files with 33 additions and 19 deletions

View File

@ -1330,23 +1330,6 @@ BacktrackingAllocator::computePriority(const VirtualRegisterGroup *group)
return priority;
}
CodePosition
BacktrackingAllocator::minimalDefEnd(LInstruction *ins)
{
// Compute the shortest interval that captures vregs defined by ins.
// Watch for instructions that are followed by an OSI point and/or Nop.
// If moves are introduced between the instruction and the OSI point then
// safepoint information for the instruction may be incorrect. This is
// pretty disgusting and should be fixed somewhere else in the compiler.
while (true) {
LInstruction *next = insData[outputOf(ins).next()].ins();
if (!next->isNop() && !next->isOsiPoint())
break;
ins = next;
}
return outputOf(ins);
}
bool
BacktrackingAllocator::minimalDef(const LiveInterval *interval, LInstruction *ins)
{

View File

@ -212,7 +212,6 @@ class BacktrackingAllocator : public LiveRangeAllocator<BacktrackingVirtualRegis
struct PrintLiveIntervalRange;
CodePosition minimalDefEnd(LInstruction *ins);
bool minimalDef(const LiveInterval *interval, LInstruction *ins);
bool minimalUse(const LiveInterval *interval, LInstruction *ins);
bool minimalInterval(const LiveInterval *interval, bool *pfixed = NULL);

View File

@ -352,7 +352,23 @@ LinearScanAllocator::reifyAllocations()
if (def->policy() == LDefinition::PRESET && def->output()->isRegister()) {
AnyRegister fixedReg = def->output()->toRegister();
LiveInterval *from = fixedIntervals[fixedReg.code()];
if (!moveAfter(outputOf(reg->ins()), from, interval))
// Insert the move after any OsiPoint or Nop instructions
// following this one. See minimalDefEnd for more info.
CodePosition defEnd = minimalDefEnd(reg->ins());
// If we just skipped an OsiPoint, and it uses this vreg, it
// should use the fixed register instead.
for (UsePositionIterator usePos(interval->usesBegin());
usePos != interval->usesEnd();
usePos++)
{
if (usePos->pos > defEnd)
break;
*static_cast<LAllocation *>(usePos->use) = LAllocation(fixedReg);
}
if (!moveAfter(defEnd, from, interval))
return false;
spillFrom = from->getAllocation();
} else {

View File

@ -352,6 +352,22 @@ class RegisterAllocator
}
return i;
}
CodePosition minimalDefEnd(LInstruction *ins) {
// Compute the shortest interval that captures vregs defined by ins.
// Watch for instructions that are followed by an OSI point and/or Nop.
// If moves are introduced between the instruction and the OSI point then
// safepoint information for the instruction may be incorrect. This is
// pretty disgusting and should be fixed somewhere else in the compiler.
while (true) {
LInstruction *next = insData[outputOf(ins).next()].ins();
if (!next->isNop() && !next->isOsiPoint())
break;
ins = next;
}
return outputOf(ins);
}
};
static inline AnyRegister