Skip to content

Commit

Permalink
fixed build error for arm64
Browse files Browse the repository at this point in the history
  • Loading branch information
kunalspathak committed May 20, 2024
1 parent d356c89 commit 06bd9e2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 48 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ set( JIT_SOURCES
redundantbranchopts.cpp
regalloc.cpp
registerargconvention.cpp
regMaskTPOps.cpp
regset.cpp
scev.cpp
scopeinfo.cpp
Expand Down
22 changes: 11 additions & 11 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,7 @@ class LinearScan : public LinearScanInterface
return nextConsecutiveRefPositionMap;
}
FORCEINLINE RefPosition* getNextConsecutiveRefPosition(RefPosition* refPosition);
void getLowVectorOperandAndCandidates(HWIntrinsic intrin, size_t* operandNum, regMaskTP* candidates);
void getLowVectorOperandAndCandidates(HWIntrinsic intrin, size_t* operandNum, SingleTypeRegSet* candidates);
#endif

#ifdef DEBUG
Expand Down Expand Up @@ -1983,10 +1983,10 @@ class LinearScan : public LinearScanInterface
bool isCandidateMultiRegLclVar(GenTreeLclVar* lclNode);
bool checkContainedOrCandidateLclVar(GenTreeLclVar* lclNode);

RefPosition* BuildUse(GenTree* operand, regMaskTP candidates = RBM_NONE, int multiRegIdx = 0);
RefPosition* BuildUse(GenTree* operand, SingleTypeRegSet candidates = RBM_NONE, int multiRegIdx = 0);
void setDelayFree(RefPosition* use);
int BuildBinaryUses(GenTreeOp* node, regMaskTP candidates = RBM_NONE);
int BuildCastUses(GenTreeCast* cast, regMaskTP candidates);
int BuildBinaryUses(GenTreeOp* node, SingleTypeRegSet candidates = RBM_NONE);
int BuildCastUses(GenTreeCast* cast, SingleTypeRegSet candidates);
#ifdef TARGET_XARCH
int BuildRMWUses(GenTree* node, GenTree* op1, GenTree* op2, regMaskTP candidates = RBM_NONE);
inline regMaskTP BuildEvexIncompatibleMask(GenTree* tree);
Expand All @@ -2001,22 +2001,22 @@ class LinearScan : public LinearScanInterface
bool supportsSpecialPutArg();

int BuildSimple(GenTree* tree);
int BuildOperandUses(GenTree* node, regMaskTP candidates = RBM_NONE);
int BuildOperandUses(GenTree* node, SingleTypeRegSet candidates = RBM_NONE);
void AddDelayFreeUses(RefPosition* refPosition, GenTree* rmwNode);
int BuildDelayFreeUses(GenTree* node,
GenTree* rmwNode = nullptr,
regMaskTP candidates = RBM_NONE,
SingleTypeRegSet candidates = RBM_NONE,
RefPosition** useRefPosition = nullptr);
int BuildIndirUses(GenTreeIndir* indirTree, regMaskTP candidates = RBM_NONE);
int BuildAddrUses(GenTree* addr, regMaskTP candidates = RBM_NONE);
int BuildIndirUses(GenTreeIndir* indirTree, SingleTypeRegSet candidates = RBM_NONE);
int BuildAddrUses(GenTree* addr, SingleTypeRegSet candidates = RBM_NONE);
void HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs);

