-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Rework JIT<->EE communication for struct promotion; add support for general recursive struct promotion #85569
Conversation
Rework the communication so that the JIT asks the EE for struct field related information relevant to promotion in a single JIT-EE call of a new function called 'flattenType'. As a side effect, removes CORINFO_FLG_CUSTOMLAYOUT and CORINFO_FLG_INDEXABLE_FIELDS (the latter by adding support to inline arrays in this new function). Also, last but not least, this adds support for general recursive struct promotion provided the field limit of 4 is not hit (for now, let's see if there are any more fundamental issues with this). Fix dotnet#85511 Fix dotnet#71711
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsRework the communication so that the JIT asks the EE for struct field related information relevant to promotion in a single JIT-EE call of a new function called As a side effect, removes Fix #85511
|
if (varDsc->lvIsStructField) | ||
{ | ||
LclVarDsc* parentvarDsc = lvaGetDesc(varDsc->lvParentLcl); | ||
#if !defined(TARGET_64BIT) | ||
if (varTypeIsLong(parentvarDsc)) | ||
{ | ||
bool isLo = (lclNum == parentvarDsc->lvFieldLclStart); | ||
printf(" V%02u.%s(offs=0x%02x)", varDsc->lvParentLcl, isLo ? "lo" : "hi", isLo ? 0 : genTypeSize(TYP_INT)); | ||
} | ||
else | ||
#endif // !defined(TARGET_64BIT) | ||
{ | ||
CORINFO_CLASS_HANDLE typeHnd = parentvarDsc->GetLayout()->GetClassHandle(); | ||
CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(typeHnd, varDsc->lvFldOrdinal); | ||
|
||
char buffer[128]; | ||
printf(" V%02u.%s(offs=0x%02x)", varDsc->lvParentLcl, eeGetFieldName(fldHnd, false, buffer, sizeof(buffer)), | ||
varDsc->lvFldOffset); | ||
|
||
lvaPromotionType promotionType = lvaGetPromotionType(parentvarDsc); | ||
switch (promotionType) | ||
{ | ||
case PROMOTION_TYPE_NONE: | ||
printf(" P-NONE"); | ||
break; | ||
case PROMOTION_TYPE_DEPENDENT: | ||
printf(" P-DEP"); | ||
break; | ||
case PROMOTION_TYPE_INDEPENDENT: | ||
printf(" P-INDEP"); | ||
break; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LclVarDsc::lvReason
printed below already contains this information, so we were printing it twice (and this code wouldn't work anymore, since lvFldOrdinal
cannot be used to map fields of the parent local in the general case).
The promotion of inline arrays does not really work well because local morph does not recognize the accesses to other elements based on the first element: LocalAddressVisitor visiting statement:
STMT00008 ( INL01 @ 0x010[E-] ... ??? ) <- INLRT @ 0x000[E-]
[000034] -ACXG------ ▌ ASG ref
[000033] --CXG--N--- ├──▌ IND ref
[000054] ----------- │ └──▌ ADD byref
[000050] ----------- │ ├──▌ FIELD_ADDR byref System.ThreeObjects:Arg0
[000049] ----------- │ │ └──▌ LCL_ADDR byref V06 loc0 [+0]
│ │ └──▌ ref field V06.Arg0 (fldOffset=0x0) -> V10 tmp3
│ │ └──▌ ref field V06.Arg0 (fldOffset=0x8) -> V11 tmp4
│ │ └──▌ ref field V06.Arg0 (fldOffset=0x10) -> V12 tmp5
[000053] ----------- │ └──▌ CNS_INT long 8
[000002] ----------- └──▌ LCL_VAR ref V04 arg4
Replacing the field in promoted struct with local var V10
Local V10 should not be enregistered because: it is address exposed
Local V11 should not be enregistered because: it is address exposed
Local V12 should not be enregistered because: it is address exposed
Local V06 should not be enregistered because: it is address exposed
LocalAddressVisitor modified statement:
STMT00008 ( INL01 @ 0x010[E-] ... ??? ) <- INLRT @ 0x000[E-]
[000034] -ACXG------ ▌ ASG ref
[000033] --CXG--N--- ├──▌ IND ref
[000054] ----------- │ └──▌ ADD byref
[000093] ----------- │ ├──▌ LCL_ADDR long V10 tmp3 [+0]
[000094] ----------- │ └──▌ CNS_INT long 8
[000002] ----------- └──▌ LCL_VAR ref V04 arg4 That leads to significantly worse codegen than without promotion (this example is from |
significantPadding = true; | ||
if (!type.ContainsGCPointers && !type.IsByRefLike) | ||
{ | ||
significantPadding = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this pessimize cases that don't have padding?
Say for example you've defined a union { float f; int32_t i; }
and therefore it is explicit, but the two structures are "perfectly overlapping".
-- JW as a potential "future" improvement, not something to be handled in this PR or anything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, since we don't support promotion of structs with overlapping fields. But if we did still no as the JIT only pays attention to significantPadding
when there are holes in the struct.
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
Rework the communication so that the JIT asks the EE for struct field related information relevant to promotion in a single JIT-EE call of a new function called
flattenType
. Crossgen2 can then more easily provide the information that the JIT is allowed to depend on.As a side effect, removes
CORINFO_FLG_CUSTOMLAYOUT
(which fixes #71711) andCORINFO_FLG_INDEXABLE_FIELDS
(the latter by adding support to inline arrays in this new function). Last but not least, this adds support for general recursive struct promotion provided the field limit of 4 is not hit (for now, let's see if there are any more fundamental issues with this).Fix #85511
Fix #71711
Fix #7576