Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISC-V] Transfer arguments between calling conventions in shuffling thunks #107282

Merged
merged 66 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
70cf57f
Log ShuffleEntries from GenerateShuffleArray
tomeksowi Aug 2, 2024
1377172
Add failing tests for passing FP structs through shuffling thunks
tomeksowi Aug 2, 2024
1cec66b
Report proper ShuffleEntries for lowered FP structs
tomeksowi Aug 7, 2024
329321b
Implement shuffling thunk generation in tighter, more focused loops i…
tomeksowi Aug 13, 2024
9a50786
Generate ShuffleEntries for delowered arguments
tomeksowi Aug 20, 2024
87c8397
Better ShuffleEntry mask names, one more bit for field offset
tomeksowi Aug 20, 2024
8b3b470
Fix FpStruct for dst arg loc
tomeksowi Aug 21, 2024
1a14067
Fold ShuffleEntry generation code for lowering and delowering FpStructs
tomeksowi Aug 21, 2024
6fa6d18
ShuffleEntry mask doc update
tomeksowi Aug 21, 2024
114583a
Implement forward shuffling of floating registers and delowering of F…
tomeksowi Aug 22, 2024
331d77e
Fix shuffling of integer registers for member functions
tomeksowi Aug 23, 2024
1d96d11
The delowered argument can also be put in the first stack slot
tomeksowi Aug 23, 2024
30edbc5
Stask shuffling after delowered argument doesn't start with 0. Fixes …
tomeksowi Aug 23, 2024
a445275
Code cleanup, fewer indents
tomeksowi Aug 23, 2024
bec2d89
Support second lowering
tomeksowi Aug 23, 2024
83dee89
Remove unused CondCode
tomeksowi Aug 26, 2024
b1466a0
Handle stack slot shuffling to the right
tomeksowi Aug 28, 2024
6a7d2ce
Add some stack slots to shuffle in the growing stack test case
tomeksowi Aug 28, 2024
bb28b72
Fix Equals signature on test structs
tomeksowi Aug 28, 2024
dbb5338
Remodel the shuffling with calling convention transfer to recognize t…
tomeksowi Aug 30, 2024
68e0c36
Use helper functions in EmitComputedInstantiatingMethodStub
tomeksowi Aug 30, 2024
015aed0
Implement stack growing in shuffling thunk
tomeksowi Sep 2, 2024
3dcc74c
Use signed immediate in EmitSubImm to be consistent with EmitAddImm
tomeksowi Sep 2, 2024
afdec48
Use ABI register names in logs
tomeksowi Sep 2, 2024
84bffa4
Remove LoadRegPair because it's not used
tomeksowi Sep 2, 2024
de61b96
Add logging for slli and lui
tomeksowi Sep 3, 2024
750122a
Remove stack growing from hand-emitted shuffle thunks
tomeksowi Sep 4, 2024
d12ca52
Minor FloatFloatEmpty test cleanup
tomeksowi Sep 6, 2024
461f0c3
Implement IL shuffling thunks for cases where the stack is growing
tomeksowi Sep 9, 2024
fea44e3
Test stack walking in frames laid by the IL shuffle thunk
tomeksowi Sep 9, 2024
64a4a62
Add assert and comment in CreateILDelegateShuffleThunk
tomeksowi Sep 9, 2024
1c7b0b1
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Sep 9, 2024
7f81c07
Fix release build
tomeksowi Sep 10, 2024
4b1b31a
Fixes for static delegates from member methods
tomeksowi Sep 10, 2024
2edf53d
Fix log and comment
tomeksowi Sep 10, 2024
74dcd7c
Remove EmitJumpAndLinkRegister because it's no longer used
tomeksowi Sep 10, 2024
c5f72c6
Use TransferredField.reg in delowering (cosmetic fix to restart CI)
tomeksowi Sep 11, 2024
5ed7466
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Sep 16, 2024
3bbc188
New stub type for delegate shuffle thunk so it doesn't go in multidel…
tomeksowi Sep 16, 2024
268a28b
Make Test_ShufflingThunk_MemberGrowsStack_RiscV harder by returning v…
tomeksowi Sep 16, 2024
ccd4aae
Explain lowering
tomeksowi Sep 18, 2024
1c18c46
Fold 12-bit sign extension branch in EmitMovConstant
tomeksowi Sep 18, 2024
6c7e29f
Harden Test_ShufflingThunk_PackedEmptyUintEmptyFloat_PackedEmptyDoubl…
tomeksowi Sep 18, 2024
12eb8ba
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Sep 20, 2024
f4620c4
Handle shuffles between calling conventions in IL stubs
tomeksowi Sep 23, 2024
2e20dfa
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Sep 23, 2024
c2acecb
Update comments
tomeksowi Sep 25, 2024
5773596
Don't use NewStub for IL stubs
tomeksowi Sep 26, 2024
cdd04ec
Fold some more duplicated code into SetupShuffleThunk
tomeksowi Sep 26, 2024
ae18a27
Clean up unnecessary diffs
tomeksowi Sep 26, 2024
c4025b7
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Sep 27, 2024
a008f20
IL shuffle thunk takes target function address from delegate object. …
tomeksowi Oct 1, 2024
2900dfb
Build target signature based on delegate signature instead of just us…
tomeksowi Oct 3, 2024
fe5d775
Test calling instance and static methods via the same delegate type
tomeksowi Oct 3, 2024
9321b07
Simplify shuffle thunk caching on DelegateEEClass
tomeksowi Oct 3, 2024
5e1455c
Clean up CreateILDelegateShuffleThunk
tomeksowi Oct 3, 2024
ec1c57a
Delete Windows X86 stack size check
tomeksowi Oct 8, 2024
27c005f
Remove #ifdefs around ILSTUB_DELEGATE_SHUFFLE_THUNK, fix typo in GetS…
tomeksowi Oct 8, 2024
b9201b1
Fix DecRef'ing path when the IL thunk is already cached on DelegateEE…
tomeksowi Oct 8, 2024
e41802f
Fix shuffle thunk destruction in EEClass::Destruct: properly handle I…
tomeksowi Oct 8, 2024
118f191
Don't use RemoveStubRange in the destructor, make code for dereferenc…
tomeksowi Oct 9, 2024
5832103
Remove unused RemoveStubRange
tomeksowi Oct 9, 2024
7fe3c4e
Cover IL shuffle thunks in ILStubManager::TraceManager
tomeksowi Oct 9, 2024
659a9e4
Remove unused start, end arguments from RangeList::RemoveRanges[Worker]
tomeksowi Oct 9, 2024
ccf1e4e
Update src/coreclr/vm/comdelegate.cpp
jkotas Oct 9, 2024
e45db16
Merge branch 'main' into fp-structs-shuffling-thunks
tomeksowi Oct 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/vm/callingconvention.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE
//------------------------------------------------------------
int GetNextOffset();

CorElementType GetArgType(TypeHandle *pTypeHandle = NULL)
CorElementType GetArgType(TypeHandle *pTypeHandle = NULL) const
{
LIMITED_METHOD_CONTRACT;
if (pTypeHandle != NULL)
Expand All @@ -652,7 +652,7 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE
return m_argType;
}

int GetArgSize()
int GetArgSize() const
{
LIMITED_METHOD_CONTRACT;
return m_argSize;
Expand Down
276 changes: 240 additions & 36 deletions src/coreclr/vm/comdelegate.cpp

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions src/coreclr/vm/comdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,28 @@ struct ShuffleEntry
FPREGMASK = 0x4000, // Floating point register bit
FPSINGLEMASK = 0x2000, // Single precising floating point register
OFSMASK = 0x7fff, // Mask to get stack offset
#if defined(TARGET_RISCV64)
// Whether it's a field of an argument transferred between integer and floating-point calling conventions,
// in which case field size and offset are avalilable.
CALLCONVTRANSFERMASK = FPSINGLEMASK,
OFSREGMASK = 0x7, // Mask to get register index
FIELDSIZESHIFTPOS = 3,
FIELDSIZESHIFTMASK = 0x3 << FIELDSIZESHIFTPOS, // Mask to get field log2(size) of FP struct
FIELDOFFSETPOS = FIELDSIZESHIFTPOS + 2,
FIELDOFFSETMASK = 0xf << FIELDOFFSETPOS, // Mask to get field offset of FP struct
#else
OFSREGMASK = 0x1fff, // Mask to get register index
#endif // TARGET_RISCV64
SENTINEL = 0xffff, // Indicates end of shuffle array
HELPERREG = 0xcfff, // Use a helper register as source or destination (used to handle cycles in the shuffling)
};

#if defined(TARGET_RISCV64)
static_assert((OFSREGMASK & FIELDSIZESHIFTMASK) == 0, "must not overlap");
static_assert((FIELDSIZESHIFTMASK & FIELDOFFSETMASK) == 0, "must not overlap");
static_assert((FIELDOFFSETMASK & (REGMASK | FPREGMASK | CALLCONVTRANSFERMASK)) == 0, "must not overlap");
#endif

UINT16 srcofs;

union {
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/dllimport.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ enum ILStubTypes
ILSTUB_TAILCALL_STOREARGS = 0x80000008,
ILSTUB_TAILCALL_CALLTARGET = 0x80000009,
ILSTUB_STATIC_VIRTUAL_DISPATCH_STUB = 0x8000000A,
#ifdef TARGET_RISCV64
ILSTUB_DELEGATE_SHUFFLE_THUNK = 0x8000000B,
#endif
};