RefPosition* BuildDef(GenTree* tree, regMaskTP dstCandidates = RBM_NONE, int multiRegIdx = 0);
void BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates = RBM_NONE);
RefPosition* BuildDef(GenTree* tree, SingleTypeRegSet dstCandidates = RBM_NONE, int multiRegIdx = 0);
void BuildDefs(GenTree* tree, int dstCount, SingleTypeRegSet dstCandidates = RBM_NONE);
void BuildCallDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates);
void BuildKills(GenTree* tree, regMaskTP killMask);
#ifdef TARGET_ARMARCH
void BuildDefWithKills(GenTree* tree, regMaskTP dstCandidates, regMaskTP killMask);
void BuildDefWithKills(GenTree* tree, SingleTypeRegSet dstCandidates, regMaskTP killMask);
#else
void BuildDefWithKills(GenTree* tree, int dstCount, regMaskTP dstCandidates, regMaskTP killMask);
#endif
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/jit/lsraarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
}
else if (HWIntrinsicInfo::IsMaskedOperation(intrin.id))
{
regMaskTP predMask = HWIntrinsicInfo::IsLowMaskedOperation(intrin.id) ? RBM_LOWMASK : RBM_ALLMASK;
SingleTypeRegSet predMask = HWIntrinsicInfo::IsLowMaskedOperation(intrin.id) ? RBM_LOWMASK : RBM_ALLMASK;
srcCount += BuildOperandUses(intrin.op1, predMask);
}
else if (intrinsicTree->OperIsMemoryLoadOrStore())
Expand Down Expand Up @@ -1844,7 +1844,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
assert(intrin.op1 != nullptr);

