if (pFieldInfo->fldSize == 0)
{
- // Size of TYP_BLK, TYP_FUNC, TYP_VOID and TYP_STRUCT is zero.
- // Early out if field type is other than TYP_STRUCT.
- // This is a defensive check as we don't expect a struct to have
- // fields of TYP_BLK, TYP_FUNC or TYP_VOID.
- if (pFieldInfo->fldType != TYP_STRUCT)
- {
- return;
- }
-
// Non-primitive struct field.
- // Try to promote structs of single field of scalar types aligned at their
- // natural boundary.
-
- // Do Not promote if the struct field in turn has more than one field.
- if (info.compCompHnd->getClassNumInstanceFields(pFieldInfo->fldTypeHnd) != 1)
- {
- return;
- }
-
- // Do not promote if the single field is not aligned at its natural boundary within
- // the struct field.
- CORINFO_FIELD_HANDLE fHnd = info.compCompHnd->getFieldInClass(pFieldInfo->fldTypeHnd, 0);
- unsigned fOffset = info.compCompHnd->getFieldOffset(fHnd);
- if (fOffset != 0)
- {
- return;
- }
-
- CORINFO_CLASS_HANDLE cHnd;
- CorInfoType fieldCorType = info.compCompHnd->getFieldType(fHnd, &cHnd);
- var_types fieldVarType = JITtype2varType(fieldCorType);
- unsigned fieldSize = genTypeSize(fieldVarType);
-
- // Do not promote if either not a primitive type or size equal to ptr size on
- // target or a struct containing a single floating-point field.
- //
- // TODO-PERF: Structs containing a single floating-point field on Amd64
- // needs to be passed in integer registers. Right now LSRA doesn't support
- // passing of floating-point LCL_VARS in integer registers. Enabling promotion
- // of such structs results in an assert in lsra right now.
- //
- // TODO-PERF: Right now promotion is confined to struct containing a ptr sized
- // field (int/uint/ref/byref on 32-bits and long/ulong/ref/byref on 64-bits).
- // Though this would serve the purpose of promoting Span<T> containing ByReference<T>,
- // this can be extended to other primitive types as long as they are aligned at their
- // natural boundary.
- if (fieldSize == 0 || fieldSize != TARGET_POINTER_SIZE || varTypeIsFloating(fieldVarType))
- {
- return;
- }
-
- // Retype the field as the type of the single field of the struct
- pFieldInfo->fldType = fieldVarType;
- pFieldInfo->fldSize = fieldSize;
+ return;
}
if ((pFieldInfo->fldOffset % pFieldInfo->fldSize) != 0)
assert(!varTypeIsSIMD(arg));
numRefs = comp->info.compCompHnd->getClassGClayout(arg->gtObj.gtClass, gcLayout);
putArg->AsPutArgStk()->setGcPointers(numRefs, gcLayout);
-
-#ifdef _TARGET_X86_
- // On x86 VM lies about the type of a struct containing a pointer sized
- // integer field by returning the type of its field as the type of struct.
- // Such struct can be passed in a register depending its position in
- // parameter list. VM does this unwrapping only one level and therefore
- // a type like Struct Foo { Struct Bar { int f}} awlays needs to be
- // passed on stack. Also, VM doesn't lie about type of such a struct
- // when it is a field of another struct. That is VM doesn't lie about
- // the type of Foo.Bar
- //
- // Promotion of structs containing structs of single field can promote
- // such a struct. Say Foo.Bar field is getting passed as a parameter
- // to a call, Since it is a TYP_STRUCT, as per x86 ABI it should always
- // be passed on stack. Therefore GenTree node under a PUTARG_STK could
- // be GT_OBJ(GT_LCL_VAR_ADDR(v1)), where local v1 could be a promoted
- // field standing for Foo.Bar. Note that the type of v1 will be the
- // type of field of Foo.Bar.f when Foo is promoted. That is v1
- // will be a scalar type. In this case we need to pass v1 on stack
- // instead of in a register.
- //
- // TODO-PERF: replace GT_OBJ(GT_LCL_VAR_ADDR(v1)) with v1 if v1 is
- // a scalar type and the width of GT_OBJ matches the type size of v1.
- // Note that this cannot be done till call node arguments are morphed
- // because we should not lose the fact that the type of argument is
- // a struct so that the arg gets correctly marked to be passed on stack.
- GenTree* objOp1 = arg->gtGetOp1();
- if (objOp1->OperGet() == GT_LCL_VAR_ADDR)
- {
- unsigned lclNum = objOp1->AsLclVarCommon()->GetLclNum();
- if (comp->lvaTable[lclNum].lvType != TYP_STRUCT)
- {
- comp->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_VMNeedsStackAddr));
- }
- }
-#endif // _TARGET_X86_
}
}
#endif // FEATURE_PUT_STRUCT_ARG_STK