Skip to content

Commit 6db2ad5

Browse files
Reduce cost of working on fixedRegs.
1 parent 889d514 commit 6db2ad5

File tree

2 files changed

+105
-27
lines changed

2 files changed

+105
-27
lines changed

src/coreclr/jit/lsra.cpp

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -275,30 +275,60 @@ SingleTypeRegSet LinearScan::lowSIMDRegs()
275275
#endif
276276
}
277277

278+
template <bool isLow>
278279
void LinearScan::updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill)
279280
{
280281
LsraLocation nextLocation = nextRefPosition == nullptr ? MaxLocation : nextRefPosition->nodeLocation;
281282

282283
RefPosition* kill = nextKill;
283284
while ((kill != nullptr) && (kill->nodeLocation < nextLocation))
284285
{
285-
if (kill->killedRegisters.IsRegNumInMask(regRecord->regNum))
286+
if (isLow)
286287
{
287-
nextLocation = kill->nodeLocation;
288-
break;
288+
if ((kill->killedRegisters.getLow() & genSingleTypeRegMask(regRecord->regNum)) != RBM_NONE)
289+
{
290+
nextLocation = kill->nodeLocation;
291+
break;
292+
}
289293
}
290-
294+
#ifdef HAS_MORE_THAN_64_REGISTERS
295+
else
296+
{
297+
if ((kill->killedRegisters.getHigh() &
298+
genSingleTypeRegMask((regNumber)(regRecord->regNum - REG_HIGH_BASE))) != RBM_NONE)
299+
{
300+
nextLocation = kill->nodeLocation;
301+
break;
302+
}
303+
}
304+
#endif
291305
kill = kill->nextRefPosition;
292306
}
293307

294-
if (nextLocation == MaxLocation)
308+
if (isLow)
295309
{
296-
fixedRegs.RemoveRegNumFromMask(regRecord->regNum);
310+
if (nextLocation == MaxLocation)
311+
{
312+
fixedRegsLow &= ~genSingleTypeRegMask(regRecord->regNum);
313+
}
314+
else
315+
{
316+
fixedRegsLow |= genSingleTypeRegMask(regRecord->regNum);
317+
}
297318
}
319+
#ifdef HAS_MORE_THAN_64_REGISTERS
298320
else
299321
{
300-
fixedRegs.AddRegNumInMask(regRecord->regNum);
322+
if (nextLocation == MaxLocation)
323+
{
324+
fixedRegsHigh &= ~genSingleTypeRegMask((regNumber)(regRecord->regNum - REG_HIGH_BASE));
325+
}
326+
else
327+
{
328+
fixedRegsHigh |= genSingleTypeRegMask((regNumber)(regRecord->regNum - REG_HIGH_BASE));
329+
}
301330
}
331+
#endif
302332

303333
nextFixedRef[regRecord->regNum] = nextLocation;
304334
}
@@ -3857,10 +3887,10 @@ void LinearScan::processKills(RefPosition* killRefPosition)
38573887

38583888
regMaskTP killedRegs = killRefPosition->getKilledRegisters();
38593889

3860-
freeKilledRegs(killRefPosition, killedRegs.getLow(), nextKill, REG_LOW_BASE);
3890+
freeKilledRegs<true>(killRefPosition, killedRegs.getLow(), nextKill, REG_LOW_BASE);
38613891

38623892
#ifdef HAS_MORE_THAN_64_REGISTERS
3863-
freeKilledRegs(killRefPosition, killedRegs.getHigh(), nextKill, REG_HIGH_BASE);
3893+
freeKilledRegs<false>(killRefPosition, killedRegs.getHigh(), nextKill, REG_HIGH_BASE);
38643894
#endif
38653895

38663896
regsBusyUntilKill &= ~killRefPosition->getKilledRegisters();
@@ -3877,6 +3907,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
38773907
// nextKill - The RefPosition for next kill
38783908
// regBase - `0` or `64` based on the `killedRegs` being processed
38793909
//
3910+
template <bool isLow>
38803911
void LinearScan::freeKilledRegs(RefPosition* killRefPosition,
38813912
SingleTypeRegSet killedRegs,
38823913
RefPosition* nextKill,
@@ -3899,7 +3930,7 @@ void LinearScan::freeKilledRegs(RefPosition* killRefPosition,
38993930
RefPosition* regNextRefPos = regRecord->recentRefPosition == nullptr
39003931
? regRecord->firstRefPosition
39013932
: regRecord->recentRefPosition->nextRefPosition;
3902-
updateNextFixedRef(regRecord, regNextRefPos, nextKill);
3933+
updateNextFixedRef<isLow>(regRecord, regNextRefPos, nextKill);
39033934
}
39043935
}
39053936

