Skip to content

Commit c7c88e0

Browse files
committed
Cache CORINFO_FPSTRUCT_LOWERING
1 parent e37e984 commit c7c88e0

File tree

5 files changed

+72
-58
lines changed

5 files changed

+72
-58
lines changed

src/coreclr/jit/compiler.cpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -930,17 +930,16 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
930930
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
931931
if (structSize <= (TARGET_POINTER_SIZE * 2))
932932
{
933-
CORINFO_FPSTRUCT_LOWERING lowering;
934-
GetFpStructLowering(clsHnd, &lowering);
935-
if (lowering.numLoweredElements == 1)
933+
const CORINFO_FPSTRUCT_LOWERING* lowering = GetFpStructLowering(clsHnd);
934+
if (lowering->numLoweredElements == 1)
936935
{
937-
useType = JITtype2varType(lowering.loweredElements[0]);
936+
useType = JITtype2varType(lowering->loweredElements[0]);
938937
assert(varTypeIsFloating(useType));
939938
howToReturnStruct = SPK_PrimitiveType;
940939
}
941-
else if (!lowering.byIntegerCallConv)
940+
else if (!lowering->byIntegerCallConv)
942941
{
943-
assert(lowering.numLoweredElements == 2);
942+
assert(lowering->numLoweredElements == 2);
944943
howToReturnStruct = SPK_ByValue;
945944
useType = TYP_STRUCT;
946945
}
@@ -1982,6 +1981,9 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
19821981
#ifdef SWIFT_SUPPORT
19831982
m_swiftLoweringCache = nullptr;
19841983
#endif
1984+
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
1985+
m_fpStructLoweringCache = nullptr;
1986+
#endif
19851987

19861988
// check that HelperCallProperties are initialized
19871989

@@ -8292,35 +8294,44 @@ void Compiler::GetStructTypeOffset(
82928294
//
82938295
// Arguments:
82948296
// structHandle - type handle
8295-
// pLowering - out param; returns the lowering info for the struct fields
82968297
//
82978298
// Return value:
8298-
// None
8299-
void Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle, CORINFO_FPSTRUCT_LOWERING* pLowering)
8299+
// Lowering info for the struct fields
8300+
const CORINFO_FPSTRUCT_LOWERING* Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle)
83008301
{
8301-
info.compCompHnd->getFpStructLowering(structHandle, pLowering);
8302-
#ifdef DEBUG
8303-
if (verbose)
8304-
{
8305-
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
8306-
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));
8302+
if (m_fpStructLoweringCache == nullptr)
8303+
m_fpStructLoweringCache = new (this, CMK_CallArgs) FpStructLoweringMap(getAllocator(CMK_CallArgs));
83078304

8308-
if (pLowering->byIntegerCallConv)
8309-
{
8310-
printf(" pass by integer calling convention\n");
8311-
}
8312-
else
8305+
CORINFO_FPSTRUCT_LOWERING* lowering;
8306+
if (!m_fpStructLoweringCache->Lookup(structHandle, &lowering))
8307+
{
8308+
lowering = new (this, CMK_CallArgs) CORINFO_FPSTRUCT_LOWERING;
8309+
info.compCompHnd->getFpStructLowering(structHandle, lowering);
8310+
m_fpStructLoweringCache->Set(structHandle, lowering);
8311+
#ifdef DEBUG
8312+
if (verbose)
83138313
{
8314-
printf(" may be passed by floating-point calling convention (%zu fields):\n",
8315-
pLowering->numLoweredElements);
8316-
for (size_t i = 0; i < pLowering->numLoweredElements; ++i)
8314+
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
8315+
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));
8316+
8317+
if (lowering->byIntegerCallConv)
83178318
{
8318-
const char* type = varTypeName(JITtype2varType(pLowering->loweredElements[i]));
8319-
printf(" * field[%zu]: type %s at offset %u\n", i, type, pLowering->offsets[i]);
8319+
printf(" pass by integer calling convention\n");
8320+
}
8321+
else
8322+
{
8323+
printf(" may be passed by floating-point calling convention (%zu fields):\n",
8324+
lowering->numLoweredElements);
8325+
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
8326+
{
8327+
const char* type = varTypeName(JITtype2varType(lowering->loweredElements[i]));
8328+
printf(" * field[%zu]: type %s at offset %u\n", i, type, lowering->offsets[i]);
8329+
}
83208330
}
83218331
}
8322-
}
83238332
#endif // DEBUG
8333+
}
8334+
return lowering;
83248335
}
83258336

