@@ -275,30 +275,60 @@ 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;
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>
38803911void 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))))
0 commit comments