Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -3173,6 +3173,10 @@ class ICorStaticInfo
// Returns lowering info for fields of a RISC-V/LoongArch struct passed in registers according to
// hardware floating-point calling convention.
virtual void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering) = 0;

// Returns the primitive type for passing/returning a Wasm struct by value,
// or CORINFO_TYPE_UNDEF if passing/returning must be by reference.
virtual CorInfoType getWasmLowering(CORINFO_CLASS_HANDLE structHnd) = 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 @@ -535,6 +535,9 @@ void getFpStructLowering(
CORINFO_CLASS_HANDLE structHnd,
CORINFO_FPSTRUCT_LOWERING* pLowering) override;

CorInfoType getWasmLowering(
CORINFO_CLASS_HANDLE structHnd) override;

uint32_t getThreadTLSIndex(
void** ppIndirection) override;

Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* 976a4d6d-d1b2-4096-a3c9-46ddcae71196 */
0x976a4d6d,
0xd1b2,
0x4096,
{0xa3, 0xc9, 0x46, 0xdd, 0xca, 0xe7, 0x11, 0x96}
constexpr GUID JITEEVersionIdentifier = { /* 27ef98b9-21db-46a5-bb25-1ca4b88ce24c */
0x27ef98b9,
0x21db,
0x46a5,
{0xbb, 0x25, 0x1c, 0xa4, 0xb8, 0x8c, 0xe2, 0x4c}
};

#endif // JIT_EE_VERSIONING_GUID_H
1 change: 1 addition & 0 deletions src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ DEF_CLR_API(getMethodHash)
DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor)
DEF_CLR_API(getSwiftLowering)
DEF_CLR_API(getFpStructLowering)
DEF_CLR_API(getWasmLowering)
DEF_CLR_API(getThreadTLSIndex)
DEF_CLR_API(getAddrOfCaptureThreadGlobal)
DEF_CLR_API(getHelperFtn)
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,15 @@ void WrapICorJitInfo::getFpStructLowering(
API_LEAVE(getFpStructLowering);
}

CorInfoType WrapICorJitInfo::getWasmLowering(
CORINFO_CLASS_HANDLE structHnd)
{
API_ENTER(getWasmLowering);
CorInfoType temp = wrapHnd->getWasmLowering(structHnd);
API_LEAVE(getWasmLowering);
return temp;
}

uint32_t WrapICorJitInfo::getThreadTLSIndex(
void** ppIndirection)
{
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,10 @@ void CodeGen::genGenerateMachineCode()
printf("generic LOONGARCH64");
#elif defined(TARGET_RISCV64)
printf("generic RISCV64");
#elif defined(TARGET_WASM32)
printf("wasm32");
#elif defined(TARGET_WASM64)
printf("wasm64");
#else
printf("unknown architecture");
#endif
Expand Down
30 changes: 30 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,36 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
}
assert(structSize > 0);

#if defined(TARGET_WASM)
CorInfoType abiType = info.compCompHnd->getWasmLowering(clsHnd);

if (abiType == CORINFO_TYPE_UNDEF)
{
howToReturnStruct = SPK_ByReference;
useType = TYP_UNKNOWN;
}
else
{
howToReturnStruct = SPK_ByValue;
useType = JITtype2varType(abiType);
}

if (wbReturnStruct != nullptr)
{
*wbReturnStruct = howToReturnStruct;
}

return useType;
#else
#ifdef DEBUG
// Extra query to facilitate wasm replay
if (JitConfig.EnableExtraSuperPmiQueries())
{
info.compCompHnd->getWasmLowering(clsHnd);
}
#endif // DEBUG
#endif // defined(TARGET_WASM)

#ifdef SWIFT_SUPPORT
if (callConv == CorInfoCallConvExtension::Swift)
{
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,18 @@ void Compiler::lvaClassifyParameterABI(Classifier& classifier)

dsc->lvIsRegArg = numRegisters > 0;
dsc->lvIsMultiRegArg = numRegisters > 1;

#ifdef DEBUG
// Extra query to facilitate wasm replay
if (JitConfig.EnableExtraSuperPmiQueries() && (structLayout != nullptr))
{
CORINFO_CLASS_HANDLE clsHnd = structLayout->GetClassHandle();
if (clsHnd != NO_CLASS_HANDLE)
{
info.compCompHnd->getWasmLowering(clsHnd);
}
}
#endif
}

