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

Fold primitive-typed access to promoted structs in local morph and forbid mismatched struct assignments #76766

Merged

Conversation

SingleAccretion
Copy link
Contributor

@SingleAccretion SingleAccretion commented Oct 7, 2022

Two changes:

  1. Do not create invalid IR in the form of ASG(struct, primitive) in fgMorphStructField. This leads to some improvements (as well as regressions) due to us now being able to forward-substitute more things. It also decouples the replacement logic from lvFieldHnd, making it unnecessary. This shrinks the size of LclVarDsc from 104 to 96 bytes on x64, resulting in ~0.35% memory consumption reduction (for optimized code), and a TP loss because more instructions are used by MSVC to perform pointer arithmetic on LclVarDsc*s.
  2. Allow folding access to promoted locals in local morph. This results in a few regressions that were fixed by teaching fgMorphStructField to work with IND-based access. The alternative of moving the whole logic to post-order was explored, but ultimately discarded due to it being more complex.

As of this change, it will be the case that the two sides of a struct assignment will always agree on types, for which a special assert has been added. This will render most of fgMorphBlockOperand unnecessary, but deleting will have to wait till #76745 is in.

We are expecting overall good diffs, most of the regressions are associated with more substitutions. There are also two cases in test code where the new logic is more conservative for RETURNs, but it does not seem worth the code to fix them (by propagating the quirked RETURN handling into local morph).

@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 Oct 7, 2022
@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Oct 7, 2022
@ghost
Copy link

ghost commented Oct 7, 2022

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

Issue Details

Two changes:

  1. Do not create invalid IR in the form of ASG(struct, primitive) in fgMorphStructField. This leads to some improvements (as well as regressions) due to us now being able to forward-substitute more things. It also decouples the replacement logic from lvFieldHnd, making it unnecessary. This shrinks the size of LclVarDsc from 104 to 96 bytes on x64, resulting in ~0.35% memory consumption reduction (for optimized code), and a TP loss because more instructions are used by MSVC to perform pointer arithmetic on LclVarDsc*s.
  2. Allow folding access to promoted locals in local morph. This results in a few regressions that were fixed by teaching fgMorphStructField to work with IND-based access. The alternative of moving the whole logic to post-order was explore, but ultimately discarded due to it being more complex.

As of this change, it will be the case that the two sides of a struct assignment will always agree on types, for which a special asset has been added. This will render most of fgMorphBlockOperand unnecessary, but deleting will have to wait till #76745 is in.

We are expecting overall good diffs, most of the regressions are associated with more substitutions. There are also two cases in test code where the new logic is more conservative for RETURNs, but it does not seem worth the code to fix them (by propagating the quirked RETURN handling into local morph).

Author: SingleAccretion
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@SingleAccretion SingleAccretion changed the title Fold primitive-typed access to promoted structs in local morph, forbid mismatched struct assignments Fold primitive-typed access to promoted structs in local morph and forbid mismatched struct assignments Oct 7, 2022
@SingleAccretion SingleAccretion force-pushed the LclMorph-Promotion-Simple-Upstream branch from 5ff9b77 to 24f8a34 Compare October 7, 2022 22:04
And simplify the code...
Without handle equality, the assert no longer holds, for example:
```cs
private StructWithInt Problem(StructWithInt b, StructWithInt a)
{
    a = ((StructWithStructWithInt*)&b)->StructWithInt;
    return a;
}
```
Dead / unncessary.

No diffs.
This is significantly simpler than moving the promotion logic
to post-order because we don't need to fiddle with the ref
counting process and complexities of intermediate states, e. g.
"IND<float>(ADDR(FIELD<int>(ADDR(LCL_VAR<struct>))))" can be
naturally turned into "BITCAST<float>(LCL_VAR<int>)" like this.
With this, we have only a very small regression:

Base: 1297463478, Diff: 1297750893, +0.0222%
LocalAddressVisitor::MorphStructField : 345099  : NA       : 31.52% : +0.0266%
LocalAddressVisitor::PreOrderVisit    : 224684  : +3.53%   : 20.52% : +0.0173%
memset                                : 88591   : +0.99%   : 8.09%  : +0.0068%
Compiler::fgMorphSmpOp                : -19170  : -0.06%   : 1.75%  : -0.0015%
Compiler::fgMorphStructField          : -367474 : -100.00% : 33.56% : -0.0283%

(This is with a dummy field on LclVarDsc)

Losing the assert does not seem worrysome as we have an identical one in "fgMorphField".
@SingleAccretion SingleAccretion force-pushed the LclMorph-Promotion-Simple-Upstream branch from 24f8a34 to 1e86541 Compare October 7, 2022 22:35
@build-analysis build-analysis bot mentioned this pull request Oct 8, 2022
2 tasks
@SingleAccretion SingleAccretion marked this pull request as ready for review October 10, 2022 19:58
@SingleAccretion
Copy link
Contributor Author

@dotnet/jit-contrib

@AndyAyersMS
Copy link
Member

@jakobbotsch can you take a look at this one?

@jakobbotsch jakobbotsch self-requested a review October 20, 2022 07:20
Copy link
Member

@jakobbotsch jakobbotsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Will rerun the CI.

@jakobbotsch jakobbotsch reopened this Oct 24, 2022
@jakobbotsch
Copy link
Member

Nice cleanup, thanks again!

@jakobbotsch jakobbotsch merged commit 76cf397 into dotnet:main Oct 24, 2022
@SingleAccretion SingleAccretion deleted the LclMorph-Promotion-Simple-Upstream branch October 25, 2022 16:26
@ghost ghost locked as resolved and limited conversation to collaborators Nov 24, 2022
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 community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants