Skip to content

Commit dc1d20a

Browse files
Reduce cost of working on fixedRegs by making it SingleTypeRegSet.
1 parent 889d514 commit dc1d20a

File tree

2 files changed

+111
-27
lines changed

2 files changed

+111
-27
lines changed

src/coreclr/jit/lsra.cpp

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -275,30 +275,66 @@ 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;
284+
285+
#ifdef HAS_MORE_THAN_64_REGISTERS
286+
SingleTypeRegSet regMask = isLow ? genSingleTypeRegMask(regRecord->regNum)
287+
: genSingleTypeRegMask((regNumber)(regRecord->regNum - REG_HIGH_BASE));
288+
#else
289+
SingleTypeRegSet regMask = genSingleTypeRegMask(regRecord->regNum);
290+
#endif
283291
while ((kill != nullptr) && (kill->nodeLocation < nextLocation))
284292
{
285-
if (kill->killedRegisters.IsRegNumInMask(regRecord->regNum))
293+
if (isLow)
286294
{
287-
nextLocation = kill->nodeLocation;
288-
break;
295+
if ((kill->killedRegisters.getLow() & regMask) != RBM_NONE)
296+
{
297+
nextLocation = kill->nodeLocation;
298+
break;
299+
}
289300
}
290-
301+
#ifdef HAS_MORE_THAN_64_REGISTERS
302+
else
303+
{
304+
if ((kill->killedRegisters.getHigh() & regMask) != RBM_NONE)
305+
{
306+
nextLocation = kill->nodeLocation;
307+
break;
308+
}
309+
}
310+
#endif
291311
kill = kill->nextRefPosition;
292312
}
293313

294-
if (nextLocation == MaxLocation)
314+
if (isLow)
295315
{
296-
fixedRegs.RemoveRegNumFromMask(regRecord->regNum);
316+
if (nextLocation == MaxLocation)
317+
{
318+
fixedRegsLow &= ~regMask;
319+
}
320+
else
321+
{
322+
fixedRegsLow |= regMask;
323+
}
297324
}
325+
#ifdef HAS_MORE_THAN_64_REGISTERS
298326
else
299327
{
300-
fixedRegs.AddRegNumInMask(regRecord->regNum);
328+
if (nextLocation == MaxLocation)
329+
{
330+
fixedRegsHigh &= ~regMask;
331+
}
332+
else
333+
{
334+
fixedRegsHigh |= regMask;
335+
}
301336
}
337+
#endif
302338

303339
nextFixedRef[regRecord->regNum] = nextLocation;
304340
}
@@ -3857,10 +3893,10 @@ void LinearScan::processKills(RefPosition* killRefPosition)
38573893

38583894
regMaskTP killedRegs = killRefPosition->getKilledRegisters();
38593895

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

38623898
#ifdef HAS_MORE_THAN_64_REGISTERS
3863-
freeKilledRegs(killRefPosition, killedRegs.getHigh(), nextKill, REG_HIGH_BASE);
3899+
freeKilledRegs<false>(killRefPosition, killedRegs.getHigh(), nextKill, REG_HIGH_BASE);
38643900
#endif
38653901

38663902
regsBusyUntilKill &= ~killRefPosition->getKilledRegisters();
@@ -3877,6 +3913,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
38773913
// nextKill - The RefPosition for next kill
38783914
// regBase - `0` or `64` based on the `killedRegs` being processed
38793915
//
3916+
template <bool isLow>
38803917
void LinearScan::freeKilledRegs(RefPosition* killRefPosition,
38813918
SingleTypeRegSet killedRegs,
38823919
RefPosition* nextKill,
@@ -3899,7 +3936,7 @@ void LinearScan::freeKilledRegs(RefPosition* killRefPosition,
38993936
RefPosition* regNextRefPos = regRecord->recentRefPosition == nullptr
39003937
? regRecord->firstRefPosition
39013938
: regRecord->recentRefPosition->nextRefPosition;
3902-
updateNextFixedRef(regRecord, regNextRefPos, nextKill);
3939+
updateNextFixedRef<isLow>(regRecord, regNextRefPos, nextKill);
39033940
}
39043941
}
39053942

@@ -4862,7 +4899,7 @@ void LinearScan::allocateRegistersMinimal()
48624899
{
48634900
RegRecord* physRegRecord = getRegisterRecord(reg);
48644901
physRegRecord->recentRefPosition = nullptr;
4865-
updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead);
4902+
updateNextFixedRefDispatch(physRegRecord, physRegRecord->firstRefPosition, killHead);
48664903
assert(physRegRecord->assignedInterval == nullptr);
48674904
}
48684905

@@ -5080,8 +5117,7 @@ void LinearScan::allocateRegistersMinimal()
50805117
{
50815118
RegRecord* regRecord = currentRefPosition.getReg();
50825119
Interval* assignedInterval = regRecord->assignedInterval;
5083-
5084-
updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill);
5120+
updateNextFixedRefDispatch(regRecord, currentRefPosition.nextRefPosition, nextKill);
50855121

