-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
CQ: Big Value Type Suboptimal Inlining Code Generation #39732
Comments
cc: @EgorBo help! 😉 |
I'm going to mark this as future. Passing large structs by value through layers of calls puts a premium on struct optimizations like copy prop and reverse copy prop; the jit is not proficient at these opts. We should be able to extend the "tail call copy avoidance" change to optimize away the last of these; all we need is a call in tail position, not an actual tail call (see #33004). SysV codegen is somewhat amusing (this is with preview 5). cc @sandreenko ; Program+StructComparisonComparer`1[[Program+BigStruct, r39732]].Compare(BigStruct, BigStruct)
push rbp
vzeroupper
mov rbp,rsp
vmovdqu xmm0,xmmword ptr [rbp+10]
vmovdqu xmmword ptr [rbp+10],xmm0
vmovdqu xmm0,xmmword ptr [rbp+20]
vmovdqu xmmword ptr [rbp+20],xmm0
vmovdqu xmm0,xmmword ptr [rbp+30]
vmovdqu xmmword ptr [rbp+30],xmm0
vmovdqu xmm0,xmmword ptr [rbp+40]
vmovdqu xmmword ptr [rbp+40],xmm0
mov rax,[rdi]
mov rdi,[rax+8]
mov rax,[rax+18]
pop rbp
jmp rax
; Total bytes of code 62
`` |
@sandreenko can you look into this as part of your possible .Net 6 work? |
@AndyAyersMS sure! |
The codegen today (with TieredPGO disabled, to make it faithful to the original benchmark) is: ; Assembly listing for method Program+CompareBigStruct:ComparerStructComparison():int:this
; Emitting BLENDED_CODE for X64 with AVX - Windows
; Tier-1 compilation
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; 0 inlinees with PGO data; 3 single block inlinees; 0 inlinees without PGO data
; Final local variable assignments
;
; V00 this [V00,T00] ( 5, 5 ) ref -> rcx this class-hnd single-def
; V01 OutArgs [V01 ] ( 1, 1 ) struct (32) [rsp+00H] do-not-enreg[XS] addr-exposed "OutgoingArgSpace"
;* V02 tmp1 [V02 ] ( 0, 0 ) byref -> zero-ref "impAppendStmt"
;* V03 tmp2 [V03 ] ( 0, 0 ) struct (32) zero-ref do-not-enreg[S] "impAppendStmt"
;* V04 tmp3 [V04 ] ( 0, 0 ) struct (32) zero-ref do-not-enreg[S] "spilled call-like call argument"
; V05 tmp4 [V05 ] ( 2, 4 ) struct (32) [rsp+48H] do-not-enreg[XS] addr-exposed "by-value struct argument"
; V06 tmp5 [V06 ] ( 2, 4 ) struct (32) [rsp+28H] do-not-enreg[XS] addr-exposed "by-value struct argument"
; V07 tmp6 [V07,T01] ( 3, 6 ) ref -> rax single-def "argument with side effect"
;
; Lcl frame size = 104
G_M64140_IG01: ;; offset=0000H
sub rsp, 104
vzeroupper
;; size=7 bbWeight=1 PerfScore 1.25
G_M64140_IG02: ;; offset=0007H
mov rax, gword ptr [rcx+30H]
vmovdqu ymm0, ymmword ptr [rcx+38H]
vmovdqu ymmword ptr [rsp+48H], ymm0
vmovdqu ymm0, ymmword ptr [rcx+58H]
vmovdqu ymmword ptr [rsp+28H], ymm0
mov rcx, gword ptr [rax+08H]
lea rdx, [rsp+48H]
lea r8, [rsp+28H]
call [rax+18H]System.Comparison`1[Program+BigStruct]:Invoke(Program+BigStruct,Program+BigStruct):int:this
nop
;; size=44 bbWeight=1 PerfScore 20.25
G_M64140_IG03: ;; offset=0033H
vzeroupper
add rsp, 104
ret
;; size=8 bbWeight=1 PerfScore 2.25
; Total bytes of code 59, prolog size 7, PerfScore 29.65, instruction count 15, allocated bytes for code 59 (MethodHash=bf2d0573) for method Program+CompareBigStruct:ComparerStructComparison():int:this
; ============================================================ So looks like this has been fixed at some point. Bonus: results on my machine on main with and without physical promotion:
|
Improve support for "functor" pattern in .NET, reduce code duplication and help resolve an issue in #39543 which tries to consolidate sorting code on a generic
TComparer
code path. It would be great if the JIT could be improved in the face of big value types.Benchmark Code
Benchmark Results
Benchmark Disassembly
The problem is in the code generated for
CompareBigStruct.ComparerStructComparison
which can be easily seen..NET Core 5.0.0 (CoreCLR 5.0.20.36102, CoreFX 5.0.20.36102), X64 RyuJIT
.NET Core 5.0.0 (CoreCLR 5.0.20.36102, CoreFX 5.0.20.36102), X64 RyuJIT
.NET Core 5.0.0 (CoreCLR 5.0.20.36102, CoreFX 5.0.20.36102), X64 RyuJIT
.NET Core 5.0.0 (CoreCLR 5.0.20.36102, CoreFX 5.0.20.36102), X64 RyuJIT
.NET Core 5.0.0 (CoreCLR 5.0.20.36102, CoreFX 5.0.20.36102), X64 RyuJIT
cc: @jkotas @dotnet/jit-contrib
category:cq
theme:structs
skill-level:expert
cost:large
impact:medium
The text was updated successfully, but these errors were encountered: