mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 905091 part 1 - Fix Ion regalloc to not insert movegroups between an instruction and its OsiPoint. r=bhackett
This commit is contained in:
parent
a887a977e6
commit
ff5d640943
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user