50865122
// This is a FixedReg. Disassociate any inactive constant interval from this register.
50875123
if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
@@ -5526,7 +5562,7 @@ void LinearScan::allocateRegisters()
55265562
{
55275563
RegRecord* physRegRecord = getRegisterRecord(reg);
55285564
physRegRecord->recentRefPosition = nullptr;
5529-
updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead);
5565+
updateNextFixedRefDispatch(physRegRecord, physRegRecord->firstRefPosition, killHead);
55305566

55315567
// Is this an incoming arg register? (Note that we don't, currently, consider reassigning
55325568
// an incoming arg register as having spill cost.)
@@ -5794,8 +5830,7 @@ void LinearScan::allocateRegisters()
57945830
{
57955831
RegRecord* regRecord = currentRefPosition.getReg();
57965832
Interval* assignedInterval = regRecord->assignedInterval;
5797-
5798-
updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill);
5833+
updateNextFixedRefDispatch(regRecord, currentRefPosition.nextRefPosition, nextKill);
57995834

58005835
// This is a FixedReg. Disassociate any inactive constant interval from this register.
58015836
if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
@@ -13593,14 +13628,29 @@ SingleTypeRegSet LinearScan::RegisterSelection::select(Interval*
1359313628
// Also eliminate as busy any register with a conflicting fixed reference at this or
1359413629
// the next location.
1359513630
// Note that this will eliminate the fixedReg, if any, but we'll add it back below.
13596-
SingleTypeRegSet checkConflictMask = candidates & linearScan->fixedRegs.GetRegSetForType(regType);
13631+
SingleTypeRegSet checkConflictMask = candidates;
13632+
int regBase = REG_LOW_BASE;
13633+
#ifdef HAS_MORE_THAN_64_REGISTERS
13634+
if (!varTypeIsMask(regType))
13635+
{
13636+
checkConflictMask &= linearScan->fixedRegsLow;
13637+
}
13638+
else
13639+
{
13640+
regBase = REG_HIGH_BASE;
13641+
checkConflictMask &= linearScan->fixedRegsHigh;
13642+
}
13643+
#else
13644+
checkConflictMask &= linearScan->fixedRegsLow;
13645+
#endif
1359713646
while (checkConflictMask != RBM_NONE)
1359813647
{
13599-
regNumber checkConflictReg = genFirstRegNumFromMask(checkConflictMask, regType);
13600-
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictReg);
13648+
regNumber checkConflictRegSingle = (regNumber)BitOperations::BitScanForward(checkConflictMask);
13649+
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictRegSingle);
1360113650
checkConflictMask ^= checkConflictBit;
1360213651

13603-
LsraLocation checkConflictLocation = linearScan->nextFixedRef[checkConflictReg];
13652+
LsraLocation checkConflictLocation =
13653+
linearScan->nextFixedRef[(regNumber)(checkConflictRegSingle + regBase)];
1360413654

1360513655
if ((checkConflictLocation == refPosition->nodeLocation) ||
1360613656
(refPosition->delayRegFree && (checkConflictLocation == (refPosition->nodeLocation + 1))))
@@ -13912,14 +13962,28 @@ SingleTypeRegSet LinearScan::RegisterSelection::selectMinimal(
1391213962
// Also eliminate as busy any register with a conflicting fixed reference at this or
1391313963
// the next location.
1391413964
// Note that this will eliminate the fixedReg, if any, but we'll add it back below.
13915-
SingleTypeRegSet checkConflictMask = candidates & linearScan->fixedRegs.GetRegSetForType(regType);
13965+
SingleTypeRegSet checkConflictMask = candidates;
13966+
int regBase = REG_LOW_BASE;
13967+
#ifdef HAS_MORE_THAN_64_REGISTERS
13968+
if (!varTypeIsMask(regType))
13969+
{
13970+
checkConflictMask &= linearScan->fixedRegsLow;
13971+
}
13972+
else
13973+
{
13974+
regBase = REG_HIGH_BASE;
13975+
checkConflictMask &= linearScan->fixedRegsHigh;
13976+
}
13977+
#else
13978+
checkConflictMask &= linearScan->fixedRegsLow;
13979+
#endif
1391613980
while (checkConflictMask != RBM_NONE)
1391713981
{
13918-
regNumber checkConflictReg = genFirstRegNumFromMask(checkConflictMask, regType);
13919-
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictReg);
13982+
regNumber checkConflictRegSingle = (regNumber)BitOperations::BitScanForward(checkConflictMask);
13983+
SingleTypeRegSet checkConflictBit = genSingleTypeRegMask(checkConflictRegSingle);
1392013984
checkConflictMask ^= checkConflictBit;
1392113985

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

1392413988
if ((checkConflictLocation == refPosition->nodeLocation) ||
1392513989
(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)