Skip to content
Closed
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
73 changes: 73 additions & 0 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9714,6 +9714,21 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
}
}

#ifdef DEBUG
if (compiler->verbose)
{
printf("Resolving Edge: ");
if (fromBlock != nullptr)
{
printf("from: " FMT_BB " ", fromBlock->bbNum);
}
if (toBlock != nullptr)
{
printf("to: " FMT_BB, toBlock->bbNum);
}
}
#endif // DEBUG

// First:
// - Perform all moves from reg to stack (no ordering needed on these)
// - For reg to reg moves, record the current location, associating their
Expand Down Expand Up @@ -9776,6 +9791,18 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
source[toReg] = (regNumberSmall)fromReg;
sourceIntervals[fromReg] = interval;
targetRegsToDo |= genRegMask(toReg);

#ifdef DEBUG
if (compiler->verbose)
{
printf("Added ");
interval->tinyDump();
printf(" for %s -> %s (%s). targetRegsToDo= ", getRegName(fromReg), getRegName(toReg),
((interval->registerType == TYP_DOUBLE) ? "double" : "float"));
compiler->dumpRegMask(targetRegsToDo.getLow(), TYP_FLOAT);
printf("\n");
}
#endif // DEBUG
}
}

Expand Down Expand Up @@ -9839,10 +9866,30 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
// Perform reg to reg moves
while (targetRegsToDo.IsNonEmpty())
{
#ifdef DEBUG
if (compiler->verbose)
{
printf("targetRegsToDo: ");
compiler->dumpRegMask(targetRegsToDo);
printf("\n");
}
#endif // DEBUG
while (targetRegsReady.IsNonEmpty())
{
regNumber targetReg = genFirstRegNumFromMaskAndToggle(targetRegsReady);
targetRegsToDo.RemoveRegNumFromMask(targetReg);
#ifdef DEBUG
if (compiler->verbose)
{
printf("targetReg: %s, ", getRegName(targetReg));
printf("targetRegsReady: ");
compiler->dumpRegMask(targetRegsReady);
printf(", targetRegsToDo: ");
compiler->dumpRegMask(targetRegsToDo);
printf("\n");
}
#endif // DEBUG

assert(location[targetReg] != targetReg);
assert(targetReg < REG_COUNT);
regNumber sourceReg = (regNumber)source[targetReg];
Expand All @@ -9854,6 +9901,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
assert(interval != nullptr);
addResolution(block, insertionPoint, interval, targetReg,
fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType]));

sourceIntervals[sourceReg] = nullptr;
location[sourceReg] = REG_NA;

Expand Down Expand Up @@ -10062,6 +10110,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
{
compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(true));
#ifdef TARGET_ARM
regNumber originDoubleReg = REG_NA;
Interval* otherTargetInterval = nullptr;
regNumber otherHalfTargetReg = REG_NA;
if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg))
Expand All @@ -10076,6 +10125,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,

addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg, targetReg,
resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock));
originDoubleReg = targetReg;
}
else if (otherTargetInterval != nullptr)
{
Expand All @@ -10084,6 +10134,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,

addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg,
otherHalfTargetReg, resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock));
originDoubleReg = otherHalfTargetReg;
}
else
{
Expand All @@ -10092,8 +10143,30 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg,
targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)
DEBUG_ARG(resolveTypeName[resolveType]));

if (sourceIntervals[targetReg]->registerType == TYP_DOUBLE)
{
originDoubleReg = targetReg;
}

location[targetReg] = (regNumberSmall)tempReg;
}

if (originDoubleReg != REG_NA)
{
// There was a value in originDoubleReg, which we free-up by moving it to
// tempReg. As such, make sure to free-up the upper-half too, only if
// originDoubleReg held DOUBLE interval and upper-half is target of a
// different interval.
assert(genIsValidDoubleReg(originDoubleReg));
targetRegMask |= genRegMask(originDoubleReg);

regNumber upperHalfReg = REG_NEXT(originDoubleReg);
if (targetRegsToDo.IsRegNumInMask(upperHalfReg))
{
targetRegMask |= genRegMask(upperHalfReg);
}
}
#else
assert(sourceIntervals[targetReg] != nullptr);

Expand Down
Loading