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

Intrinsify typeof(T).GetGenericTypeDefinition() #103528

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f5c77e5
Add getTypeDefinition definition
Sergio0694 Jan 18, 2024
7b27bb2
Implement CEEInfo::getTypeDefinition
Sergio0694 Jan 18, 2024
f7e8951
Tweak CEEInfo::getTypeDefinition
Sergio0694 Jan 18, 2024
9d6ec48
Make Type.GetGenericTypeDefinition() an intrinsic
Sergio0694 Jan 18, 2024
b537505
Add GetGenericTypeDefinition() intrinsic tests
Sergio0694 Jan 18, 2024
a02c9a1
Only expand intrinsic for generic types
Sergio0694 Jan 18, 2024
23f8ebc
Use normal JIT_TO_EE transition
Sergio0694 Jan 18, 2024
d6a925d
Apply review suggestions for CEEInfo::getTypeDefinition
Sergio0694 Jan 18, 2024
cf937db
Implement managed version of getTypeDefinition
Sergio0694 Jan 18, 2024
98952fc
Fix EE_TO_JIT transition
Sergio0694 Jan 18, 2024
f65d626
Implement missing superPMI methods
Sergio0694 Mar 11, 2024
cfad15d
Remove extra blank line
Sergio0694 Jun 16, 2024
f3b5402
Add missing handle -> 'Type' conversion
Sergio0694 Jun 16, 2024
b44805d
Add '__Canon' tests as well
Sergio0694 Jun 17, 2024
447f949
Add tests for failure cases as well
Sergio0694 Jun 17, 2024
1ccc84f
Run ThunkGenerator again
Sergio0694 Jul 10, 2024
7175c3a
Add docs for 'impGetGenericTypeDefinition'
Sergio0694 Jul 11, 2024
ae66298
Add assert in 'getTypeDefinition'
Sergio0694 Jul 11, 2024
9a2aa1e
Remove assert
Sergio0694 Jul 11, 2024
a2eb42e
Allow non instantiated generics in new JIT interface method
Sergio0694 Jul 11, 2024
a2a8d60
Update docs for 'getTypeDefinition'
Sergio0694 Jul 16, 2024
89319d7
Tweak condition in 'CEEInfo::getTypeDefinition'
Sergio0694 Jul 17, 2024
4cbe7f3
Run ThunkGenerator again
Sergio0694 Jul 18, 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
16 changes: 16 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,22 @@ class ICorStaticInfo
CORINFO_METHOD_HANDLE meth1Hnd,
CORINFO_METHOD_HANDLE meth2Hnd) = 0;

//------------------------------------------------------------------------------
// getTypeDefinition: Get the (unconstructed) type definition from a given type handle.
//
// Arguments:
// type - The input type handle
//
// Return Value:
// The type handle for the (unconstructed) type definition from type.
//
// Remarks:
// This is equivalent of Type.GetGenericTypeDefinition(). Given a generic type handle, it will
Sergio0694 marked this conversation as resolved.
Show resolved Hide resolved
// return the original type definition (eg. for Foo<int> it will return Foo<>). If called with
// an unconstructed generic type, the method returns the same type as the input. This method
// should only be called when the input type is in fact a generic type.
Sergio0694 marked this conversation as resolved.
Show resolved Hide resolved
virtual CORINFO_CLASS_HANDLE getTypeDefinition(CORINFO_CLASS_HANDLE type) = 0;

// Decides if you have any limitations for inlining. If everything's OK, it will return
// INLINE_PASS.
//
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 @@ -48,6 +48,9 @@ bool haveSameMethodDefinition(
CORINFO_METHOD_HANDLE meth1Hnd,
CORINFO_METHOD_HANDLE meth2Hnd) override;

CORINFO_CLASS_HANDLE getTypeDefinition(
CORINFO_CLASS_HANDLE type) override;

CorInfoInline canInline(
CORINFO_METHOD_HANDLE callerHnd,
CORINFO_METHOD_HANDLE calleeHnd) 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 @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED

constexpr GUID JITEEVersionIdentifier = { /* 64fe30fb-0a27-4b1d-b89e-306e552ac848 */
0x64fe30fb,
0x0a27,
0x4b1d,
{0xb8, 0x9e, 0x30, 0x6e, 0x55, 0x2a, 0xc8, 0x48}
constexpr GUID JITEEVersionIdentifier = { /* 273ba350-32bf-4714-beb0-7fa46c11364d */
0x273ba350,
0x32bf,
0x4714,
{0xbe, 0xb0, 0x7f, 0xa4, 0x6c, 0x11, 0x36, 0x4d}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
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 @@ -11,6 +11,7 @@ DEF_CLR_API(setMethodAttribs)
DEF_CLR_API(getMethodSig)
DEF_CLR_API(getMethodInfo)
DEF_CLR_API(haveSameMethodDefinition)
DEF_CLR_API(getTypeDefinition)
DEF_CLR_API(canInline)
DEF_CLR_API(beginInlining)
DEF_CLR_API(reportInliningDecision)
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 @@ -79,6 +79,15 @@ bool WrapICorJitInfo::haveSameMethodDefinition(
return temp;
}

CORINFO_CLASS_HANDLE WrapICorJitInfo::getTypeDefinition(
CORINFO_CLASS_HANDLE type)
{
API_ENTER(getTypeDefinition);
CORINFO_CLASS_HANDLE temp = wrapHnd->getTypeDefinition(type);
API_LEAVE(getTypeDefinition);
return temp;
}

CorInfoInline WrapICorJitInfo::canInline(
CORINFO_METHOD_HANDLE callerHnd,
CORINFO_METHOD_HANDLE calleeHnd)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4589,6 +4589,7 @@ class Compiler
#endif
void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom);
GenTree* impGetGenericTypeDefinition(GenTree* type);

// Mirrors StringComparison.cs
enum StringComparison
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_System_Type_get_IsByRefLike:
case NI_System_Type_get_IsGenericType:
case NI_System_Type_GetTypeFromHandle:
case NI_System_Type_GetGenericTypeDefinition:
case NI_System_String_get_Length:
case NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness:
#if defined(FEATURE_HW_INTRINSICS)
Expand Down
36 changes: 36 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2490,6 +2490,42 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom)
return nullptr;
}

//------------------------------------------------------------------------
// impGetGenericTypeDefinition: gets the generic type definition from a 'typeof' expression.
//
// Arguments:
// type - The 'GenTree' node to inspect.
//
// Notes:
// If successful, this method will call 'impPopStack()' before returning.
//
GenTree* Compiler::impGetGenericTypeDefinition(GenTree* type)
Sergio0694 marked this conversation as resolved.
Show resolved Hide resolved
{
// This intrinsic requires the first arg to be some `typeof()` expression,
// ie. it applies to cases such as `typeof(...).GetGenericTypeDefinition()`.
CORINFO_CLASS_HANDLE hClassType = NO_CLASS_HANDLE;
if (gtIsTypeof(type, &hClassType))
{
// Check that the 'typeof()' expression is being used on a type that is in fact generic.
// If that is not the case, we don't expand the intrinsic. This will end up using
// the usual Type.GetGenericTypeDefinition() at runtime, which will throw in this case.
if (info.compCompHnd->getTypeInstantiationArgument(hClassType, 0) != NO_CLASS_HANDLE)
{
CORINFO_CLASS_HANDLE hClassResult = info.compCompHnd->getTypeDefinition(hClassType);

GenTree* handle = gtNewIconEmbClsHndNode(hClassResult);
GenTree* retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle);

// Drop the typeof(T) node
impPopStack();
Sergio0694 marked this conversation as resolved.
Show resolved Hide resolved

return retNode;
}
}

return nullptr;
}

/*****************************************************************************
* 'logMsg' is true if a log message needs to be logged. false if the caller has
* already logged it (presumably in a more detailed fashion than done here)
Expand Down
15 changes: 15 additions & 0 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3321,6 +3321,9 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
case NI_System_Type_op_Equality:
case NI_System_Type_op_Inequality:

// This allows folding "typeof(...).GetGenericTypeDefinition() == typeof(...)"
case NI_System_Type_GetGenericTypeDefinition:

// These may lead to early dead code elimination
case NI_System_Type_get_IsValueType:
case NI_System_Type_get_IsPrimitive:
Expand Down Expand Up @@ -3856,6 +3859,14 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
break;
}

case NI_System_Type_GetGenericTypeDefinition:
{
GenTree* type = impStackTop(0).val;

retNode = impGetGenericTypeDefinition(type);
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
break;
}

case NI_System_Type_op_Equality:
case NI_System_Type_op_Inequality:
{
Expand Down Expand Up @@ -10220,6 +10231,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
{
result = NI_System_Type_GetTypeFromHandle;
}
else if (strcmp(methodName, "GetGenericTypeDefinition") == 0)
{
result = NI_System_Type_GetGenericTypeDefinition;
}
else if (strcmp(methodName, "IsAssignableFrom") == 0)
{
result = NI_System_Type_IsAssignableFrom;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/namedintrinsiclist.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum NamedIntrinsic : unsigned short
NI_System_Type_op_Equality,
NI_System_Type_op_Inequality,
NI_System_Type_GetTypeFromHandle,
NI_System_Type_GetGenericTypeDefinition,
NI_System_Array_Clone,
NI_System_Array_GetLength,
NI_System_Array_GetLowerBound,
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,11 @@ private bool haveSameMethodDefinition(CORINFO_METHOD_STRUCT_* methHnd1, CORINFO_
return meth1.GetTypicalMethodDefinition() == meth2.GetTypicalMethodDefinition();
}

private CORINFO_CLASS_STRUCT_* getTypeDefinition(CORINFO_CLASS_STRUCT_* type)
{
return ObjectToHandle(HandleToObject(type).GetTypeDefinition());
Sergio0694 marked this conversation as resolved.
Show resolved Hide resolved
}

private CorInfoInline canInline(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd)
{
MethodDesc callerMethod = HandleToObject(callerHnd);
Expand Down
Loading
Loading