Skip to content

Commit

Permalink
[VM] Add getRISCV64PassStructInRegisterFlags
Browse files Browse the repository at this point in the history
  • Loading branch information
clamp03 committed Apr 6, 2023
1 parent 43d90dc commit cd1ea45
Show file tree
Hide file tree
Showing 18 changed files with 394 additions and 69 deletions.
5 changes: 3 additions & 2 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
}
};

// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` API
// to convey struct argument passing information.
// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` and
// `getRISCV64PassStructInRegisterFlags` API to convey struct argument passing information.
//
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
//
Expand Down Expand Up @@ -3000,6 +3000,7 @@ class ICorStaticInfo
) = 0;

virtual uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
virtual uint32_t getRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
};

/*****************************************************************************
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ bool getSystemVAmd64PassStructInRegisterDescriptor(
uint32_t getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd) override;

uint32_t getRISCV64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd) override;

uint32_t getThreadTLSIndex(
void** ppIndirection) override;

Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3251,6 +3251,12 @@ private uint getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls)
return LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(typeDesc);
}

private uint getRISCV64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls)
{
TypeDesc typeDesc = HandleToObject(cls);
return RISCV64PassStructInRegister.GetRISCV64PassStructInRegisterFlags(typeDesc);
}

private uint getThreadTLSIndex(ref void* ppIndirection)
{ throw new NotImplementedException("getThreadTLSIndex"); }
private void* getInlinedCallFrameVptr(ref void* ppIndirection)
Expand Down
122 changes: 69 additions & 53 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,8 +1202,8 @@ public struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
public byte eightByteOffsets1;
};

// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` API
// to convey struct argument passing information.
// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` and
// `getRISCV64PassStructInRegisterFlags` API to convey struct argument passing information.
//
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
//
Expand Down
207 changes: 207 additions & 0 deletions src/coreclr/tools/Common/JitInterface/RISCV64PassStructInRegister.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using Internal.TypeSystem;

namespace Internal.JitInterface
{

internal static class RISCV64PassStructInRegister
{
public static uint GetRISCV64PassStructInRegisterFlags(TypeDesc typeDesc)
{
FieldDesc firstField = null;
uint floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
int numIntroducedFields = 0;
foreach (FieldDesc field in typeDesc.GetFields())
{
if (!field.IsStatic)
{
firstField ??= field;
numIntroducedFields++;
}
}

if ((numIntroducedFields == 0) || (numIntroducedFields > 2) || (typeDesc.GetElementSize().AsInt > 16))
{
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}

//// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers
if (typeDesc.IsIntrinsic)
{
throw new NotImplementedException("For RISCV64, SIMD would be implemented later");
}

MetadataType mdType = typeDesc as MetadataType;
Debug.Assert(mdType != null);

TypeDesc firstFieldElementType = firstField.FieldType;
int firstFieldSize = firstFieldElementType.GetElementSize().AsInt;

// A fixed buffer type is always a value type that has exactly one value type field at offset 0
// and who's size is an exact multiple of the size of the field.
// It is possible that we catch a false positive with this check, but that chance is extremely slim
// and the user can always change their structure to something more descriptive of what they want
// instead of adding additional padding at the end of a one-field structure.
// We do this check here to save looking up the FixedBufferAttribute when loading the field
// from metadata.
bool isFixedBuffer = numIntroducedFields == 1
&& firstFieldElementType.IsValueType
&& firstField.Offset.AsInt == 0
&& mdType.HasLayout()
&& ((typeDesc.GetElementSize().AsInt % firstFieldSize) == 0);

if (isFixedBuffer)
{
numIntroducedFields = typeDesc.GetElementSize().AsInt / firstFieldSize;
if (numIntroducedFields > 2)
{
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
}

int fieldIndex = 0;
foreach (FieldDesc field in typeDesc.GetFields())
{
if (fieldIndex > 1)
{
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
else if (field.IsStatic)
{
continue;
}

Debug.Assert(fieldIndex < numIntroducedFields);

switch (field.FieldType.Category)
{
case TypeFlags.Double:
{
if (numIntroducedFields == 1)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else if (fieldIndex == 0)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_DOUBLE;
}
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0)
{
floatFieldFlags ^= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND_8;
}
else
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_DOUBLE;
}
}
break;

case TypeFlags.Single:
{
if (numIntroducedFields == 1)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else if (fieldIndex == 0)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST;
}
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0)
{
floatFieldFlags ^= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND;
}
else
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND;
}
}
break;

case TypeFlags.ValueType:
//case TypeFlags.Class:
//case TypeFlags.Array:
//case TypeFlags.SzArray:
{
uint floatFieldFlags2 = GetRISCV64PassStructInRegisterFlags(field.FieldType);
if (numIntroducedFields == 1)
{
floatFieldFlags = floatFieldFlags2;
}
else if (field.FieldType.GetElementSize().AsInt > 8)
{
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
else if (fieldIndex == 0)
{
if ((floatFieldFlags2 & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST;
}
if (field.FieldType.GetElementSize().AsInt == 8)
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_SIZE_IS8;
}
}
else
{
Debug.Assert(fieldIndex == 1);
if ((floatFieldFlags2 & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND;
}
if (field.FieldType.GetElementSize().AsInt == 8)
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_SIZE_IS8;
}

floatFieldFlags2 = floatFieldFlags & ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND);
if (floatFieldFlags2 == 0)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
else if (floatFieldFlags2 == ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND))
{
floatFieldFlags ^= ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_TWO | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND);
}
}
}
break;

default:
{
if (field.FieldType.GetElementSize().AsInt == 8)
{
if (numIntroducedFields > 1)
{
if (fieldIndex == 0)
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_SIZE_IS8;
}
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0)
{
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_SIZE_IS8;
}
else
{
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
}
}
else if (fieldIndex == 1)
{
floatFieldFlags = (floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) > 0 ? floatFieldFlags : (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD;
}
break;
}
}

fieldIndex++;
}

return floatFieldFlags;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ FUNCTIONS
size_t findNameOfToken(CORINFO_MODULE_HANDLE moduleHandle,mdToken token, char * szFQName,size_t FQNameCapacity);
bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);
uint32_t getRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);
uint32_t getThreadTLSIndex(void **ppIndirection);
const void * getInlinedCallFrameVptr(void **ppIndirection);
int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
<Compile Include="..\..\Common\JitInterface\CorInfoTypes.VarInfo.cs" Link="JitInterface\CorInfoTypes.VarInfo.cs" />
<Compile Include="..\..\Common\JitInterface\SystemVStructClassificator.cs" Link="JitInterface\SystemVStructClassificator.cs" />
<Compile Include="..\..\Common\JitInterface\LoongArch64PassStructInRegister.cs" Link="JitInterface\LoongArch64PassStructInRegister.cs" />
<Compile Include="..\..\Common\JitInterface\RISCV64PassStructInRegister.cs" Link="JitInterface\RISCV64PassStructInRegister.cs" />
<Compile Include="..\..\Common\TypeSystem\Interop\InteropTypes.cs" Link="Interop\InteropTypes.cs" />
<Compile Include="..\..\Common\TypeSystem\Interop\UnmanagedCallingConventions.cs" Link="Interop\UnmanagedCallingConventions.cs" />
<Compile Include="..\ILCompiler.Reflection.ReadyToRun\PEReaderExtensions.cs" Link="Reflection\PEReaderExtensions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
<Compile Include="..\..\Common\JitInterface\LoongArch64PassStructInRegister.cs">
<Link>JitInterface\LoongArch64PassStructInRegister.cs</Link>
</Compile>
<Compile Include="..\..\Common\JitInterface\RISCV64PassStructInRegister.cs">
<Link>JitInterface\RISCV64PassStructInRegister.cs</Link>
</Compile>
<Compile Include="..\..\Common\Pgo\TypeSystemEntityOrUnknown.cs">
<Link>Pgo\TypeSystemEntityOrUnknown.cs</Link>
</Compile>
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/tools/aot/jitinterface/jitinterface_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct JitInterfaceCallbacks
size_t (* findNameOfToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE moduleHandle, unsigned int token, char* szFQName, size_t FQNameCapacity);
bool (* getSystemVAmd64PassStructInRegisterDescriptor)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
uint32_t (* getLoongArch64PassStructInRegisterFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd);
uint32_t (* getRISCV64PassStructInRegisterFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd);
uint32_t (* getThreadTLSIndex)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
const void* (* getInlinedCallFrameVptr)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
Expand Down Expand Up @@ -1425,6 +1426,15 @@ class JitInterfaceWrapper : public ICorJitInfo
return temp;
}

virtual uint32_t getRISCV64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
CorInfoExceptionClass* pException = nullptr;
uint32_t temp = _callbacks->getRISCV64PassStructInRegisterFlags(_thisHandle, &pException, structHnd);
if (pException != nullptr) throw pException;
return temp;
}

virtual uint32_t getThreadTLSIndex(
void** ppIndirection)
{
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ LWM(GetSharedCCtorHelper, DWORDLONG, DWORD)
LWM(GetStringConfigValue, DWORD, DWORD)
LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor)
LWM(GetLoongArch64PassStructInRegisterFlags, DWORDLONG, DWORD)
LWM(GetRISCV64PassStructInRegisterFlags, DWORDLONG, DWORD)
LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS)
LWM(UpdateEntryPointForTailCall, Agnostic_CORINFO_CONST_LOOKUP, Agnostic_CORINFO_CONST_LOOKUP)
LWM(GetThreadTLSIndex, DWORD, DLD)
Expand Down
25 changes: 25 additions & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6118,6 +6118,31 @@ DWORD MethodContext::repGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HA
return value;
}

void MethodContext::recGetRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value)
{
if (GetRISCV64PassStructInRegisterFlags == nullptr)
GetRISCV64PassStructInRegisterFlags = new LightWeightMap<DWORDLONG, DWORD>();

DWORDLONG key = CastHandle(structHnd);

GetRISCV64PassStructInRegisterFlags->Add(key, value);
DEBUG_REC(dmpGetRISCV64PassStructInRegisterFlags(key, value));
}

void MethodContext::dmpGetRISCV64PassStructInRegisterFlags(DWORDLONG key, DWORD value)
{
printf("GetRISCV64PassStructInRegisterFlags key %016" PRIX64 " value-%08X", key, value);
}

DWORD MethodContext::repGetRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd)
{
DWORDLONG key = CastHandle(structHnd);

DWORD value = LookupByKeyOrMissNoMessage(GetRISCV64PassStructInRegisterFlags, key);
DEBUG_REP(dmpGetRISCV64PassStructInRegisterFlags(key, value));
return value;
}

void MethodContext::recGetRelocTypeHint(void* target, WORD result)
{
if (GetRelocTypeHint == nullptr)
Expand Down
25 changes: 15 additions & 10 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,10 @@ class MethodContext
void dmpGetLoongArch64PassStructInRegisterFlags(DWORDLONG key, DWORD value);
DWORD repGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);

void recGetRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value);
void dmpGetRISCV64PassStructInRegisterFlags(DWORDLONG key, DWORD value);
DWORD repGetRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);

void recGetRelocTypeHint(void* target, WORD result);
void dmpGetRelocTypeHint(DWORDLONG key, DWORD value);
WORD repGetRelocTypeHint(void* target);
Expand Down Expand Up @@ -1152,16 +1156,17 @@ enum mcPackets
Packet_IsIntrinsic = 192,
Packet_UpdateEntryPointForTailCall = 193,
Packet_GetLoongArch64PassStructInRegisterFlags = 194,
Packet_GetExactClasses = 195,
Packet_GetRuntimeTypePointer = 196,
Packet_PrintObjectDescription = 197,
Packet_GetReadonlyStaticFieldValue = 198,
Packet_GetObjectType = 199,
Packet_IsObjectImmutable = 200,
Packet_ExpandRawHandleIntrinsic = 201,
Packet_GetArrayOrStringLength = 202,
Packet_IsEnum = 203,
Packet_GetStringChar = 204,
Packet_GetRISCV64PassStructInRegisterFlags = 195,
Packet_GetExactClasses = 196,
Packet_GetRuntimeTypePointer = 197,
Packet_PrintObjectDescription = 198,
Packet_GetReadonlyStaticFieldValue = 199,
Packet_GetObjectType = 200,
Packet_IsObjectImmutable = 201,
Packet_ExpandRawHandleIntrinsic = 202,
Packet_GetArrayOrStringLength = 203,
Packet_IsEnum = 204,
Packet_GetStringChar = 205,
};

void SetDebugDumpVariables();
Expand Down
Loading

0 comments on commit cd1ea45

Please sign in to comment.