Skip to content

Commit

Permalink
Make Type.GetGenericTypeDefinition() an intrinsic
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Jan 18, 2024
1 parent 47173ad commit 859adb8
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4430,6 +4430,7 @@ class Compiler
void impImportLeave(BasicBlock* block);
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 @@ -1369,6 +1369,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_System_Type_get_IsPrimitive:
case NI_System_Type_get_IsByRefLike:
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
21 changes: 21 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2486,6 +2486,27 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom)
return nullptr;
}


GenTree* Compiler::impGetGenericTypeDefinition(GenTree* type)
{
// 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))
{
CORINFO_CLASS_HANDLE hClassResult = info.compCompHnd->getTypeDefinition(hClassType);

GenTree* retNode = gtNewIconEmbClsHndNode(hClassResult);

// Drop the typeof(T) node
impPopStack();

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 @@ -2719,6 +2719,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
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 @@ -3221,6 +3224,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
break;
}

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

retNode = impGetGenericTypeDefinition(type);
break;
}

case NI_System_Type_op_Equality:
case NI_System_Type_op_Inequality:
{
Expand Down Expand Up @@ -9018,6 +9029,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 @@ -84,6 +84,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
1 change: 1 addition & 0 deletions src/libraries/System.Private.CoreLib/src/System/Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public bool IsInterface

public virtual int GetArrayRank() => throw new NotSupportedException(SR.NotSupported_SubclassOverride);

[Intrinsic]
public virtual Type GetGenericTypeDefinition() => throw new NotSupportedException(SR.NotSupported_SubclassOverride);
public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : EmptyTypes;
public virtual Type[] GetGenericArguments() => throw new NotSupportedException(SR.NotSupported_SubclassOverride);
Expand Down

0 comments on commit 859adb8

Please sign in to comment.