lvaParameterStackSize = classifier.StackSize();
Expand Down
16 changes: 15 additions & 1 deletion src/coreclr/jit/targetwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,21 @@ ABIPassingInformation WasmClassifier::Classify(Compiler* comp,
{
if (type == TYP_STRUCT)
{
NYI_WASM("WasmClassifier::Classify - structs");
CORINFO_CLASS_HANDLE clsHnd = structLayout->GetClassHandle();
assert(clsHnd != NO_CLASS_HANDLE);
CorInfoType abiType = comp->info.compCompHnd->getWasmLowering(clsHnd);
bool passByRef = false;

if (abiType == CORINFO_TYPE_UNDEF)
{
abiType = CORINFO_TYPE_NATIVEINT;
passByRef = true;
}

var_types type = JITtype2varType(abiType);
regNumber reg = MakeWasmReg(m_localIndex++, genActualType(type));
ABIPassingSegment seg = ABIPassingSegment::InRegister(reg, 0, genTypeSize(type));
return ABIPassingInformation::FromSegment(comp, passByRef, seg);
}

regNumber reg = MakeWasmReg(m_localIndex++, genActualType(type));
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 @@ -3616,6 +3616,12 @@ private void getFpStructLowering(CORINFO_CLASS_STRUCT_* structHnd, ref CORINFO_F
}
}

private CorInfoType getWasmLowering(CORINFO_CLASS_STRUCT_* structHnd)
{
uint size = getClassSize(structHnd);
return WasmLowering.LowerTypeForWasm(HandleToObject(structHnd), size);
}

private uint getThreadTLSIndex(ref void* ppIndirection)
{ throw new NotImplementedException("getThreadTLSIndex"); }

Expand Down
17 changes: 17 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ static ICorJitInfoCallbacks()
s_callbacks.getSystemVAmd64PassStructInRegisterDescriptor = &_getSystemVAmd64PassStructInRegisterDescriptor;
s_callbacks.getSwiftLowering = &_getSwiftLowering;
s_callbacks.getFpStructLowering = &_getFpStructLowering;
s_callbacks.getWasmLowering = &_getWasmLowering;
s_callbacks.getThreadTLSIndex = &_getThreadTLSIndex;
s_callbacks.getAddrOfCaptureThreadGlobal = &_getAddrOfCaptureThreadGlobal;
s_callbacks.getHelperFtn = &_getHelperFtn;
Expand Down Expand Up @@ -327,6 +328,7 @@ static ICorJitInfoCallbacks()
public delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte> getSystemVAmd64PassStructInRegisterDescriptor;
public delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_SWIFT_LOWERING*, void> getSwiftLowering;
public delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CORINFO_FPSTRUCT_LOWERING*, void> getFpStructLowering;
public delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, CorInfoType> getWasmLowering;
public delegate* unmanaged<IntPtr, IntPtr*, void**, uint> getThreadTLSIndex;
public delegate* unmanaged<IntPtr, IntPtr*, void**, int*> getAddrOfCaptureThreadGlobal;
public delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, CORINFO_CONST_LOOKUP*, CORINFO_METHOD_STRUCT_**, void> getHelperFtn;
Expand Down Expand Up @@ -2271,6 +2273,21 @@ private static void _getFpStructLowering(IntPtr thisHandle, IntPtr* ppException,
}
}

[UnmanagedCallersOnly]
private static CorInfoType _getWasmLowering(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* structHnd)
{
var _this = GetThis(thisHandle);
try
{
return _this.getWasmLowering(structHnd);
}
catch (Exception ex)
{
*ppException = _this.AllocException(ex);
return default;
}
}

[UnmanagedCallersOnly]
private static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ FUNCTIONS
bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
void getSwiftLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering);
void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering);
CorInfoType getWasmLowering(CORINFO_CLASS_HANDLE structHnd);
uint32_t getThreadTLSIndex(void **ppIndirection);
int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection);
void getHelperFtn (CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE *pMethod);
Expand Down
124 changes: 124 additions & 0 deletions src/coreclr/tools/Common/JitInterface/WasmLowering.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using ILCompiler;
using Internal.TypeSystem;

namespace Internal.JitInterface
{
public static class WasmLowering
{
// The Wasm "basic C ABI" passes structs that contain one
// primitive field as that primitive field.
//
// Analyze the type and determine if it should be passed
// as a primitive, and if so, which type. If not, return
// CORINFO_TYPE_UNDEF.

public static CorInfoType LowerTypeForWasm(TypeDesc type, uint size)
{
if (!type.IsValueType)
{
Debug.Fail("Non-struct types should passed directly in Wasm.");
return CorInfoType.CORINFO_TYPE_UNDEF;
}

MetadataType mdType = type as MetadataType;
if (mdType.HasImpliedRepeatedFields())
{
return CorInfoType.CORINFO_TYPE_UNDEF;
}

switch (size)
{
case 1:
case 2:
case 4:
case 8:
break;

default:
return CorInfoType.CORINFO_TYPE_UNDEF;
}

while (true)
{
FieldDesc firstField = null;
int numIntroducedFields = 0;
foreach (FieldDesc field in type.GetFields())
{
if (!field.IsStatic)
{
firstField ??= field;
numIntroducedFields++;
}

if (numIntroducedFields > 1)
{
break;
}
}

if (numIntroducedFields != 1)
{
return CorInfoType.CORINFO_TYPE_UNDEF;
}

TypeDesc firstFieldElementType = firstField.FieldType;

if (firstFieldElementType.IsValueType)
{
type = firstFieldElementType;
continue;
}

return WasmTypeClassification(firstFieldElementType, size);
}
}

private static CorInfoType WasmTypeClassification(TypeDesc typeDesc, uint size)
{
switch (typeDesc.Category)
{
case TypeFlags.Boolean:
case TypeFlags.Char:
case TypeFlags.SByte:
case TypeFlags.Byte:
case TypeFlags.Int16:
case TypeFlags.UInt16:
case TypeFlags.Int32:
case TypeFlags.UInt32:
return (size > 4) ? CorInfoType.CORINFO_TYPE_LONG : CorInfoType.CORINFO_TYPE_INT;

case TypeFlags.Int64:
case TypeFlags.UInt64:
return CorInfoType.CORINFO_TYPE_LONG;

case TypeFlags.Single:
return (size > 4) ? CorInfoType.CORINFO_TYPE_DOUBLE : CorInfoType.CORINFO_TYPE_FLOAT;
case TypeFlags.Double:
return CorInfoType.CORINFO_TYPE_DOUBLE;

case TypeFlags.Enum:
return WasmTypeClassification(typeDesc.UnderlyingType, size);

case TypeFlags.IntPtr:
case TypeFlags.UIntPtr:
case TypeFlags.Pointer:
case TypeFlags.FunctionPointer:
case TypeFlags.Class:
case TypeFlags.Interface:
case TypeFlags.Array:
case TypeFlags.SzArray:
case TypeFlags.ByRef:
return CorInfoType.CORINFO_TYPE_NATIVEINT;

default:
return CorInfoType.CORINFO_TYPE_UNDEF;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
<Compile Include="..\..\Common\JitInterface\SystemVStructClassificator.cs" Link="JitInterface\SystemVStructClassificator.cs" />
<Compile Include="..\..\Common\Internal\Runtime\RiscVLoongArch64FpStruct.cs" Link="Common\RiscVLoongArch64FpStruct.cs" />
<Compile Include="..\..\Common\JitInterface\SwiftPhysicalLowering.cs" Link="JitInterface\SwiftPhysicalLowering.cs" />
<Compile Include="..\..\Common\JitInterface\WasmLowering.cs" Link="JitInterface\WasmLowering.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="..\..\Common\Compiler\ObjectWriter\Dwarf\DwarfHelper.cs" Link="Compiler\ObjectWriter\Dwarf\DwarfHelper.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
<Compile Include="..\..\Common\JitInterface\SwiftPhysicalLowering.cs">
<Link>JitInterface\SwiftPhysicalLowering.cs</Link>
</Compile>
<Compile Include="..\..\Common\JitInterface\WasmLowering.cs">
<Link>JitInterface\WasmLowering.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 @@ -139,6 +139,7 @@ struct JitInterfaceCallbacks
bool (* getSystemVAmd64PassStructInRegisterDescriptor)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
void (* getSwiftLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering);
void (* getFpStructLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering);
CorInfoType (* getWasmLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd);
uint32_t (* getThreadTLSIndex)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
void (* getHelperFtn)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE* pMethod);
Expand Down Expand Up @@ -1441,6 +1442,15 @@ class JitInterfaceWrapper : public ICorJitInfo
if (pException != nullptr) throw pException;
}

virtual CorInfoType getWasmLowering(
CORINFO_CLASS_HANDLE structHnd)
{
CorInfoExceptionClass* pException = nullptr;
CorInfoType temp = _callbacks->getWasmLowering(_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 @@ -127,6 +127,7 @@ LWM(GetStringConfigValue, DWORD, DWORD)
LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor)
LWM(GetSwiftLowering, DWORDLONG, Agnostic_GetSwiftLowering)
LWM(GetFpStructLowering, DWORDLONG, Agnostic_GetFpStructLowering)
LWM(GetWasmLowering, DWORDLONG, DWORD)
LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS)
LWM(GetAsyncResumptionStub, DWORD, DLDL)
LWM(GetContinuationType, Agnostic_GetContinuationTypeIn, DWORDLONG)
Expand Down
Loading
Loading