@@ -4862,7 +4893,7 @@ void LinearScan::allocateRegistersMinimal()
48624893
{
48634894
RegRecord* physRegRecord = getRegisterRecord(reg);
48644895
physRegRecord->recentRefPosition = nullptr;
4865-
updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead);
4896+
updateNextFixedRefDispatch(physRegRecord, physRegRecord->firstRefPosition, killHead);
48664897
assert(physRegRecord->assignedInterval == nullptr);
48674898
}
48684899

@@ -5080,8 +5111,7 @@ void LinearScan::allocateRegistersMinimal()
50805111
{
50815112
RegRecord* regRecord = currentRefPosition.getReg();
50825113
Interval* assignedInterval = regRecord->assignedInterval;
5083-
5084-
updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill);
5114+
updateNextFixedRefDispatch(regRecord, currentRefPosition.nextRefPosition, nextKill);
50855115

50865116
// This is a FixedReg. Disassociate any inactive constant interval from this register.
50875117
if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
@@ -5526,7 +5556,7 @@ void LinearScan::allocateRegisters()
55265556
{
55275557
RegRecord* physRegRecord = getRegisterRecord(reg);
55285558
physRegRecord->recentRefPosition = nullptr;
5529-
updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead);
5559+
updateNextFixedRefDispatch(physRegRecord, physRegRecord->firstRefPosition, killHead);
55305560

55315561
// Is this an incoming arg register? (Note that we don't, currently, consider reassigning
55325562
// an incoming arg register as having spill cost.)
@@ -5794,8 +5824,7 @@ void LinearScan::allocateRegisters()
57945824
{
57955825
RegRecord* regRecord = currentRefPosition.getReg();
57965826
Interval* assignedInterval = regRecord->assignedInterval;
5797-
5798-
updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill);
5827+
updateNextFixedRefDispatch(regRecord, currentRefPosition.nextRefPosition, nextKill);
57995828

58005829
// This is a FixedReg. Disassociate any inactive constant interval from this register.
58015830
if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
@@ -13593,14 +13622,29 @@ SingleTypeRegSet LinearScan::RegisterSelection::select(Interval*
1359313622
// Also eliminate as busy any register with a conflicting fixed reference at this or
1359413623
// the next location.
1359513624
// Note that this will eliminate the fixedReg, if any, but we'll add it back below.
13596-
SingleTypeRegSet checkConflictMask = candidates & linearScan->fixedRegs.GetRegSetForType(regType);
13625+
SingleTypeRegSet checkConflictMask = candidates;
13626+
int regBase = REG_LOW_BASE;
13627+
#ifdef HAS_MORE_THAN_64_REGISTERS
13628+
if (!varTypeIsMask(regType))
13629+
{
13630+
checkConflictMask &= linearScan->fixedRegsLow;
13631+
}
13632+
else
13633+
{
13634+
regBase = REG_HIGH_BASE;
13635+
checkConflictMask &= linearScan->fixedRegsHigh;
13636+
}
13637+
#else
13638+
checkConflictMask &= linearScan->fixedRegsLow;
13639+
#endif
1359713640
while (checkConflictMask != RBM_NONE)
1359813641
{
13599-
regNumber checkConflictReg = genFirstRegNumFromMask(checkConflictMask, regType);
13600-
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictReg);
13642+
regNumber checkConflictRegSingle = (regNumber)BitOperations::BitScanForward(checkConflictMask);
13643+
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictRegSingle);
1360113644
checkConflictMask ^= checkConflictBit;
1360213645

13603-
LsraLocation checkConflictLocation = linearScan->nextFixedRef[checkConflictReg];
13646+
LsraLocation checkConflictLocation =
13647+
linearScan->nextFixedRef[(regNumber)(checkConflictRegSingle + regBase)];
1360413648

