This commit is contained in:
DeepakRajendrakumaran 2025-07-30 22:32:26 +08:00 committed by GitHub
commit 69f1548a60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 3 deletions

View File

@ -498,6 +498,35 @@ RegRecord* LinearScan::getRegisterRecord(regNumber regNum)
return &physRegs[regNum];
}
//------------------------------------------------------------------------
// getAvailableGPRsForType: Returns available general-purpose registers for the given type,
// with platform-specific restrictions applied.
//
// Arguments:
// candidates - The candidate register mask to be filtered
// regType - The register type for which we need available registers
//
// Return Value:
// A filtered register mask with platform-specific restrictions applied.
// For AMD64: GC types and long types are restricted to low GPRs only.
// For other platforms: Returns the original candidates unchanged.
//
// Notes:
// On AMD64, we don't use extended GPRs (R16-R31) for GC types to ensure
// proper GC tracking and code generation compatibility.
//
SingleTypeRegSet LinearScan::getAvailableGPRsForType(SingleTypeRegSet candidates, var_types regType)
{
#ifdef TARGET_AMD64
if (varTypeIsGC(regType) || varTypeIsLong(regType))
{
// For AMD64, we don't use eGPR for GC types.
candidates &= (SingleTypeRegSet)RBM_LOWINT.getLow();
}
#endif // TARGET_AMD64
return candidates;
}
#ifdef DEBUG
//----------------------------------------------------------------------------
@ -8694,6 +8723,9 @@ regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock,
}
#else // !TARGET_ARM
SingleTypeRegSet freeRegs = allRegs(type);
// We call getTempRegForResolution() with only either TYP_INT or TYP_FLOAT.
// We are being conservative with eGPR usage when type is TYP_INT since it could be a reference type.
freeRegs = getAvailableGPRsForType(freeRegs, (type == TYP_INT) ? TYP_REF : type);
#endif // !TARGET_ARM
#ifdef DEBUG
@ -13466,7 +13498,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::select(Interval*
{
preferences = candidates;
}
candidates = linearScan->getAvailableGPRsForType(candidates, regType);
#ifdef DEBUG
candidates = linearScan->stressLimitRegs(refPosition, regType, candidates);
#endif
@ -13934,7 +13966,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::selectMinimal(
}
}
}
candidates = linearScan->getAvailableGPRsForType(candidates, regType);
#ifdef DEBUG
candidates = linearScan->stressLimitRegs(refPosition, regType, candidates);
#endif

View File

@ -1142,7 +1142,8 @@ private:
return getIntervalForLocalVar(varDsc->lvVarIndex);
}
RegRecord* getRegisterRecord(regNumber regNum);
RegRecord* getRegisterRecord(regNumber regNum);
SingleTypeRegSet getAvailableGPRsForType(SingleTypeRegSet candidates, var_types regType);
RefPosition* newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType);