@@ -275,30 +275,66 @@ SingleTypeRegSet LinearScan::lowSIMDRegs()
275275#endif
276276}
277277
278+ template <bool isLow>
278279void 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>
38803917void 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))))
0 commit comments