Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Fix to issue 8286. #8532

Merged
merged 1 commit into from
Dec 12, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 39 additions & 43 deletions src/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7191,59 +7191,44 @@ void LinearScan::allocateRegisters()
assert(currentInterval != nullptr);

// It's already in a register, but not one we need.
// If it is a fixed use that is not marked "delayRegFree", there is already a FixedReg to ensure that
// the needed reg is not otherwise in use, so we can simply ignore it and codegen will do the copy.
// The reason we need special handling for the "delayRegFree" case is that we need to mark the
// fixed-reg as in-use and delayed (the FixedReg RefPosition doesn't handle the delay requirement).
// Otherwise, if this is a pure use localVar or tree temp, we assign a copyReg, but must free both regs
// if it is a last use.
if (!currentRefPosition->isFixedRegRef || currentRefPosition->delayRegFree)
{
if (!RefTypeIsDef(currentRefPosition->refType))
if (!RefTypeIsDef(currentRefPosition->refType))
{
regNumber copyReg = assignCopyReg(currentRefPosition);
assert(copyReg != REG_NA);
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
lastAllocatedRefPosition = currentRefPosition;
if (currentRefPosition->lastUse)
{
regNumber copyReg = assignCopyReg(currentRefPosition);
assert(copyReg != REG_NA);
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
lastAllocatedRefPosition = currentRefPosition;
if (currentRefPosition->lastUse)
if (currentRefPosition->delayRegFree)
{
if (currentRefPosition->delayRegFree)
{
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
assignedRegister));
delayRegsToFree |=
(genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
else
{
INDEBUG(
dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
assignedRegister));
delayRegsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
// If this is a tree temp (non-localVar) interval, we will need an explicit move.
if (!currentInterval->isLocalVar)
else
{
currentRefPosition->moveReg = true;
currentRefPosition->copyReg = false;
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
continue;
}
else
// If this is a tree temp (non-localVar) interval, we will need an explicit move.
if (!currentInterval->isLocalVar)
{
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
regsToFree |= genRegMask(assignedRegister);
// We want a new register, but we don't want this to be considered a spill.
assignedRegister = REG_NA;
if (physRegRecord->assignedInterval == currentInterval)
{
unassignPhysRegNoSpill(physRegRecord);
}
currentRefPosition->moveReg = true;
currentRefPosition->copyReg = false;
}
continue;
}
else
{
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, assignedRegister));
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
regsToFree |= genRegMask(assignedRegister);
// We want a new register, but we don't want this to be considered a spill.
assignedRegister = REG_NA;
if (physRegRecord->assignedInterval == currentInterval)
{
unassignPhysRegNoSpill(physRegRecord);
}
}
}
}
Expand Down Expand Up @@ -11725,9 +11710,18 @@ void LinearScan::verifyFinalAllocation()
{
if (VERBOSE)
{
// If refPos is marked as copyReg, then the reg that is spilled
// is the homeReg of the interval not the reg currently assigned
// to refPos.
regNumber spillReg = regNum;
if (currentRefPosition->copyReg)
{
assert(interval != nullptr);
spillReg = interval->physReg;
}
dumpRegRecords();
dumpEmptyRefPosition();
printf("Spill %-4s ", getRegName(regNum));
printf("Spill %-4s ", getRegName(spillReg));
}
}
else if (currentRefPosition->copyReg)
Expand Down Expand Up @@ -11902,6 +11896,8 @@ void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation curr
assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
leftInterval->physReg = rightRegNum;
rightInterval->physReg = leftRegNum;
leftInterval->assignedReg = &physRegs[rightRegNum];
rightInterval->assignedReg = &physRegs[leftRegNum];
physRegs[rightRegNum].assignedInterval = leftInterval;
physRegs[leftRegNum].assignedInterval = rightInterval;
if (VERBOSE)
Expand Down