-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Fold primitive-typed access to promoted structs in local morph and forbid mismatched struct assignments #76766
Conversation
Instead, create constructions like "OBJ(ADDR(LCL_VAR))" that block morphing can recognize on its own.
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsTwo changes:
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 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
|
5ff9b77
to
24f8a34
Compare
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".
24f8a34
to
1e86541
Compare
@dotnet/jit-contrib |
@jakobbotsch can you take a look at this one? |
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.
LGTM. Will rerun the CI.
Nice cleanup, thanks again! |
Two changes:
ASG(struct, primitive)
infgMorphStructField
. 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 fromlvFieldHnd
, making it unnecessary. This shrinks the size ofLclVarDsc
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 onLclVarDsc*
s.fgMorphStructField
to work withIND
-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
RETURN
s, but it does not seem worth the code to fix them (by propagating the quirkedRETURN
handling into local morph).