-
Notifications
You must be signed in to change notification settings - Fork 4.9k
JIT: Handle primitive remainder stores to regularly promoted fields in physical promotion #87217
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
Conversation
…n physical promotion If the remainder of a block copy is handled as a primitive, then it is possible that the destination or source is a regularly promoted field. In this case we do not have to DNER it. Example. Before: ``` Processing block operation [000009] that involves replacements V08 (field V02.hasValue (fldOffset=0x0)) <- V16 (V00.[000..001)) (last use) Remainder: [004..008) => Remainder strategy: int at +004 Local V00 should not be enregistered because: was accessed as a local field Local V02 should not be enregistered because: was accessed as a local field New statement: STMT00003 ( 0x00D[E-] ... 0x00E ) [000090] -A--------- ▌ COMMA void [000087] DA--------- ├──▌ STORE_LCL_VAR bool V08 tmp4 [000086] ----------- │ └──▌ LCL_VAR bool V16 tmp12 (last use) [000089] UA--------- └──▌ STORE_LCL_FLD int (P) V02 loc1 [+4] ▌ bool V02.<unknown class>:hasValue (offs=0x00) -> V08 tmp4 ▌ int V02.<unknown class>:value (offs=0x04) -> V09 tmp5 [000088] ----------- └──▌ LCL_FLD int V00 arg0 [+4] ``` After: ``` Processing block operation [000009] that involves replacements V08 (field V02.hasValue (fldOffset=0x0)) <- V16 (V00.[000..001)) (last use) Remainder: [004..008) => Remainder strategy: int at +004 Local V00 should not be enregistered because: was accessed as a local field New statement: STMT00003 ( 0x00D[E-] ... 0x00E ) [000090] -A--------- ▌ COMMA void [000087] DA--------- ├──▌ STORE_LCL_VAR bool V08 tmp4 [000086] ----------- │ └──▌ LCL_VAR bool V16 tmp12 (last use) [000089] DA--------- └──▌ STORE_LCL_VAR int V09 tmp5 [000088] ----------- └──▌ LCL_FLD int V00 arg0 [+4] ```
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsIf the remainder of a block copy is handled as a primitive, then it is possible that the destination or source is a regularly promoted field. In this case we do not have to DNER it. For example Example. Before: STMT00003 ( 0x00D[E-] ... 0x00E )
[000009] DA--------- ▌ STORE_LCL_VAR struct<System.Nullable`1, 8>(P) V02 loc1
▌ bool V02.<unknown class>:hasValue (offs=0x00) -> V08 tmp4
▌ int V02.<unknown class>:value (offs=0x04) -> V09 tmp5
[000008] ----------- └──▌ LCL_VAR struct<System.Nullable`1, 8> V00 arg0 (last use)
Processing block operation [000009] that involves replacements
V08 (field V02.hasValue (fldOffset=0x0)) <- V16 (V00.[000..001)) (last use)
Remainder: [004..008)
=> Remainder strategy: int at +004
Local V00 should not be enregistered because: was accessed as a local field
Local V02 should not be enregistered because: was accessed as a local field
New statement:
STMT00003 ( 0x00D[E-] ... 0x00E )
[000090] -A--------- ▌ COMMA void
[000087] DA--------- ├──▌ STORE_LCL_VAR bool V08 tmp4
[000086] ----------- │ └──▌ LCL_VAR bool V16 tmp12 (last use)
[000089] UA--------- └──▌ STORE_LCL_FLD int (P) V02 loc1 [+4]
▌ bool V02.<unknown class>:hasValue (offs=0x00) -> V08 tmp4
▌ int V02.<unknown class>:value (offs=0x04) -> V09 tmp5
[000088] ----------- └──▌ LCL_FLD int V00 arg0 [+4] After: STMT00003 ( 0x00D[E-] ... 0x00E )
[000009] DA--------- ▌ STORE_LCL_VAR struct<System.Nullable`1, 8>(P) V02 loc1
▌ bool V02.<unknown class>:hasValue (offs=0x00) -> V08 tmp4
▌ int V02.<unknown class>:value (offs=0x04) -> V09 tmp5
[000008] ----------- └──▌ LCL_VAR struct<System.Nullable`1, 8> V00 arg0 (last use)
Processing block operation [000009] that involves replacements
V08 (field V02.hasValue (fldOffset=0x0)) <- V16 (V00.[000..001)) (last use)
Remainder: [004..008)
=> Remainder strategy: int at +004
Local V00 should not be enregistered because: was accessed as a local field
New statement:
STMT00003 ( 0x00D[E-] ... 0x00E )
[000090] -A--------- ▌ COMMA void
[000087] DA--------- ├──▌ STORE_LCL_VAR bool V08 tmp4
[000086] ----------- │ └──▌ LCL_VAR bool V16 tmp12 (last use)
[000089] DA--------- └──▌ STORE_LCL_VAR int V09 tmp5
[000088] ----------- └──▌ LCL_FLD int V00 arg0 [+4]
|
cc @dotnet/jit-contrib PTAL @EgorBo. Diffs with physical promotion. Quite large x86/arm32 diffs compared to 64-bit, not quite sure why, will try to take a closer look, and also look at some of the regressions. Diffs without old promotion. None as expected since there are no regular promoted fields in this case. |
/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress, runtime-jit-experimental |
Azure Pipelines successfully started running 3 pipeline(s). |
We only promote struct parameters if they are passed in registers or as implicit byrefs, which particularly means a parameter
There are very few, but the one I looked at was just due to different register allocation because of a new independent promotion taking up a register and another local then being spilled instead. |
If the remainder of a block copy is handled as a primitive, then it is possible that the destination or source is a regularly promoted field. In this case we do not have to DNER it.
Example. Before:
After: