Uh oh!
There was an error while loading. Please reload this page.
JIT: fold trees after inline return expression updates - #1751
Conversation
Aggressively fold as we substitute inline return value trees in for the return value placeholders. Notice when this folding leads to branch simplification, and make the associated flow graph update. The recently added early flow opt pass will then transitively remove any newly unreachable code. Resolves dotnet/coreclr#27395.
AndyAyersMS
commented
Jan 15, 2020
This is the change I had in mind when I started working on #1309; I didn't realize at the time that #1309 would end up being quite a bit more impactful. One would hope that early folding like this would always lead to better code later on, but that's not the case. I will spend some time looking at the more prominent regressions. Sample good diff: ;;; MemoryExtensions:IndexOfAny(Span`1,long,long,long):int;;; beforeG_M64714_IG01:subrsp,40mov qword ptr [rsp+38H],rdxmov qword ptr [rsp+40H],r8mov qword ptr [rsp+48H],r9 ;; bbWeight=1 PerfScore 3.25G_M64714_IG02:movrdx, bword ptr [rcx]movecx, dword ptr [rcx+8] ;; bbWeight=1 PerfScore 4.00G_M64714_IG03:movr8, qword ptr [rsp+38H]movr9, qword ptr [rsp+40H]movrax, qword ptr [rsp+48H]mov dword ptr [rsp+20H],ecxmovrcx,rdxmovrdx,r8movr8,r9movr9,raxcall SpanHelpers:IndexOfAny(byref,long,long,long,int):intnop ;; bbWeight=1 PerfScore 6.25G_M64714_IG04:addrsp,40ret;;; afterG_M64714_IG01:subrsp,40 ;; bbWeight=1 PerfScore 0.25G_M64714_IG02:movrax, bword ptr [rcx]movecx, dword ptr [rcx+8]mov dword ptr [rsp+20H],ecxmovrcx,raxcall SpanHelpers:IndexOfAny(byref,long,long,long,int):intnop ;; bbWeight=1 PerfScore 6.50G_M64714_IG03:addrsp,40retcc @dotnet/jit-contrib |
Suchiman
commented
Jan 15, 2020
Is dotnet/coreclr#27395 really the correct issue this solves? |
AndyAyersMS
commented
Jan 15, 2020
Thanks for spotting this -- should have been dotnet/coreclr#27935 |
AndyAyersMS
commented
Jan 15, 2020
Diff on the test case from dotnet/coreclr#27935: -; Lcl frame size = 56+; Lcl frame size = 40
G_M21895_IG01:
- sub rsp, 56- vzeroupper- xor rax, rax- mov qword ptr [rsp+28H], rax- ;; bbWeight=1 PerfScore 2.50+ sub rsp, 40+ ;; bbWeight=1 PerfScore 0.25
G_M21895_IG02:
- vmovdqu xmm0, xmmword ptr [rdx]- vmovdqu xmmword ptr [rsp+28H], xmm0- ;; bbWeight=1 PerfScore 3.00-G_M21895_IG03:- lea rdx, bword ptr [rsp+28H]
call C:FuncAvx(int,System.Span`1[Byte])
nop
- ;; bbWeight=1 PerfScore 1.75-G_M21895_IG04:- add rsp, 56+ ;; bbWeight=1 PerfScore 1.25+G_M21895_IG03:+ add rsp, 40
ret
;; bbWeight=1 PerfScore 1.25
-; Total bytes of code 40, prolog size 14, PerfScore 12.70, (MethodHash=7a51aa79) for method C:A(int,System.Span`1[Byte])+; Total bytes of code 15, prolog size 4, PerfScore 4.25, (MethodHash=7a51aa79) for method C:A(int,System.Span`1[Byte]) |
AndyAyersMS
commented
Jan 16, 2020
Note this doesn't get the improvement in |
AndyAyersMS
commented
Jan 16, 2020
Seems like if an implicit byref field appears as an argument in a call we ought to give more weight to promotion, since (if unpromoted) the byref will likely be in a register that conflicts with the registers needed to make the call. |
Do you mean struct promotion or CSE promotion? You probably mean this kind of "promoted" |
AndyAyersMS
commented
Jan 16, 2020
Struct promotion. The early trimming reduces the RCS_EARLY ref counts, and so leads to more cases where we we will undo promotion of implicit byref params. This undone promotion effectively "sinks" loads of the byref fields down to where they are consumed and keeps the byref live at those points, and this can lead to potential conflicts. |
AndyAyersMS
commented
Jan 27, 2020
I don't see any easy way to address the regressions, and on balance this is a net win, so I suggest we go ahead with it as is.... |
AndyAyersMS
commented
Jan 31, 2020
@dotnet/jit-contrib anyone up for reviewing this? |
CarolEidt
left a comment
There was a problem hiding this comment.
This LGTM, my only question is whether the folding of the JTRUE is something that is done elsewhere and could be factored out.
AndyAyersMS
commented
Feb 1, 2020
There is conceptually similar code in |
Aggressively fold as we substitute inline return value trees in for the return
value placeholders. Notice when this folding leads to branch simplification,
and make the associated flow graph update.
The recently added early flow opt pass will then transitively remove any
newly unreachable code.
Resolves
dotnet/coreclr#27395.dotnet/coreclr#27935 (now migrated to #13824)