Skip to content

JIT: Add missing new-style ABI classifiers for LA64 and RISCV64 #100744

@jakobbotsch

Description

@jakobbotsch

#100138 introduced a new representation for ABI information that I am planning on switching the JIT to use in all places that deal with ABI details. It explicitly represents how all parts of all parameters are passed. #100276 and #100526 introduced classifiers for all of our supported targets: win-x86, win-x64, SysV x64, arm64 and arm32.
#100572 is an example PR that is making use of the new ABI representation to rewrite parameter homing.

Before I can proceed with moving the rest of the JIT to the new representation we need implementations of new-style classifiers for LA64 (cc @shushanhf) and RISCV64 (cc @dotnet/samsung). I would greatly appreciate contributions of implementations of these. Otherwise I can try to base it on what happens in lvaInitUserArgs today, but I will not be able to test it.

Once implemented, the following code can be enabled to cross check the new style ABI information against the old one stored in LclVarDsc:

#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM)
{
PlatformClassifier classifier(cInfo);
lvaClassifyParameterABI(classifier);
}
#endif
#ifdef DEBUG
if (lvaParameterPassingInfo == nullptr)
{
return;
}
for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++)
{
LclVarDsc* dsc = lvaGetDesc(lclNum);
const ABIPassingInformation& abiInfo = lvaParameterPassingInfo[lclNum];
assert(abiInfo.NumSegments > 0);
if ((dsc->TypeGet() == TYP_STRUCT) && (info.compCallConv == CorInfoCallConvExtension::Swift))
{
continue;
}
unsigned numSegmentsToCompare = abiInfo.NumSegments;
if (dsc->lvIsHfa())
{
// LclVarDsc only has one register set for HFAs
numSegmentsToCompare = 1;
}
#ifdef TARGET_ARM
// On arm the old representation only represents the start register for
// struct multireg args.
if (varTypeIsStruct(dsc))
{
numSegmentsToCompare = 1;
}
// And also for TYP_DOUBLE on soft FP
if (opts.compUseSoftFP && (dsc->TypeGet() == TYP_DOUBLE))
{
numSegmentsToCompare = 1;
}
#endif
for (unsigned i = 0; i < numSegmentsToCompare; i++)
{
const ABIPassingSegment& expected = abiInfo.Segments[i];
regNumber reg = REG_NA;
if (i == 0)
{
reg = dsc->GetArgReg();
}
#if FEATURE_MULTIREG_ARGS
else if (i == 1)
{
reg = dsc->GetOtherArgReg();
}
#endif
if (expected.IsPassedOnStack())
{
if (i == 0)
{
assert(reg == REG_STK);
// On x86, varargs methods access stack args off of a base pointer, and the
// first stack arg is not considered to be at offset 0.
// TODO-Cleanup: Unify things so that x86 is consistent with other platforms
// here and change fgMorphExpandStackArgForVarArgs to account for that.
#ifndef TARGET_X86
assert((unsigned)dsc->GetStackOffset() == expected.GetStackOffset());
#endif
}
}
else
{
assert(reg == expected.GetRegister());
}
}
}
#endif // DEBUG

Eventually the old information will be removed from LclVarDsc and the new style information will be the only source-of-truth for the ABI information.

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions