Skip to content
Open
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
78 changes: 74 additions & 4 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12985,8 +12985,69 @@ void LinearScan::RegisterSelection::try_REG_ORDER()
// This will always result in a single candidate. That is, it is the tie-breaker
// for free candidates, and doesn't make sense as anything other than the last
// heuristic for free registers.
unsigned lowestRegOrder = UINT_MAX;
SingleTypeRegSet lowestRegOrderBit = RBM_NONE;
#ifdef TARGET_ARM64
// These groups preserve REG_VAR_ORDER and REG_VAR_ORDER_FLT. Select from
// the first nonempty group instead of visiting every candidate's rank.
SingleTypeRegSet preferred;
SingleTypeRegSet lowestRegOrderBit;
if (varTypeUsesFloatReg(regType))
{
// Mask off V0-V15 to select the V16-V31 group.
preferred = candidates & (RBM_ALLFLOAT.GetFloatRegSet() & ~((1ULL << REG_V16) - 1));
if (preferred != RBM_NONE)
{
lowestRegOrderBit = genFindLowestBit(preferred);
}
else
{
preferred = candidates & (RBM_V4 | RBM_V5 | RBM_V6 | RBM_V7).GetFloatRegSet();
if (preferred != RBM_NONE)
{
// V7..V4 are preferred in descending register-number order.
lowestRegOrderBit = 1ULL << BitOperations::BitScanReverse(preferred);
}
else
{
preferred =
candidates &
(RBM_V8 | RBM_V9 | RBM_V10 | RBM_V11 | RBM_V12 | RBM_V13 | RBM_V14 | RBM_V15).GetFloatRegSet();
if (preferred != RBM_NONE)
{
lowestRegOrderBit = genFindLowestBit(preferred);
}
else
{
// The remaining floating-point registers are V3..V0.
lowestRegOrderBit = 1ULL << BitOperations::BitScanReverse(candidates);
}
}
}
}
else if (varTypeIsMask(regType))
{
// ARM64 predicate registers have equal regOrder ranks.
lowestRegOrderBit = genFindLowestBit(candidates);
}
else
{
preferred = candidates & (((1ULL << REG_R12) - 1) | (RBM_R13 | RBM_R14).GetIntRegSet());
if (preferred == RBM_NONE)
{
// After R13/R14, the remaining ranked registers are in ascending order.
preferred = candidates & RBM_ALLINT.GetIntRegSet();
if (preferred == RBM_NONE)
{
// Registers absent from REG_VAR_ORDER retain the same last rank.
preferred = candidates;
}
}
lowestRegOrderBit = genFindLowestBit(preferred);
}
#endif // TARGET_ARM64

#if !defined(TARGET_ARM64) || defined(DEBUG)
unsigned lowestRegOrder = UINT_MAX;
regNumber lowestReg = REG_NA;
for (SingleTypeRegSet regOrderCandidates = candidates; regOrderCandidates != RBM_NONE;)
{
regNumber regOrderCandidateRegNum = genFirstRegNumFromMask(regOrderCandidates, regType);
Expand All @@ -12996,10 +13057,19 @@ void LinearScan::RegisterSelection::try_REG_ORDER()
unsigned thisRegOrder = linearScan->getRegisterRecord(regOrderCandidateRegNum)->regOrder;
if (thisRegOrder < lowestRegOrder)
{
lowestRegOrder = thisRegOrder;
lowestRegOrderBit = regOrderCandidateBit;
lowestRegOrder = thisRegOrder;
lowestReg = regOrderCandidateRegNum;
}
}
assert(lowestReg != REG_NA);
SingleTypeRegSet scannedRegOrderBit = genSingleTypeRegMask(lowestReg);
#ifdef TARGET_ARM64
// Check the grouped selection against the rank scan, including stress modes.
assert(lowestRegOrderBit == scannedRegOrderBit);
#else
SingleTypeRegSet lowestRegOrderBit = scannedRegOrderBit;
#endif
#endif // !TARGET_ARM64 || DEBUG
assert(lowestRegOrderBit != RBM_NONE);
found = applySingleRegSelection(REG_ORDER, lowestRegOrderBit);
}
Expand Down
Loading