Skip to content

Commit

Permalink
Cache CORINFO_FPSTRUCT_LOWERING
Browse files Browse the repository at this point in the history
  • Loading branch information
tomeksowi committed Jul 9, 2024
1 parent e37e984 commit c7c88e0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 58 deletions.
63 changes: 37 additions & 26 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,17 +930,16 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
if (structSize <= (TARGET_POINTER_SIZE * 2))
{
CORINFO_FPSTRUCT_LOWERING lowering;
GetFpStructLowering(clsHnd, &lowering);
if (lowering.numLoweredElements == 1)
const CORINFO_FPSTRUCT_LOWERING* lowering = GetFpStructLowering(clsHnd);
if (lowering->numLoweredElements == 1)
{
useType = JITtype2varType(lowering.loweredElements[0]);
useType = JITtype2varType(lowering->loweredElements[0]);
assert(varTypeIsFloating(useType));
howToReturnStruct = SPK_PrimitiveType;
}
else if (!lowering.byIntegerCallConv)
else if (!lowering->byIntegerCallConv)
{
assert(lowering.numLoweredElements == 2);
assert(lowering->numLoweredElements == 2);
howToReturnStruct = SPK_ByValue;
useType = TYP_STRUCT;
}
Expand Down Expand Up @@ -1982,6 +1981,9 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
#ifdef SWIFT_SUPPORT
m_swiftLoweringCache = nullptr;
#endif
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
m_fpStructLoweringCache = nullptr;
#endif

// check that HelperCallProperties are initialized

Expand Down Expand Up @@ -8292,35 +8294,44 @@ void Compiler::GetStructTypeOffset(
//
// Arguments:
// structHandle - type handle
// pLowering - out param; returns the lowering info for the struct fields
//
// Return value:
// None
void Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle, CORINFO_FPSTRUCT_LOWERING* pLowering)
// Lowering info for the struct fields
const CORINFO_FPSTRUCT_LOWERING* Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle)
{
info.compCompHnd->getFpStructLowering(structHandle, pLowering);
#ifdef DEBUG
if (verbose)
{
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));
if (m_fpStructLoweringCache == nullptr)
m_fpStructLoweringCache = new (this, CMK_CallArgs) FpStructLoweringMap(getAllocator(CMK_CallArgs));

if (pLowering->byIntegerCallConv)
{
printf(" pass by integer calling convention\n");
}
else
CORINFO_FPSTRUCT_LOWERING* lowering;
if (!m_fpStructLoweringCache->Lookup(structHandle, &lowering))
{
lowering = new (this, CMK_CallArgs) CORINFO_FPSTRUCT_LOWERING;
info.compCompHnd->getFpStructLowering(structHandle, lowering);
m_fpStructLoweringCache->Set(structHandle, lowering);
#ifdef DEBUG
if (verbose)
{
printf(" may be passed by floating-point calling convention (%zu fields):\n",
pLowering->numLoweredElements);
for (size_t i = 0; i < pLowering->numLoweredElements; ++i)
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));

if (lowering->byIntegerCallConv)
{
const char* type = varTypeName(JITtype2varType(pLowering->loweredElements[i]));
printf(" * field[%zu]: type %s at offset %u\n", i, type, pLowering->offsets[i]);
printf(" pass by integer calling convention\n");
}
else
{
printf(" may be passed by floating-point calling convention (%zu fields):\n",
lowering->numLoweredElements);
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
{
const char* type = varTypeName(JITtype2varType(lowering->loweredElements[i]));
printf(" * field[%zu]: type %s at offset %u\n", i, type, lowering->offsets[i]);
}
}
}
}
#endif // DEBUG
}
return lowering;
}

#endif // defined(UNIX_AMD64_ABI)
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11365,7 +11365,10 @@ class Compiler
CORINFO_CLASS_HANDLE typeHnd, var_types* type0, var_types* type1, uint8_t* offset0, uint8_t* offset1);

#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
void GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle, CORINFO_FPSTRUCT_LOWERING* pLowering);
typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, CORINFO_FPSTRUCT_LOWERING*>
FpStructLoweringMap;
FpStructLoweringMap* m_fpStructLoweringCache;
const CORINFO_FPSTRUCT_LOWERING* GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle);
#endif // defined(UNIX_AMD64_ABI)

void fgMorphMultiregStructArgs(GenTreeCall* call);
Expand Down
12 changes: 5 additions & 7 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28941,17 +28941,15 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,

#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
assert((structSize >= TARGET_POINTER_SIZE) && (structSize <= (2 * TARGET_POINTER_SIZE)));

CORINFO_FPSTRUCT_LOWERING lowering;
comp->GetFpStructLowering(retClsHnd, &lowering);
BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
comp->info.compCompHnd->getClassGClayout(retClsHnd, &gcPtrs[0]);
if (!lowering.byIntegerCallConv)
const CORINFO_FPSTRUCT_LOWERING* lowering = comp->GetFpStructLowering(retClsHnd);
if (!lowering->byIntegerCallConv)
{
comp->compFloatingPointUsed = true;
assert(lowering.numLoweredElements == MAX_RET_REG_COUNT);
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering.loweredElements[0]),
JITtype2varType(lowering.loweredElements[1])};
assert(lowering->numLoweredElements == MAX_RET_REG_COUNT);
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering->loweredElements[0]),
JITtype2varType(lowering->loweredElements[1])};
assert(varTypeIsFloating(types[0]) || varTypeIsFloating(types[1]));
assert((structSize > 8) == ((genTypeSize(types[0]) == 8) || (genTypeSize(types[1]) == 8)));
for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
Expand Down
16 changes: 8 additions & 8 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -898,36 +898,36 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
}
else
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
CORINFO_FPSTRUCT_LOWERING lowering = {.byIntegerCallConv = true};
const CORINFO_FPSTRUCT_LOWERING* lowering = nullptr;

