Skip to content
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

Closed
wants to merge 17 commits into from

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Apr 30, 2023

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) and CORINFO_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

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
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 30, 2023
@ghost ghost assigned jakobbotsch Apr 30, 2023
@ghost
Copy link

ghost commented Apr 30, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

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) and CORINFO_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

Author: jakobbotsch
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

Comment on lines -7698 to -7731
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;
}
}
}
Copy link
Member Author

@jakobbotsch jakobbotsch Apr 30, 2023

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).

@jakobbotsch
Copy link
Member Author

jakobbotsch commented May 1, 2023

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 System.Text.StringBuilder:AppendFormat(System.IFormatProvider,System.String,System.Object,System.Object,System.Object)).. Likely need to teach local morph to be smarter.

significantPadding = true;
if (!type.ContainsGCPointers && !type.IsByRefLike)
{
significantPadding = true;
Copy link
Member

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

Copy link
Member Author

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.

@jakobbotsch jakobbotsch closed this May 4, 2023
@jakobbotsch jakobbotsch reopened this May 4, 2023
@ghost ghost closed this Jun 3, 2023
@ghost
Copy link

ghost commented Jun 3, 2023

Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it.

@ghost ghost locked as resolved and limited conversation to collaborators Jul 4, 2023
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
2 participants