#ifdef FEATURE_COMINTEROP
Expand Down Expand Up @@ -238,6 +241,9 @@ inline bool SF_IsInstantiatingStub (DWORD dwStubFlags) { LIMITED_METHOD_CON
#endif
inline bool SF_IsTailCallStoreArgsStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_TAILCALL_STOREARGS); }
inline bool SF_IsTailCallCallTargetStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_TAILCALL_CALLTARGET); }
#ifdef TARGET_RISCV64
inline bool SF_IsDelegateShuffleThunk (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_DELEGATE_SHUFFLE_THUNK); }
#endif // TARGET_RISCV64
tomeksowi marked this conversation as resolved.
Show resolved Hide resolved

inline bool SF_IsCOMStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_COM)); }
inline bool SF_IsCOMLateBoundStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_COMLATEBOUND)); }
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/vm/ilstubcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ namespace
case DynamicMethodDesc::StubTailCallStoreArgs: return "IL_STUB_StoreTailCallArgs";
case DynamicMethodDesc::StubTailCallCallTarget: return "IL_STUB_CallTailCallTarget";
case DynamicMethodDesc::StubVirtualStaticMethodDispatch: return "IL_STUB_bVirtualStaticMethodDispatch";
tomeksowi marked this conversation as resolved.
Show resolved Hide resolved
#ifdef TARGET_RISCV64
case DynamicMethodDesc::StubDelegateShuffleThunk: return "IL_STUB_bDelegateShuffleThunk";
#endif
tomeksowi marked this conversation as resolved.
Show resolved Hide resolved
default:
UNREACHABLE_MSG("Unknown stub type");
}
Expand Down Expand Up @@ -297,6 +300,13 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
pMD->SetILStubType(DynamicMethodDesc::StubVirtualStaticMethodDispatch);
}
else
#ifdef TARGET_RISCV64
if (SF_IsDelegateShuffleThunk(dwStubFlags))
{
pMD->SetILStubType(DynamicMethodDesc::StubDelegateShuffleThunk);
}
else
#endif // TARGET_RISCV64
tomeksowi marked this conversation as resolved.
Show resolved Hide resolved
{
// mark certain types of stub MDs with random flags so ILStubManager recognizes them
if (SF_IsReverseStub(dwStubFlags))
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2512,6 +2512,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc
StubTailCallCallTarget,

StubVirtualStaticMethodDispatch,
StubDelegateShuffleThunk,

StubLast
};
Expand Down
17 changes: 6 additions & 11 deletions src/coreclr/vm/riscv64/cgencpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,15 +360,6 @@ struct FloatReg
WORD Mask() const { return 1 << reg; }
};

struct CondCode
{
int cond;
CondCode(int cond):cond(cond)
{
_ASSERTE(0 <= cond && cond < 16);
}
};

const IntReg RegSp = IntReg(2);
const IntReg RegFp = IntReg(8);
const IntReg RegRa = IntReg(1);
Expand All @@ -392,6 +383,7 @@ class StubLinkerCPU : public StubLinker
void EmitCallLabel(CodeLabel *target, BOOL fTailCall, BOOL fIndirect);

void EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray);
void EmitShufflingWithCallingConventionTransfers(const struct ShuffleEntry *pShuffleEntryArray);

#if defined(FEATURE_SHARE_GENERIC_CODE)
void EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg);
Expand All @@ -402,15 +394,18 @@ class StubLinkerCPU : public StubLinker
void EmitMovReg(IntReg dest, IntReg source);
void EmitMovReg(FloatReg dest, FloatReg source);

void EmitSubImm(IntReg Xd, IntReg Xn, unsigned int value);
void EmitAddImm(IntReg Xd, IntReg Xn, unsigned int value);
void EmitSubImm(IntReg Xd, IntReg Xn, int value);
void EmitAddImm(IntReg Xd, IntReg Xn, int value);
void EmitSllImm(IntReg Xd, IntReg Xn, unsigned int value);
void EmitLuImm(IntReg Xd, unsigned int value);

void EmitLoad(IntReg dest, IntReg srcAddr, int offset = 0);
void EmitLoad(FloatReg dest, IntReg srcAddr, int offset = 0);
void EmitAnyLoad(bool isFloat, unsigned int sizeShift, int destReg, IntReg srcAddr, int offset = 0);

void EmitStore(IntReg src, IntReg destAddr, int offset = 0);
void EmitStore(FloatReg src, IntReg destAddr, int offset = 0);
void EmitAnyStore(bool isFloat, unsigned int sizeShift, int srcReg, IntReg destAddr, int offset = 0);

void EmitProlog(unsigned short cIntRegArgs, unsigned short cFpRegArgs, unsigned short cbStackSpace = 0);
void EmitEpilog();
Expand Down
Loading