var_types argRegTypeInStruct1 = TYP_UNKNOWN;
var_types argRegTypeInStruct2 = TYP_UNKNOWN;

if ((strip(corInfoType) == CORINFO_TYPE_VALUECLASS) && (argSize <= MAX_PASS_MULTIREG_BYTES))
{
GetFpStructLowering(typeHnd, &lowering);
lowering = GetFpStructLowering(typeHnd);
}

if (!lowering.byIntegerCallConv)
if ((lowering != nullptr) && !lowering->byIntegerCallConv)
{
assert(varTypeIsStruct(argType));
int floatNum = 0;
if (lowering.numLoweredElements == 1)
if (lowering->numLoweredElements == 1)
{
assert(argSize <= 8);
assert(varDsc->lvExactSize() <= argSize);

floatNum = 1;
canPassArgInRegisters = varDscInfo->canEnreg(TYP_DOUBLE, 1);

argRegTypeInStruct1 = JITtype2varType(lowering.loweredElements[0]);
argRegTypeInStruct1 = JITtype2varType(lowering->loweredElements[0]);
assert(varTypeIsFloating(argRegTypeInStruct1));
}
else
{
assert(lowering.numLoweredElements == 2);
argRegTypeInStruct1 = genActualType(JITtype2varType(lowering.loweredElements[0]));
argRegTypeInStruct2 = genActualType(JITtype2varType(lowering.loweredElements[1]));
assert(lowering->numLoweredElements == 2);
argRegTypeInStruct1 = genActualType(JITtype2varType(lowering->loweredElements[0]));
argRegTypeInStruct2 = genActualType(JITtype2varType(lowering->loweredElements[1]));
floatNum = (int)varTypeIsFloating(argRegTypeInStruct1) + (int)varTypeIsFloating(argRegTypeInStruct2);
canPassArgInRegisters = varDscInfo->canEnreg(TYP_DOUBLE, floatNum);
if (floatNum == 1)
Expand Down
34 changes: 18 additions & 16 deletions src/coreclr/jit/targetriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
ClassLayout* structLayout,
WellKnownArg /*wellKnownParam*/)
{
CORINFO_FPSTRUCT_LOWERING lowering = {.byIntegerCallConv = true};
unsigned intFields = 0, floatFields = 0;
unsigned passedSize;
const CORINFO_FPSTRUCT_LOWERING* lowering = nullptr;

unsigned intFields = 0, floatFields = 0;
unsigned passedSize;

if (varTypeIsStruct(type))
{
Expand All @@ -71,17 +72,17 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
}
else if (!structLayout->IsBlockLayout())
{
comp->GetFpStructLowering(structLayout->GetClassHandle(), &lowering);
assert((lowering.numLoweredElements > 0) == !lowering.byIntegerCallConv);
assert(lowering.numLoweredElements <= 2);
lowering = comp->GetFpStructLowering(structLayout->GetClassHandle());
assert((lowering->numLoweredElements > 0) == !lowering->byIntegerCallConv);
assert(lowering->numLoweredElements <= 2);
INDEBUG(unsigned debugIntFields = 0;)
for (size_t i = 0; i < lowering.numLoweredElements; ++i)
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
{
var_types type = JITtype2varType(lowering.loweredElements[i]);
var_types type = JITtype2varType(lowering->loweredElements[i]);
floatFields += (unsigned)varTypeIsFloating(type);
INDEBUG(debugIntFields += (unsigned)varTypeIsIntegralOrI(type);)
}
intFields = lowering.numLoweredElements - floatFields;
intFields = lowering->numLoweredElements - floatFields;
assert(debugIntFields == intFields);
}
}
Expand All @@ -99,14 +100,14 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
// Hardware floating-point calling convention
if ((floatFields == 1) && (intFields == 0))
{
if (lowering.byIntegerCallConv)
if (lowering == nullptr)
{
assert(varTypeIsFloating(type)); // standalone floating-point real
}
else
{
assert(lowering.numLoweredElements == 1); // struct containing just one FP real
assert(varTypeIsFloating(JITtype2varType(lowering.loweredElements[0])));
assert(lowering->numLoweredElements == 1); // struct containing just one FP real
assert(varTypeIsFloating(JITtype2varType(lowering->loweredElements[0])));
}
return ABIPassingInformation::FromSegment(comp, ABIPassingSegment::InRegister(m_floatRegs.Dequeue(), 0,
passedSize));
Expand All @@ -115,12 +116,13 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
{
assert(varTypeIsStruct(type));
assert((floatFields + intFields) == 2);
assert(!lowering.byIntegerCallConv);
assert(lowering.numLoweredElements == 2);
assert(lowering != nullptr);
assert(!lowering->byIntegerCallConv);
assert(lowering->numLoweredElements == 2);

var_types types[] = {
JITtype2varType(lowering.loweredElements[0]),
JITtype2varType(lowering.loweredElements[1]),
JITtype2varType(lowering->loweredElements[0]),
JITtype2varType(lowering->loweredElements[1]),
};
unsigned firstSize = (genTypeSize(types[0]) == 8) ? 8 : 4;
unsigned secondSize = (genTypeSize(types[1]) == 8) ? 8 : 4;
Expand Down

0 comments on commit c7c88e0

Please sign in to comment.