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

Commit

Permalink
Fix to issue 8287.
Browse files Browse the repository at this point in the history
  • Loading branch information
sivarv committed Dec 8, 2016
1 parent 4d35a3a commit becd12d
Showing 1 changed file with 27 additions and 42 deletions.
69 changes: 27 additions & 42 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

0 comments on commit becd12d

Please sign in to comment.