Skip to content

Commit

Permalink
Cache allregs to avoid checking the type repeatedly (#76850)
Browse files Browse the repository at this point in the history
* cache the available registers

* Convert to PhasedVar

* Store the references instead of values

* Replace allRegs(constant_index) with actual values

* Remove call to varTypeIsSIMD()
  • Loading branch information
kunalspathak committed Jan 10, 2023
1 parent d4dbcc6 commit 7a6c31c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 35 deletions.
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

0 comments on commit 7a6c31c

Please sign in to comment.