Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Don't struct-promote opaque vectors
Browse files Browse the repository at this point in the history
The hardware vector types: `Vector64<T>`, `Vector128<T>` and `Vector256<T>` are declared
as having one or more fields of `ulong`. However, the JIT shouldn't be promoting these
fields to local variables. It is almost never the right type, and the intrinsics in any
case are not designed to cooperate with promoted fields (i.e. an index of a `Vector<ulong>`
won't map to the promoted lclVar).

Most importantly, it causes all copies of the vector to be done as 64-bit integer loads
and stores.

Finally, it will be important, as we support vector ABIs, to distinguish the handling of
the fixed-size vectors (`Vector2`, `Vector3` and `Vector4`) which *are* considered to be
normal structs of N floats, from the opaque types which will be passed in vector registers.
  • Loading branch information
CarolEidt committed Nov 30, 2018
1 parent 71f259c commit 714c47e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7640,6 +7640,17 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
return NO_CLASS_HANDLE;
}

// Returns true if this is a SIMD type that should be considered an opaque
// vector type (i.e. do not analyze or promote its fields).
// Note that all but the fixed vector types are opaque, even though they may
// actually be declared as having fields.
bool isOpaqueSIMDType(CORINFO_CLASS_HANDLE structHandle)
{
return ((m_simdHandleCache != nullptr) && (structHandle != m_simdHandleCache->SIMDVector2Handle) &&
(structHandle != m_simdHandleCache->SIMDVector3Handle) &&
(structHandle != m_simdHandleCache->SIMDVector4Handle));
}

// Returns true if the tree corresponds to a TYP_SIMD lcl var.
// Note that both SIMD vector args and locals are mared as lvSIMDType = true, but
// type of an arg node is TYP_BYREF and a local node is TYP_SIMD or TYP_STRUCT.
Expand All @@ -7648,6 +7659,16 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
return tree->OperIsLocal() && lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
}

// Returns true if the lclVar is an opaque SIMD type.
bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
{
if (!varDsc->lvSIMDType)
{
return false;
}
return isOpaqueSIMDType(varDsc->lvVerTypeInfo.GetClassHandle());
}

// Returns true if the type of the tree is a byref of TYP_SIMD
bool isAddrOfSIMDType(GenTree* tree)
{
Expand Down
2 changes: 1 addition & 1 deletion src/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16973,7 +16973,7 @@ void Compiler::fgPromoteStructs()

// If we have marked this as lvUsedInSIMDIntrinsic, then we do not want to promote
// its fields. Instead, we will attempt to enregister the entire struct.
if (varDsc->lvIsSIMDType() && varDsc->lvIsUsedInSIMDIntrinsic())
if (varDsc->lvIsSIMDType() && (varDsc->lvIsUsedInSIMDIntrinsic() || isOpaqueSIMDLclVar(varDsc)))
{
varDsc->lvRegStruct = true;
}
Expand Down

0 comments on commit 714c47e

Please sign in to comment.