1360513649
if ((checkConflictLocation == refPosition->nodeLocation) ||
1360613650
(refPosition->delayRegFree && (checkConflictLocation == (refPosition->nodeLocation + 1))))
@@ -13912,14 +13956,28 @@ SingleTypeRegSet LinearScan::RegisterSelection::selectMinimal(
1391213956
// Also eliminate as busy any register with a conflicting fixed reference at this or
1391313957
// the next location.
1391413958
// Note that this will eliminate the fixedReg, if any, but we'll add it back below.
13915-
SingleTypeRegSet checkConflictMask = candidates & linearScan->fixedRegs.GetRegSetForType(regType);
13959+
SingleTypeRegSet checkConflictMask = candidates;
13960+
int regBase = REG_LOW_BASE;
13961+
#ifdef HAS_MORE_THAN_64_REGISTERS
13962+
if (!varTypeIsMask(regType))
13963+
{
13964+
checkConflictMask &= linearScan->fixedRegsLow;
13965+
}
13966+
else
13967+
{
13968+
regBase = REG_HIGH_BASE;
13969+
checkConflictMask &= linearScan->fixedRegsHigh;
13970+
}
13971+
#else
13972+
checkConflictMask &= linearScan->fixedRegsLow;
13973+
#endif
1391613974
while (checkConflictMask != RBM_NONE)
1391713975
{
13918-
regNumber checkConflictReg = genFirstRegNumFromMask(checkConflictMask, regType);
13919-
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictReg);
13976+
regNumber checkConflictRegSingle = (regNumber)BitOperations::BitScanForward(checkConflictMask);
13977+
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictRegSingle);
1392013978
checkConflictMask ^= checkConflictBit;
1392113979

13922-
LsraLocation checkConflictLocation = linearScan->nextFixedRef[checkConflictReg];
13980+
LsraLocation checkConflictLocation = linearScan->nextFixedRef[(regNumber)(checkConflictRegSingle + regBase)];
1392313981

1392413982
if ((checkConflictLocation == refPosition->nodeLocation) ||
1392513983
(refPosition->delayRegFree && (checkConflictLocation == (refPosition->nodeLocation + 1))))

src/coreclr/jit/lsra.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,8 @@ class LinearScan : public LinearScanInterface
11951195
void setIntervalAsSplit(Interval* interval);
11961196
void spillInterval(Interval* interval, RefPosition* fromRefPosition DEBUGARG(RefPosition* toRefPosition));
11971197

1198-
void processKills(RefPosition* killRefPosition);
1198+
void processKills(RefPosition* killRefPosition);
1199+
template <bool isLow>
11991200
FORCEINLINE void freeKilledRegs(RefPosition* killRefPosition,
12001201
SingleTypeRegSet killedRegs,
12011202
RefPosition* nextKill,
@@ -1822,9 +1823,28 @@ class LinearScan : public LinearScanInterface
18221823
}
18231824
SingleTypeRegSet getMatchingConstants(SingleTypeRegSet mask, Interval* currentInterval, RefPosition* refPosition);
18241825

1825-
regMaskTP fixedRegs;
1826+
SingleTypeRegSet fixedRegsLow;
1827+
#ifdef HAS_MORE_THAN_64_REGISTERS
1828+
SingleTypeRegSet fixedRegsHigh;
1829+
#endif
18261830
LsraLocation nextFixedRef[REG_COUNT];
1827-
void updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill);
1831+
template <bool isLow>
1832+
void updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill);
1833+
void updateNextFixedRefDispatch(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill)
1834+
{
1835+
#ifdef HAS_MORE_THAN_64_REGISTERS
1836+
if (regRecord->regNum < 64)
1837+
{
1838+
updateNextFixedRef<true>(regRecord, nextRefPosition, nextKill);
1839+
}
1840+
else
1841+
{
1842+
updateNextFixedRef<false>(regRecord, nextRefPosition, nextKill);
1843+
}
1844+
#else
1845+
updateNextFixedRef<true>(regRecord, nextRefPosition, nextKill);
1846+
#endif
1847+
}
18281848
LsraLocation getNextFixedRef(regNumber regNum, var_types regType)
18291849
{
18301850
LsraLocation loc = nextFixedRef[regNum];

0 commit comments

Comments
 (0)