Skip to content

Commit ece807a

Browse files
authored
Linux/arm: LSRA resolution issues (#109173)
* Revert "Arm: Free up upper-half register that was not ready because of its association with busy lower-half register (#107714)" This reverts commit f1bcbeb. * Revert "Arm: Consider the fact that targetReg can be second half during resolution (#107493)" This reverts commit ac4b7c6. * wip * clean up * Introduce addOtherHalfRegToReady() to share logic * Add test case * jit format * remove the assert that is no longer valid
1 parent 8886107 commit ece807a

File tree

3 files changed

+518
-33
lines changed

3 files changed

+518
-33
lines changed

src/coreclr/jit/lsra.cpp

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9613,6 +9613,29 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
96139613
}
96149614
}
96159615

9616+
#ifdef TARGET_ARM
9617+
auto addOtherHalfRegToReady = [&](regNumber otherHalfReg) {
9618+
// For a double interval, if the first half if freed up, check if the other
9619+
// half can also be freed (if it is a target for resolution).
9620+
9621+
regNumber otherHalfSrcReg = (regNumber)source[otherHalfReg];
9622+
regNumber otherHalfSrcLoc = (regNumber)location[otherHalfReg];
9623+
9624+
// Necessary conditions:
9625+
// - There is a source register for this reg (otherHalfSrcReg != REG_NA)
9626+
// - It is currently free (otherHalfSrcLoc == REG_NA)
9627+
// - The source interval isn't yet completed (sourceIntervals[otherHalfSrcReg] != nullptr)
9628+
// - It's in the TODO set (targetRegsToDo.IsRegNumInMask(otherHalfReg))
9629+
// - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(otherHalfReg))
9630+
if ((otherHalfSrcReg != REG_NA) && (otherHalfSrcLoc == REG_NA) &&
9631+
(sourceIntervals[otherHalfSrcReg] != nullptr) && targetRegsToDo.IsRegNumInMask(otherHalfReg) &&
9632+
!targetRegsFromStack.IsRegNumInMask(otherHalfReg))
9633+
{
9634+
targetRegsReady.AddRegNumInMask(otherHalfReg);
9635+
}
9636+
};
9637+
#endif // TARGET_ARM
9638+
96169639
// Perform reg to reg moves
96179640
while (targetRegsToDo.IsNonEmpty())
96189641
{
@@ -9654,48 +9677,18 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
96549677
}
96559678

96569679
// Since we want to check if we can free upperHalfReg, only do it
9657-
// if lowerHalfReg is ready.
9680+
// if lowerHalfReg is ready and it is one of the target candidate.
96589681
if (targetRegsReady.IsRegNumInMask(fromReg))
96599682
{
9660-
regNumber upperHalfSrcReg = (regNumber)source[upperHalfReg];
9661-
regNumber upperHalfSrcLoc = (regNumber)location[upperHalfReg];
9662-
// Necessary conditions:
9663-
// - There is a source register for this reg (upperHalfSrcReg != REG_NA)
9664-
// - It is currently free (upperHalfSrcLoc == REG_NA)
9665-
// - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr)
9666-
// - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9667-
if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) &&
9668-
(sourceIntervals[upperHalfSrcReg] != nullptr) &&
9669-
!targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9670-
{
9671-
targetRegsReady.AddRegNumInMask(upperHalfReg);
9672-
}
9683+
addOtherHalfRegToReady(upperHalfReg);
96739684
}
96749685
}
96759686
}
96769687
else if (genIsValidFloatReg(fromReg) && !genIsValidDoubleReg(fromReg))
96779688
{
96789689
// We may have freed up the other half of a double where the lower half
96799690
// was already free.
9680-
regNumber lowerHalfReg = REG_PREV(fromReg);
9681-
regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg];
9682-
regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg];
9683-
// Necessary conditions:
9684-
// - There is a source register for this reg (lowerHalfSrcReg != REG_NA)
9685-
// - It is currently free (lowerHalfSrcLoc == REG_NA)
9686-
// - The source interval isn't yet completed (sourceIntervals[lowerHalfSrcReg] != nullptr)
9687-
// - It's not in the ready set (!targetRegsReady.IsRegNumInMask(lowerHalfReg))
9688-
// - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
9689-
if ((lowerHalfSrcReg != REG_NA) && (lowerHalfSrcLoc == REG_NA) &&
9690-
(sourceIntervals[lowerHalfSrcReg] != nullptr) &&
9691-
!targetRegsReady.IsRegNumInMask(lowerHalfReg) &&
9692-
!targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
9693-
{
9694-
// This must be a double interval, otherwise it would be in targetRegsReady, or already
9695-
// completed.
9696-
assert(sourceIntervals[lowerHalfSrcReg]->registerType == TYP_DOUBLE);
9697-
targetRegsReady.AddRegNumInMask(lowerHalfReg);
9698-
}
9691+
addOtherHalfRegToReady(REG_PREV(fromReg));
96999692
#endif // TARGET_ARM
97009693
}
97019694
}
@@ -9870,6 +9863,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
98709863
targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)
98719864
DEBUG_ARG(resolveTypeName[resolveType]));
98729865
location[targetReg] = (regNumberSmall)tempReg;
9866+
9867+
if (sourceIntervals[targetReg]->registerType == TYP_DOUBLE)
9868+
{
9869+
// Free up upperHalf reg of this targetReg, if it is one of the target candidate.
9870+
9871+
assert(genIsValidDoubleReg(targetReg));
9872+
addOtherHalfRegToReady(REG_NEXT(targetReg));
9873+
}
98739874
}
98749875
#else
98759876
assert(sourceIntervals[targetReg] != nullptr);

0 commit comments

Comments
 (0)