Skip to content

Commit

Permalink
IsRegNumInMask() and IsRegNumPresent()
Browse files Browse the repository at this point in the history
  • Loading branch information
kunalspathak committed May 29, 2024
1 parent f370cf1 commit 1d0f492
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 39 deletions.
22 changes: 11 additions & 11 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4682,7 +4682,7 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock)
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
{
RegRecord* physRegRecord = getRegisterRecord(reg);
if ((liveRegs & genRegMask(reg)) == 0)
if (liveRegs.IsRegNumInMask(reg))
{
makeRegAvailable(reg, physRegRecord->registerType);
Interval* assignedInterval = physRegRecord->assignedInterval;
Expand Down Expand Up @@ -9167,14 +9167,15 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
// We only need to check for these cases if sameToReg is an actual register (not REG_STK).
if (sameToReg != REG_NA && sameToReg != REG_STK)
{
var_types outVarRegType = getIntervalForLocalVar(outResolutionSetVarIndex)->registerType;

// If there's a path on which this var isn't live, it may use the original value in sameToReg.
// In this case, sameToReg will be in the liveOutRegs of this block.
// Similarly, if sameToReg is in sameWriteRegs, it has already been used (i.e. for a lclVar that's
// live only at another target), and we can't copy another lclVar into that reg in this block.
regMaskTP sameToRegMask =
genRegMask(sameToReg, getIntervalForLocalVar(outResolutionSetVarIndex)->registerType);
if (maybeSameLivePaths &&
(((sameToRegMask & liveOutRegs).IsNonEmpty()) || ((sameToRegMask & sameWriteRegs).IsNonEmpty())))
if (maybeSameLivePaths && (liveOutRegs.IsRegNumInMask(sameToReg ARM_ARG(outVarRegType)) || sameWriteRegs.IsRegNumInMask(sameToReg ARM_ARG(outVarRegType))))
{
sameToReg = REG_NA;
}
Expand Down Expand Up @@ -9796,14 +9797,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
fromReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock) DEBUG_ARG(resolveTypeName[resolveType]));
sourceIntervals[sourceReg] = nullptr;
location[sourceReg] = REG_NA;
regMaskTP fromRegMask = genRegMask(fromReg);

// Do we have a free targetReg?
if (fromReg == sourceReg)
{
if (source[fromReg] != REG_NA && ((targetRegsFromStack & fromRegMask) != fromRegMask))
if (source[fromReg] != REG_NA && (targetRegsFromStack.IsRegNumInMask(fromReg)))
{
targetRegsReady |= fromRegMask;
targetRegsReady |= fromReg;
#ifdef TARGET_ARM
if (genIsValidDoubleReg(fromReg))
{
Expand Down Expand Up @@ -9836,13 +9836,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
// lowerHalfRegMask)
if ((lowerHalfSrcReg != REG_NA) && (lowerHalfSrcLoc == REG_NA) &&
(sourceIntervals[lowerHalfSrcReg] != nullptr) &&
((targetRegsReady & lowerHalfRegMask) == RBM_NONE) &&
((targetRegsFromStack & lowerHalfRegMask) != lowerHalfRegMask))
!targetRegsReady.IsRegNumInMask(lowerHalfReg) &&
!targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
{
// This must be a double interval, otherwise it would be in targetRegsReady, or already
// completed.
assert(sourceIntervals[lowerHalfSrcReg]->registerType == TYP_DOUBLE);
targetRegsReady |= lowerHalfRegMask;
targetRegsReady |= lowerHalfReg;
}
#endif // TARGET_ARM
}
Expand Down Expand Up @@ -11445,7 +11445,7 @@ void LinearScan::dumpRegRecordTitleIfNeeded()
int lastRegNumIndex = compiler->compFloatingPointUsed ? REG_FP_LAST : REG_INT_LAST;
for (int regNumIndex = 0; regNumIndex <= lastRegNumIndex; regNumIndex++)
{
if ((registersToDump & genRegMask((regNumber)regNumIndex)) != 0)
if (registersToDump.IsRegNumInMask((regNumber)regNumIndex))
{
lastUsedRegNumIndex = regNumIndex;
}
Expand Down Expand Up @@ -11525,7 +11525,7 @@ void LinearScan::dumpRegRecords()
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
printf("%c", activeChar);
}
else if ((genRegMask(regNum) & regsBusyUntilKill).IsNonEmpty())
else if (regsBusyUntilKill.IsRegNumInMask(regNum))
{
printf(columnFormatArray, "Busy");
}
Expand Down
15 changes: 5 additions & 10 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,7 @@ class LinearScan : public LinearScanInterface
int lastUsedRegNumIndex;
bool shouldDumpReg(regNumber regNum)
{
return (registersToDump & genRegMask(regNum)) != 0;
return registersToDump.IsRegNumInMask(regNum);
}

void dumpRegRecordHeader();
Expand Down Expand Up @@ -1815,8 +1815,7 @@ class LinearScan : public LinearScanInterface

bool isRegAvailable(regNumber reg, var_types regType)
{
regMaskTP regMask = getRegMask(reg, regType);
return (m_AvailableRegs & regMask) == regMask;
return m_AvailableRegs.IsRegNumPresent(reg, regType);
}
void setRegsInUse(regMaskTP regMask)
{
Expand Down Expand Up @@ -1860,9 +1859,7 @@ class LinearScan : public LinearScanInterface
}
bool isRegConstant(regNumber reg, var_types regType)
{
reg = getRegForType(reg, regType);
regMaskTP regMask = getRegMask(reg, regType);
return (m_RegistersWithConstants & regMask) == regMask;
return m_RegistersWithConstants.IsRegNumPresent(reg, regType);
}
SingleTypeRegSet getMatchingConstants(SingleTypeRegSet mask, Interval* currentInterval, RefPosition* refPosition);

Expand Down Expand Up @@ -1903,8 +1900,7 @@ class LinearScan : public LinearScanInterface
#endif
bool isRegBusy(regNumber reg, var_types regType)
{
regMaskTP regMask = getRegMask(reg, regType);
return (regsBusyUntilKill & regMask) != RBM_NONE;
return regsBusyUntilKill.IsRegNumPresent(reg, regType);
}
void setRegBusyUntilKill(regNumber reg, var_types regType)
{
Expand All @@ -1917,8 +1913,7 @@ class LinearScan : public LinearScanInterface

bool isRegInUse(regNumber reg, var_types regType)
{
regMaskTP regMask = getRegMask(reg, regType);
return (regsInUseThisLocation & regMask) != RBM_NONE;
return regsInUseThisLocation.IsRegNumPresent(reg, regType);
}

void resetRegState()
Expand Down
55 changes: 38 additions & 17 deletions src/coreclr/jit/regMaskTPOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ void regMaskTP::RemoveRegNumFromMask(regNumber reg, var_types type)
{
low &= ~genSingleTypeRegMask(reg, type);
}

// ----------------------------------------------------------
// IsRegNumInMask: Removes `reg` from the mask. It is same as IsRegNumInMask(reg) except
// that it takes `type` as an argument and adds `reg` to the mask for that type.
//
bool regMaskTP::IsRegNumInMask(regNumber reg, var_types type) const
{
return (low & genSingleTypeRegMask(reg, type)) != RBM_NONE;
}
#endif

// This is similar to AddRegNumInMask(reg, regType) for all platforms
Expand All @@ -81,6 +90,35 @@ void regMaskTP::AddRegNum(regNumber reg, var_types type)
#endif
}

//------------------------------------------------------------------------
// IsRegNumInMask: Checks if `reg` is in the mask
//
// Parameters:
// reg - Register to check
//
bool regMaskTP::IsRegNumInMask(regNumber reg) const
{
SingleTypeRegSet value = genSingleTypeRegMask(reg);
#ifdef HAS_MORE_THAN_64_REGISTERS
int index = getRegisterTypeIndex(reg);
return (_registers[index] & encodeForRegisterIndex(index, value)) != RBM_NONE;
#else
return (low & value) != RBM_NONE;
#endif
}

// This is similar to IsRegNumInMask(reg, regType) for all platforms
// except Arm. For Arm, it calls getRegMask() instead of genRegMask()
// to create a mask that needs to be added.
bool regMaskTP::IsRegNumPresent(regNumber reg, var_types type) const
{
#ifdef TARGET_ARM
return (low & getRegMask(reg, type)) != RBM_NONE;
#else
return IsRegNumInMask(reg);
#endif
}

//------------------------------------------------------------------------
// RemoveRegNumFromMask: Removes `reg` from the mask
//
Expand Down Expand Up @@ -114,23 +152,6 @@ void regMaskTP::RemoveRegNum(regNumber reg, var_types type)
#endif
}

//------------------------------------------------------------------------
// IsRegNumInMask: Checks if `reg` is in the mask
//
// Parameters:
// reg - Register to check
//
bool regMaskTP::IsRegNumInMask(regNumber reg)
{
SingleTypeRegSet value = genSingleTypeRegMask(reg);
#ifdef HAS_MORE_THAN_64_REGISTERS
int index = getRegisterTypeIndex(reg);
return (_registers[index] & encodeForRegisterIndex(index, value)) != RBM_NONE;
#else
return (low & value) != RBM_NONE;
#endif
}

/* static */ int regMaskTP::getRegisterTypeIndex(regNumber reg)
{
static const BYTE _registerTypeIndex[] = {
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,13 @@ struct regMaskTP
#ifdef TARGET_ARM
void AddRegNumInMask(regNumber reg, var_types type);
void RemoveRegNumFromMask(regNumber reg, var_types type);
bool IsRegNumInMask(regNumber reg, var_types type) const;
#endif
void AddRegNum(regNumber reg, var_types type);
void RemoveRegNumFromMask(regNumber reg);
void RemoveRegNum(regNumber reg, var_types type);
bool IsRegNumInMask(regNumber reg);
bool IsRegNumInMask(regNumber reg) const;
bool IsRegNumPresent(regNumber reg, var_types type) const;

regMaskTP(regMaskSmall lowMask, RegSet32 highMask)
: low(lowMask)
Expand Down

0 comments on commit 1d0f492

Please sign in to comment.