Skip to content
Open
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
8 changes: 8 additions & 0 deletions src/coreclr/inc/cor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,14 @@ FORCEINLINE int CorIsPrimitiveType(CorElementType elementtype)
return (elementtype < ELEMENT_TYPE_PTR || elementtype == ELEMENT_TYPE_I || elementtype == ELEMENT_TYPE_U);
}

// Returns true if the element type is a real or integer type.
FORCEINLINE bool CorIsNumericalType(CorElementType elementType)
{
return ((elementType >= ELEMENT_TYPE_I1) && (elementType <= ELEMENT_TYPE_R8))
|| (elementType == ELEMENT_TYPE_I)
|| (elementType == ELEMENT_TYPE_U);
}


// Return true if element type is a modifier, i.e. ELEMENT_TYPE_MODIFIER bits are
// turned on. For now, it is checking for ELEMENT_TYPE_PTR and ELEMENT_TYPE_BYREF
Expand Down
66 changes: 36 additions & 30 deletions src/coreclr/vm/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,45 +1685,64 @@ bool MethodTable::IsHFA()
#endif // !FEATURE_HFA

//*******************************************************************************
int MethodTable::GetVectorSize()
CorInfoHFAElemType MethodTable::GetVectorHFA()
{
// This is supported for finding HVA types for Arm64. In order to support the altjit,
// we support this on 64-bit platforms (i.e. Arm64 and X64).
CorInfoHFAElemType hfaType = CORINFO_HFA_ELEM_NONE;
#ifdef TARGET_64BIT
if (IsIntrinsicType())
{
LPCUTF8 namespaceName;
LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName);
int vectorSize = 0;

if (strcmp(className, "Vector`1") == 0)
{
_ASSERTE(strcmp(namespaceName, "System.Numerics") == 0);
vectorSize = GetNumInstanceFieldBytes();
#ifdef TARGET_ARM64
if (ExecutionManager::GetEEJitManager()->UseScalableVectorT())
{
// TODO-SVE: This forces Vector<T> to be passed by reference. Implement
// CORINFO_HFA_ELEM_VECTORT so we can pass Vector<T> in SVE registers.
return CORINFO_HFA_ELEM_NONE;
}
#endif
switch (GetNumInstanceFieldBytes())
{
case 8:
hfaType = CORINFO_HFA_ELEM_VECTOR64;
break;
case 16:
hfaType = CORINFO_HFA_ELEM_VECTOR128;
break;
default:
_ASSERTE(!"Invalid Vector<T> size");
break;
}
}
else if (strcmp(className, "Vector128`1") == 0)
{
_ASSERTE(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
vectorSize = 16;
hfaType = CORINFO_HFA_ELEM_VECTOR128;
}
else if (strcmp(className, "Vector64`1") == 0)
{
_ASSERTE(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
vectorSize = 8;
hfaType = CORINFO_HFA_ELEM_VECTOR64;
}
if (vectorSize != 0)

if (hfaType != CORINFO_HFA_ELEM_NONE)
{
// We need to verify that T (the element or "base" type) is a primitive type.
// We need to verify that T (the element or "base" type) is a numerical type.
TypeHandle typeArg = GetInstantiation()[0];
CorElementType corType = typeArg.GetSignatureCorElementType();
if (((corType >= ELEMENT_TYPE_I1) && (corType <= ELEMENT_TYPE_R8)) || (corType == ELEMENT_TYPE_I) || (corType == ELEMENT_TYPE_U))
if (!CorIsNumericalType(typeArg.GetSignatureCorElementType()))
{
return vectorSize;
return CORINFO_HFA_ELEM_NONE;
}
}
}
#endif // TARGET_64BIT
return 0;
return hfaType;
}

//*******************************************************************************
Expand All @@ -1745,10 +1764,11 @@ CorInfoHFAElemType MethodTable::GetHFAType()
_ASSERTE(pMT->IsValueType());
_ASSERTE(pMT->GetNumInstanceFields() > 0);

int vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
CorInfoHFAElemType hfaType = pMT->GetVectorHFA();

if (hfaType != CORINFO_HFA_ELEM_NONE)
{
return (vectorSize == 8) ? CORINFO_HFA_ELEM_VECTOR64 : CORINFO_HFA_ELEM_VECTOR128;
return hfaType;
}

PTR_FieldDesc pFirstField = pMT->GetApproxFieldDescListRaw();
Expand Down Expand Up @@ -1817,7 +1837,7 @@ EEClass::CheckForHFA()

// The opaque Vector types appear to have multiple fields, but need to be treated
// as an opaque type of a single vector.
if (GetMethodTable()->GetVectorSize() != 0)
if (GetMethodTable()->GetVectorHFA() != CORINFO_HFA_ELEM_NONE)
{
#if defined(FEATURE_HFA)
GetMethodTable()->SetIsHFA();
Expand All @@ -1843,27 +1863,13 @@ EEClass::CheckForHFA()
{
case ELEMENT_TYPE_VALUETYPE:
{
#ifdef TARGET_ARM64
MethodTable* pMT;
#if defined(FEATURE_HFA)
pMT = pByValueClassCache[i];
#else
pMT = pFD->LookupApproxFieldTypeHandle().AsMethodTable();
#endif
int thisElemSize = pMT->GetVectorSize();
if (thisElemSize != 0)
{
fieldHFAType = (thisElemSize == 8) ? CORINFO_HFA_ELEM_VECTOR64 : CORINFO_HFA_ELEM_VECTOR128;
}
else
#endif // TARGET_ARM64
{
#if defined(FEATURE_HFA)
fieldHFAType = pByValueClassCache[i]->GetHFAType();
#else
fieldHFAType = pFD->LookupApproxFieldTypeHandle().AsMethodTable()->GetHFAType();
#endif
}
fieldHFAType = pMT->GetHFAType();

int requiredAlignment;
switch (fieldHFAType)
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -2221,6 +2221,14 @@ class EEJitManager final : public EECodeGenManager
return m_CPUCompileFlags;
}

#if defined(TARGET_ARM64)
inline bool UseScalableVectorT()
{
LIMITED_METHOD_CONTRACT;
return m_CPUCompileFlags.GetInstructionSetFlags().HasInstructionSet(InstructionSet_VectorT);
}
#endif

private :
Crst m_JitLoadLock;

Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2045,8 +2045,10 @@ class MethodTable
bool IsHFA();
#endif // FEATURE_HFA

// Returns the size in bytes of this type if it is a HW vector type; 0 otherwise.
int GetVectorSize();
// Returns the HFA type for this type, if it is a valid HW vector type.
// Floating point HFA types will return CORINFO_HFA_ELEM_NONE.
// Vector classes with invalid generic parameters return CORINFO_HFA_ELEM_NONE.
CorInfoHFAElemType GetVectorHFA();

// Get the HFA type. This is supported both with FEATURE_HFA, in which case it
// depends on the cached bit on the class, or without, in which case it is recomputed
Expand Down
Loading