bool forceOp2DelayFree = false;
regMaskTP lowVectorCandidates = RBM_NONE;
SingleTypeRegSet lowVectorCandidates = RBM_NONE;
size_t lowVectorOperandNum = 0;
if ((intrin.id == NI_Vector64_GetElement) || (intrin.id == NI_Vector128_GetElement))
{
Expand Down Expand Up @@ -1897,7 +1897,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
}
else
{
regMaskTP candidates = lowVectorOperandNum == 2 ? lowVectorCandidates : RBM_NONE;
SingleTypeRegSet candidates = lowVectorOperandNum == 2 ? lowVectorCandidates : RBM_NONE;
if (forceOp2DelayFree)
{
srcCount += BuildDelayFreeUses(intrin.op2, nullptr, candidates);
Expand All @@ -1911,7 +1911,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou

if (intrin.op3 != nullptr)
{
regMaskTP candidates = lowVectorOperandNum == 3 ? lowVectorCandidates : RBM_NONE;
SingleTypeRegSet candidates = lowVectorOperandNum == 3 ? lowVectorCandidates : RBM_NONE;

srcCount += isRMW ? BuildDelayFreeUses(intrin.op3, intrin.op1, candidates)
: BuildOperandUses(intrin.op3, candidates);
Expand Down Expand Up @@ -2221,7 +2221,7 @@ bool RefPosition::isLiveAtConsecutiveRegistersLoc(LsraLocation consecutiveRegist
// operandNum (out) - The operand number having the low vector register restriction
// candidates (out) - The restricted low vector registers
//
void LinearScan::getLowVectorOperandAndCandidates(HWIntrinsic intrin, size_t* operandNum, regMaskTP* candidates)
void LinearScan::getLowVectorOperandAndCandidates(HWIntrinsic intrin, size_t* operandNum, SingleTypeRegSet* candidates)
{
assert(HWIntrinsicInfo::IsLowVectorOperation(intrin.id));
unsigned baseElementSize = genTypeSize(intrin.baseType);
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/lsraarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ int LinearScan::BuildCall(GenTreeCall* call)
{
bool hasMultiRegRetVal = false;
const ReturnTypeDesc* retTypeDesc = nullptr;
regMaskTP singleDstCandidates = RBM_NONE;
SingleTypeRegSet singleDstCandidates = RBM_NONE;

int srcCount = 0;
int dstCount = 0;
Expand All @@ -149,7 +149,7 @@ int LinearScan::BuildCall(GenTreeCall* call)
}

GenTree* ctrlExpr = call->gtControlExpr;
regMaskTP ctrlExprCandidates = RBM_NONE;
SingleTypeRegSet ctrlExprCandidates = RBM_NONE;
if (call->gtCallType == CT_INDIRECT)
{
// either gtControlExpr != null or gtCallAddr != null.
Expand Down Expand Up @@ -444,7 +444,7 @@ int LinearScan::BuildCall(GenTreeCall* call)
// The def and kill functionality is folded into a single method so that the
// save and restores of upper vector registers can be bracketed around the def.
//
void LinearScan::BuildDefWithKills(GenTree* tree, regMaskTP dstCandidates, regMaskTP killMask)
void LinearScan::BuildDefWithKills(GenTree* tree, SingleTypeRegSet dstCandidates, regMaskTP killMask)
{
assert(!tree->AsCall()->HasMultiRegRetVal());
assert((int)genCountBits(dstCandidates) == 1);
Expand Down Expand Up @@ -602,7 +602,7 @@ int LinearScan::BuildPutArgSplit(GenTreePutArgSplit* argNode)
// go into registers.
for (unsigned regIndex = 0; regIndex < currentRegCount; regIndex++)
{
regMaskTP sourceMask = RBM_NONE;
SingleTypeRegSet sourceMask = RBM_NONE;
if (sourceRegCount < argNode->gtNumRegs)
{
sourceMask = genRegMask((regNumber)((unsigned)argReg + sourceRegCount));
Expand Down
60 changes: 32 additions & 28 deletions src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,11 @@ void LinearScan::addKillForRegs(regMaskTP mask, LsraLocation currentLoc)
// modified until codegen, which is too late.
compiler->codeGen->regSet.rsSetRegsModified(mask DEBUGARG(true));

RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKill, nullptr, mask);
RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKill, nullptr, mask.getLow());
*killTail = pos;
killTail = &pos->nextRefPosition;

pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKill, nullptr, mask.getHigh());

*killTail = pos;
killTail = &pos->nextRefPosition;
Expand Down Expand Up @@ -1148,6 +1152,7 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo
}
Interval* interval = getIntervalForLocalVar(varIndex);
const bool isCallKill = ((killMask == RBM_INT_CALLEE_TRASH) || (killMask == RBM_CALLEE_TRASH));
SingleTypeRegSet regsKillMask = killMask.GetRegSetForType(interval->registerType);

if (isCallKill)
{
Expand All @@ -1160,15 +1165,15 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo
// See the "heuristics for writeThru intervals" in 'buildIntervals()'.
if (!interval->isWriteThru || !isCallKill)
{
regMaskTP newPreferences = allRegs(interval->registerType) & (~killMask);
SingleTypeRegSet newPreferences = allRegs(interval->registerType) & (~regsKillMask);

if (newPreferences != RBM_NONE)
{
if (!interval->isWriteThru)
{
// Update the register aversion as long as this is not write-thru vars for
// reason mentioned above.
interval->registerAversion |= killMask;
interval->registerAversion |= regsKillMask;
}
interval->updateRegisterPreferences(newPreferences);
}
Expand Down Expand Up @@ -3056,7 +3061,7 @@ void setTgtPref(Interval* interval, RefPosition* tgtPrefUse)
// Notes:
// Adds the RefInfo for the definition to the defList.
//
RefPosition* LinearScan::BuildDef(GenTree* tree, regMaskTP dstCandidates, int multiRegIdx)
RefPosition* LinearScan::BuildDef(GenTree* tree, SingleTypeRegSet dstCandidates, int multiRegIdx)
{
assert(!tree->isContained());

Expand Down Expand Up @@ -3158,13 +3163,12 @@ void LinearScan::BuildCallDefs(GenTree* tree, int dstCount, regMaskTP dstCandida
{
// In case of multi-reg call node, we have to query the i'th position return register.
// For all other cases of multi-reg definitions, the registers must be in sequential order.
regMaskTP thisDstCandidates =
genRegMask(tree->AsCall()->GetReturnTypeDesc()->GetABIReturnReg(i, tree->AsCall()->GetUnmanagedCallConv()));
regNumber thisReg = tree->AsCall()->GetReturnTypeDesc()->GetABIReturnReg(i, tree->AsCall()->GetUnmanagedCallConv());

assert((dstCandidates & thisDstCandidates) != RBM_NONE);
dstCandidates &= ~thisDstCandidates;
assert(dstCandidates.IsRegNumInMask(thisReg));
dstCandidates.RemoveRegNumFromMask(thisReg);

BuildDef(tree, thisDstCandidates, i);
BuildDef(tree, genRegMask(thisReg), i);
}
}

Expand All @@ -3181,7 +3185,7 @@ void LinearScan::BuildCallDefs(GenTree* tree, int dstCount, regMaskTP dstCandida
// Also, the `dstCandidates` is assumed to be of "onlyOne" type. If there are
// both gpr and float registers, use `BuildDefs` that takes `AllRegsMask`
//
void LinearScan::BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates)
void LinearScan::BuildDefs(GenTree* tree, int dstCount, SingleTypeRegSet dstCandidates)
{
assert(dstCount > 0);

Expand All @@ -3197,7 +3201,7 @@ void LinearScan::BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates)

for (int i = 0; i < dstCount; i++)
{
regMaskTP thisDstCandidates = genFindLowestBit(dstCandidates);
SingleTypeRegSet thisDstCandidates = genFindLowestBit(dstCandidates);
BuildDef(tree, thisDstCandidates, i);
dstCandidates &= ~thisDstCandidates;
}
Expand Down Expand Up @@ -3386,7 +3390,7 @@ void LinearScan::UpdatePreferencesOfDyingLocal(Interval* interval)
// Notes:
// The node must not be contained, and must have been processed by buildRefPositionsForNode().
//
RefPosition* LinearScan::BuildUse(GenTree* operand, regMaskTP candidates, int multiRegIdx)
RefPosition* LinearScan::BuildUse(GenTree* operand, SingleTypeRegSet candidates, int multiRegIdx)
{
assert(!operand->isContained());
Interval* interval;
Expand Down Expand Up @@ -3456,12 +3460,12 @@ RefPosition* LinearScan::BuildUse(GenTree* operand, regMaskTP candidates, int mu
// Notes:
// This method may only be used if the candidates are the same for all sources.
//
int LinearScan::BuildIndirUses(GenTreeIndir* indirTree, regMaskTP candidates)
int LinearScan::BuildIndirUses(GenTreeIndir* indirTree, SingleTypeRegSet candidates)
{
return BuildAddrUses(indirTree->Addr(), candidates);
}

int LinearScan::BuildAddrUses(GenTree* addr, regMaskTP candidates)
int LinearScan::BuildAddrUses(GenTree* addr, SingleTypeRegSet candidates)
{
if (!addr->isContained())
{
Expand Down Expand Up @@ -3518,7 +3522,7 @@ int LinearScan::BuildAddrUses(GenTree* addr, regMaskTP candidates)
// Return Value:
// The number of source registers used by the *parent* of this node.
//
int LinearScan::BuildOperandUses(GenTree* node, regMaskTP candidates)
int LinearScan::BuildOperandUses(GenTree* node, SingleTypeRegSet candidates)
{
if (!node->isContained())
{
Expand Down Expand Up @@ -3674,7 +3678,7 @@ void LinearScan::AddDelayFreeUses(RefPosition* useRefPosition, GenTree* rmwNode)
//
int LinearScan::BuildDelayFreeUses(GenTree* node,
GenTree* rmwNode,
regMaskTP candidates,
SingleTypeRegSet candidates,
RefPosition** useRefPositionRef)
{
RefPosition* use = nullptr;
Expand Down Expand Up @@ -3771,7 +3775,7 @@ int LinearScan::BuildDelayFreeUses(GenTree* node,
// The operands must already have been processed by buildRefPositionsForNode, and their
// RefInfoListNodes placed in the defList.
//
int LinearScan::BuildBinaryUses(GenTreeOp* node, regMaskTP candidates)
int LinearScan::BuildBinaryUses(GenTreeOp* node, SingleTypeRegSet candidates)
{
GenTree* op1 = node->gtGetOp1();
GenTree* op2 = node->gtGetOp2IfPresent();
Expand Down Expand Up @@ -3805,7 +3809,7 @@ int LinearScan::BuildBinaryUses(GenTreeOp* node, regMaskTP candidates)
// Return Value:
// The number of actual register operands.
//
int LinearScan::BuildCastUses(GenTreeCast* cast, regMaskTP candidates)
int LinearScan::BuildCastUses(GenTreeCast* cast, SingleTypeRegSet candidates)
{
GenTree* src = cast->CastOp();

Expand Down Expand Up @@ -3870,7 +3874,7 @@ void LinearScan::BuildStoreLocDef(GenTreeLclVarCommon* storeLoc,
}
}

regMaskTP defCandidates = RBM_NONE;
SingleTypeRegSet defCandidates = RBM_NONE;
var_types type = varDsc->GetRegisterType();

#ifdef TARGET_X86
Expand Down Expand Up @@ -3956,7 +3960,7 @@ int LinearScan::BuildMultiRegStoreLoc(GenTreeLclVar* storeLoc)

if (isMultiRegSrc)
{
regMaskTP srcCandidates = RBM_NONE;
SingleTypeRegSet srcCandidates = RBM_NONE;
#ifdef TARGET_X86
var_types type = fieldVarDsc->TypeGet();
if (varTypeIsByte(type))
Expand Down Expand Up @@ -4067,7 +4071,7 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc)
else
{
srcCount = 1;
regMaskTP srcCandidates = RBM_NONE;
SingleTypeRegSet srcCandidates = RBM_NONE;
#ifdef TARGET_X86
var_types type = varDsc->GetRegisterType(storeLoc);
if (varTypeIsByte(type))
Expand Down Expand Up @@ -4158,7 +4162,7 @@ int LinearScan::BuildReturn(GenTree* tree)
#endif // !defined(TARGET_64BIT)
if ((tree->TypeGet() != TYP_VOID) && !op1->isContained())
{
regMaskTP useCandidates = RBM_NONE;
SingleTypeRegSet useCandidates = RBM_NONE;

#if FEATURE_MULTIREG_RET
#ifdef TARGET_ARM64
Expand Down Expand Up @@ -4351,7 +4355,7 @@ int LinearScan::BuildPutArgReg(GenTreeUnOp* node)

// To avoid redundant moves, have the argument operand computed in the
// register in which the argument is passed to the call.
regMaskTP argMask = genRegMask(argReg);
SingleTypeRegSet argMask = genRegMask(argReg);
RefPosition* use = BuildUse(op1, argMask);

// Record that this register is occupied by a register now.
Expand Down Expand Up @@ -4448,8 +4452,8 @@ int LinearScan::BuildGCWriteBarrier(GenTree* tree)
// is an indir through an lea, we need to actually instantiate the
// lea in a register
assert(!addr->isContained() && !src->isContained());
regMaskTP addrCandidates = RBM_WRITE_BARRIER_DST;
regMaskTP srcCandidates = RBM_WRITE_BARRIER_SRC;
SingleTypeRegSet addrCandidates = RBM_WRITE_BARRIER_DST;
SingleTypeRegSet srcCandidates = RBM_WRITE_BARRIER_SRC;

#if defined(TARGET_X86) && NOGC_WRITE_BARRIERS

Expand Down Expand Up @@ -4496,7 +4500,7 @@ int LinearScan::BuildCmp(GenTree* tree)

if (!tree->TypeIs(TYP_VOID))
{
regMaskTP dstCandidates = RBM_NONE;
SingleTypeRegSet dstCandidates = RBM_NONE;

#ifdef TARGET_X86
// If the compare is used by a jump, we just need to set the condition codes. If not, then we need
Expand All @@ -4520,8 +4524,8 @@ int LinearScan::BuildCmp(GenTree* tree)
//
int LinearScan::BuildCmpOperands(GenTree* tree)
{
regMaskTP op1Candidates = RBM_NONE;
regMaskTP op2Candidates = RBM_NONE;
SingleTypeRegSet op1Candidates = RBM_NONE;
SingleTypeRegSet op2Candidates = RBM_NONE;
GenTree* op1 = tree->gtGetOp1();
GenTree* op2 = tree->gtGetOp2();

Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ struct regMaskTP
{
return getLow();
}

void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
Expand Down

0 comments on commit 06bd9e2

Please sign in to comment.