83268337
#endif // defined(UNIX_AMD64_ABI)

src/coreclr/jit/compiler.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11365,7 +11365,10 @@ class Compiler
1136511365
CORINFO_CLASS_HANDLE typeHnd, var_types* type0, var_types* type1, uint8_t* offset0, uint8_t* offset1);
1136611366

1136711367
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
11368-
void GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle, CORINFO_FPSTRUCT_LOWERING* pLowering);
11368+
typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, CORINFO_FPSTRUCT_LOWERING*>
11369+
FpStructLoweringMap;
11370+
FpStructLoweringMap* m_fpStructLoweringCache;
11371+
const CORINFO_FPSTRUCT_LOWERING* GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle);
1136911372
#endif // defined(UNIX_AMD64_ABI)
1137011373

1137111374
void fgMorphMultiregStructArgs(GenTreeCall* call);

src/coreclr/jit/gentree.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28941,17 +28941,15 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,
2894128941

2894228942
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
2894328943
assert((structSize >= TARGET_POINTER_SIZE) && (structSize <= (2 * TARGET_POINTER_SIZE)));
28944-
28945-
CORINFO_FPSTRUCT_LOWERING lowering;
28946-
comp->GetFpStructLowering(retClsHnd, &lowering);
2894728944
BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
2894828945
comp->info.compCompHnd->getClassGClayout(retClsHnd, &gcPtrs[0]);
28949-
if (!lowering.byIntegerCallConv)
28946+
const CORINFO_FPSTRUCT_LOWERING* lowering = comp->GetFpStructLowering(retClsHnd);
28947+
if (!lowering->byIntegerCallConv)
2895028948
{
2895128949
comp->compFloatingPointUsed = true;
28952-
assert(lowering.numLoweredElements == MAX_RET_REG_COUNT);
28953-
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering.loweredElements[0]),
28954-
JITtype2varType(lowering.loweredElements[1])};
28950+
assert(lowering->numLoweredElements == MAX_RET_REG_COUNT);
28951+
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering->loweredElements[0]),
28952+
JITtype2varType(lowering->loweredElements[1])};
2895528953
assert(varTypeIsFloating(types[0]) || varTypeIsFloating(types[1]));
2895628954
assert((structSize > 8) == ((genTypeSize(types[0]) == 8) || (genTypeSize(types[1]) == 8)));
2895728955
for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)

src/coreclr/jit/lclvars.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -898,36 +898,36 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
898898
}
899899
else
900900
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
901-
CORINFO_FPSTRUCT_LOWERING lowering = {.byIntegerCallConv = true};
901+
const CORINFO_FPSTRUCT_LOWERING* lowering = nullptr;
902902

903903
var_types argRegTypeInStruct1 = TYP_UNKNOWN;
904904
var_types argRegTypeInStruct2 = TYP_UNKNOWN;
905905

906906
if ((strip(corInfoType) == CORINFO_TYPE_VALUECLASS) && (argSize <= MAX_PASS_MULTIREG_BYTES))
907907
{
908-
GetFpStructLowering(typeHnd, &lowering);
908+
lowering = GetFpStructLowering(typeHnd);
909909
}
910910

