Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache allregs to avoid checking the type repeatedly #76850

Merged
merged 8 commits into from
Jan 10, 2023
46 changes: 26 additions & 20 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,25 +239,7 @@ weight_t LinearScan::getWeight(RefPosition* refPos)
regMaskTP LinearScan::allRegs(RegisterType rt)
{
assert((rt != TYP_UNDEF) && (rt != TYP_STRUCT));
if (rt == TYP_FLOAT)
{
return availableFloatRegs;
}
else if (rt == TYP_DOUBLE)
{
return availableDoubleRegs;
}
#ifdef FEATURE_SIMD
// TODO-Cleanup: Add an RBM_ALLSIMD
else if (varTypeIsSIMD(rt))
{
return availableDoubleRegs;
}
#endif // FEATURE_SIMD
else
{
return availableIntRegs;
}
return *availableRegs[rt];
}

regMaskTP LinearScan::allByteRegs()
Expand Down Expand Up @@ -382,7 +364,7 @@ regMaskTP LinearScan::internalFloatRegCandidates()
{
if (compiler->compFloatingPointUsed)
{
return allRegs(TYP_FLOAT);
return availableFloatRegs;
}
else
{
Expand Down Expand Up @@ -688,6 +670,30 @@ LinearScan::LinearScan(Compiler* theCompiler)
availableDoubleRegs &= ~RBM_CALLEE_SAVED;
}
#endif // TARGET_AMD64 || TARGET_ARM64

for (unsigned int i = 0; i < TYP_COUNT; i++)
{
var_types thisType = (var_types)genActualTypes[i];
if (thisType == TYP_FLOAT)
{
availableRegs[i] = &availableFloatRegs;
}
else if (thisType == TYP_DOUBLE)
{
availableRegs[i] = &availableDoubleRegs;
}
#ifdef FEATURE_SIMD
else if ((thisType >= TYP_SIMD8) && (thisType <= TYP_SIMD32))
{
availableRegs[i] = &availableDoubleRegs;
}
#endif
else
{
availableRegs[i] = &availableIntRegs;
}
}

compiler->rpFrameType = FT_NOT_SET;
compiler->rpMustCreateEBPCalled = false;

Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1590,9 +1590,10 @@ class LinearScan : public LinearScanInterface
// A temporary VarToRegMap used during the resolution of critical edges.
VarToRegMap sharedCriticalVarToRegMap;

PhasedVar<regMaskTP> availableIntRegs;
PhasedVar<regMaskTP> availableFloatRegs;
PhasedVar<regMaskTP> availableDoubleRegs;
PhasedVar<regMaskTP> availableIntRegs;
PhasedVar<regMaskTP> availableFloatRegs;
PhasedVar<regMaskTP> availableDoubleRegs;
PhasedVar<regMaskTP>* availableRegs[TYP_COUNT];

// Register mask of argument registers currently occupied because we saw a
// PUTARG_REG node. Tracked between the PUTARG_REG and its corresponding
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo
if (compiler->killGCRefs(tree))
{
RefPosition* pos =
newRefPosition((Interval*)nullptr, currentLoc, RefTypeKillGCRefs, tree, (allRegs(TYP_REF) & ~RBM_ARG_REGS));
newRefPosition((Interval*)nullptr, currentLoc, RefTypeKillGCRefs, tree, (availableIntRegs & ~RBM_ARG_REGS));
insertedKills = true;
}

Expand Down Expand Up @@ -1368,7 +1368,7 @@ RefPosition* LinearScan::defineNewInternalTemp(GenTree* tree, RegisterType regTy
RefPosition* LinearScan::buildInternalIntRegisterDefForNode(GenTree* tree, regMaskTP internalCands)
{
// The candidate set should contain only integer registers.
assert((internalCands & ~allRegs(TYP_INT)) == RBM_NONE);
assert((internalCands & ~availableIntRegs) == RBM_NONE);

RefPosition* defRefPosition = defineNewInternalTemp(tree, IntRegisterType, internalCands);
return defRefPosition;
Expand All @@ -1387,7 +1387,7 @@ RefPosition* LinearScan::buildInternalIntRegisterDefForNode(GenTree* tree, regMa
RefPosition* LinearScan::buildInternalFloatRegisterDefForNode(GenTree* tree, regMaskTP internalCands)
{
// The candidate set should contain only float registers.
assert((internalCands & ~allRegs(TYP_FLOAT)) == RBM_NONE);
assert((internalCands & ~availableFloatRegs) == RBM_NONE);

RefPosition* defRefPosition = defineNewInternalTemp(tree, FloatRegisterType, internalCands);
return defRefPosition;
Expand Down Expand Up @@ -2823,7 +2823,7 @@ RefPosition* LinearScan::BuildDef(GenTree* tree, regMaskTP dstCandidates, int mu
{
if (dstCandidates == RBM_NONE)
{
dstCandidates = allRegs(TYP_INT);
dstCandidates = availableIntRegs;
}
dstCandidates &= ~RBM_NON_BYTE_REGS;
assert(dstCandidates != RBM_NONE);
Expand Down
16 changes: 8 additions & 8 deletions src/coreclr/jit/lsraxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,8 @@ int LinearScan::BuildNode(GenTree* tree)

// Comparand is preferenced to RAX.
// The remaining two operands can be in any reg other than RAX.
BuildUse(tree->AsCmpXchg()->gtOpLocation, allRegs(TYP_INT) & ~RBM_RAX);
BuildUse(tree->AsCmpXchg()->gtOpValue, allRegs(TYP_INT) & ~RBM_RAX);
BuildUse(tree->AsCmpXchg()->gtOpLocation, availableIntRegs & ~RBM_RAX);
BuildUse(tree->AsCmpXchg()->gtOpValue, availableIntRegs & ~RBM_RAX);
BuildUse(tree->AsCmpXchg()->gtOpComparand, RBM_RAX);
BuildDef(tree, RBM_RAX);
}
Expand Down Expand Up @@ -989,8 +989,8 @@ int LinearScan::BuildShiftRotate(GenTree* tree)
#endif
else
{
srcCandidates = allRegs(TYP_INT) & ~RBM_RCX;
dstCandidates = allRegs(TYP_INT) & ~RBM_RCX;
srcCandidates = availableIntRegs & ~RBM_RCX;
dstCandidates = availableIntRegs & ~RBM_RCX;
}

// Note that Rotate Left/Right instructions don't set ZF and SF flags.
Expand Down Expand Up @@ -1277,7 +1277,7 @@ int LinearScan::BuildCall(GenTreeCall* call)
// Don't assign the call target to any of the argument registers because
// we will use them to also pass floating point arguments as required
// by Amd64 ABI.
ctrlExprCandidates = allRegs(TYP_INT) & ~(RBM_ARG_REGS);
ctrlExprCandidates = availableIntRegs & ~(RBM_ARG_REGS);
}
srcCount += BuildOperandUses(ctrlExpr, ctrlExprCandidates);
}
Expand Down Expand Up @@ -1402,7 +1402,7 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
case GenTreeBlk::BlkOpKindUnroll:
if ((size % XMM_REGSIZE_BYTES) != 0)
{
regMaskTP regMask = allRegs(TYP_INT);
regMaskTP regMask = availableIntRegs;
#ifdef TARGET_X86
if ((size & 1) != 0)
{
Expand Down Expand Up @@ -1622,7 +1622,7 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* putArgStk)
// If we have a remainder smaller than XMM_REGSIZE_BYTES, we need an integer temp reg.
if ((loadSize % XMM_REGSIZE_BYTES) != 0)
{
regMaskTP regMask = allRegs(TYP_INT);
regMaskTP regMask = availableIntRegs;
#ifdef TARGET_X86
// Storing at byte granularity requires a byteable register.
if ((loadSize & 1) != 0)
Expand Down Expand Up @@ -1827,7 +1827,7 @@ int LinearScan::BuildModDiv(GenTree* tree)
srcCount = 1;
}

srcCount += BuildDelayFreeUses(op2, op1, allRegs(TYP_INT) & ~(RBM_RAX | RBM_RDX));
srcCount += BuildDelayFreeUses(op2, op1, availableIntRegs & ~(RBM_RAX | RBM_RDX));

buildInternalRegisterUses();

Expand Down