911-
if (!lowering.byIntegerCallConv)
911+
if ((lowering != nullptr) && !lowering->byIntegerCallConv)
912912
{
913913
assert(varTypeIsStruct(argType));
914914
int floatNum = 0;
915-
if (lowering.numLoweredElements == 1)
915+
if (lowering->numLoweredElements == 1)
916916
{
917917
assert(argSize <= 8);
918918
assert(varDsc->lvExactSize() <= argSize);
919919

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

923-
argRegTypeInStruct1 = JITtype2varType(lowering.loweredElements[0]);
923+
argRegTypeInStruct1 = JITtype2varType(lowering->loweredElements[0]);
924924
assert(varTypeIsFloating(argRegTypeInStruct1));
925925
}
926926
else
927927
{
928-
assert(lowering.numLoweredElements == 2);
929-
argRegTypeInStruct1 = genActualType(JITtype2varType(lowering.loweredElements[0]));
930-
argRegTypeInStruct2 = genActualType(JITtype2varType(lowering.loweredElements[1]));
928+
assert(lowering->numLoweredElements == 2);
929+
argRegTypeInStruct1 = genActualType(JITtype2varType(lowering->loweredElements[0]));
930+
argRegTypeInStruct2 = genActualType(JITtype2varType(lowering->loweredElements[1]));
931931
floatNum = (int)varTypeIsFloating(argRegTypeInStruct1) + (int)varTypeIsFloating(argRegTypeInStruct2);
932932
canPassArgInRegisters = varDscInfo->canEnreg(TYP_DOUBLE, floatNum);
933933
if (floatNum == 1)

src/coreclr/jit/targetriscv64.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
5858
ClassLayout* structLayout,
5959
WellKnownArg /*wellKnownParam*/)
6060
{
61-
CORINFO_FPSTRUCT_LOWERING lowering = {.byIntegerCallConv = true};
62-
unsigned intFields = 0, floatFields = 0;
63-
unsigned passedSize;
61+
const CORINFO_FPSTRUCT_LOWERING* lowering = nullptr;
62+
63+
unsigned intFields = 0, floatFields = 0;
64+
unsigned passedSize;
6465

6566
if (varTypeIsStruct(type))
6667
{
@@ -71,17 +72,17 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
7172
}
7273
else if (!structLayout->IsBlockLayout())
7374
{
74-
comp->GetFpStructLowering(structLayout->GetClassHandle(), &lowering);
75-
assert((lowering.numLoweredElements > 0) == !lowering.byIntegerCallConv);
76-
assert(lowering.numLoweredElements <= 2);
75+
lowering = comp->GetFpStructLowering(structLayout->GetClassHandle());
76+
assert((lowering->numLoweredElements > 0) == !lowering->byIntegerCallConv);
77+
assert(lowering->numLoweredElements <= 2);
7778
INDEBUG(unsigned debugIntFields = 0;)
78-
for (size_t i = 0; i < lowering.numLoweredElements; ++i)
79+
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
7980
{
80-
var_types type = JITtype2varType(lowering.loweredElements[i]);
81+
var_types type = JITtype2varType(lowering->loweredElements[i]);
8182
floatFields += (unsigned)varTypeIsFloating(type);
8283
INDEBUG(debugIntFields += (unsigned)varTypeIsIntegralOrI(type);)
8384
}
84-
intFields = lowering.numLoweredElements - floatFields;
85+
intFields = lowering->numLoweredElements - floatFields;
8586
assert(debugIntFields == intFields);
8687
}
8788
}
@@ -99,14 +100,14 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
99100
// Hardware floating-point calling convention
100101
if ((floatFields == 1) && (intFields == 0))
101102
{
102-
if (lowering.byIntegerCallConv)
103+
if (lowering == nullptr)
103104
{
104105
assert(varTypeIsFloating(type)); // standalone floating-point real
105106
}
106107
else
107108
{
108-
assert(lowering.numLoweredElements == 1); // struct containing just one FP real
109-
assert(varTypeIsFloating(JITtype2varType(lowering.loweredElements[0])));
109+
assert(lowering->numLoweredElements == 1); // struct containing just one FP real
110+
assert(varTypeIsFloating(JITtype2varType(lowering->loweredElements[0])));
110111
}
111112
return ABIPassingInformation::FromSegment(comp, ABIPassingSegment::InRegister(m_floatRegs.Dequeue(), 0,
112113
passedSize));
@@ -115,12 +116,13 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp,
115116
{
116117
assert(varTypeIsStruct(type));
117118
assert((floatFields + intFields) == 2);
118-
assert(!lowering.byIntegerCallConv);
119-
assert(lowering.numLoweredElements == 2);
119+
assert(lowering != nullptr);
120+
assert(!lowering->byIntegerCallConv);
121+
assert(lowering->numLoweredElements == 2);
120122

121123
var_types types[] = {
122-
JITtype2varType(lowering.loweredElements[0]),
123-
JITtype2varType(lowering.loweredElements[1]),
124+
JITtype2varType(lowering->loweredElements[0]),
125+
JITtype2varType(lowering->loweredElements[1]),
124126
};
125127
unsigned firstSize = (genTypeSize(types[0]) == 8) ? 8 : 4;
126128
unsigned secondSize = (genTypeSize(types[1]) == 8) ? 8 : 4;

0 commit comments

Comments
 (0)