Skip to content

Commit

Permalink
Make padding in auto-layout types insignificant
Browse files Browse the repository at this point in the history
This fixes the other point in dotnet#71711 by adjusting the check in the VM
for whether types have significant padding or not. It effectively
unifies the VM logic with crossgen2's check.

Example C#:
```csharp
private (long, int) _tuple;

[MethodImpl(MethodImplOptions.NoInlining)]
private void Foo()
{
    _tuple = (5, 10);
}
```

Before:
```asm
;  V00 this         [V00,T00] (  3,  3   )     ref  ->  rcx         this class-hnd single-def
;# V01 OutArgs      [V01    ] (  1,  1   )  struct ( 0) [rsp+00H]   do-not-enreg[XS] addr-exposed "OutgoingArgSpace"
;  V02 tmp1         [V02    ] (  4,  8   )  struct (16) [rsp+08H]   do-not-enreg[SB] ld-addr-op "NewObj constructor temp"
;  V03 tmp2         [V03,T01] (  3,  5   )    long  ->  [rsp+08H]   do-not-enreg[] "field V02.Item1 (fldOffset=0x0)" P-DEP
;  V04 tmp3         [V04,T02] (  3,  5   )     int  ->  [rsp+10H]   do-not-enreg[] "field V02.Item2 (fldOffset=0x8)" P-DEP
;
; Lcl frame size = 24

G_M52879_IG01:  ;; offset=0000H
       sub      rsp, 24
       vzeroupper
						;; size=7 bbWeight=1 PerfScore 1.25
G_M52879_IG02:  ;; offset=0007H
       vxorps   xmm0, xmm0, xmm0
       vmovups  xmmword ptr [rsp+08H], xmm0
       mov      qword ptr [rsp+08H], 5
       mov      dword ptr [rsp+10H], 10
       vmovups  xmm0, xmmword ptr [rsp+08H]
       vmovups  xmmword ptr [rcx+08H], xmm0
						;; size=38 bbWeight=1 PerfScore 8.33
G_M52879_IG03:  ;; offset=002DH
       add      rsp, 24
       ret
						;; size=5 bbWeight=1 PerfScore 1.25

; Total bytes of code 50, prolog size 7, PerfScore 15.83, instruction count 10, allocated bytes for code 50 (MethodHash=1da13170) for method Program:Foo():this (FullOpts)
```

After:
```asm
;  V00 this         [V00,T00] (  4,  4   )     ref  ->  rcx         this class-hnd single-def
;# V01 OutArgs      [V01    ] (  1,  1   )  struct ( 0) [rsp+00H]   do-not-enreg[XS] addr-exposed "OutgoingArgSpace"
;* V02 tmp1         [V02    ] (  0,  0   )  struct (16) zero-ref    ld-addr-op "NewObj constructor temp"
;* V03 tmp2         [V03,T01] (  0,  0   )    long  ->  zero-ref    "field V02.Item1 (fldOffset=0x0)" P-INDEP
;* V04 tmp3         [V04,T02] (  0,  0   )     int  ->  zero-ref    "field V02.Item2 (fldOffset=0x8)" P-INDEP
;
; Lcl frame size = 0

G_M52879_IG01:  ;; offset=0000H
						;; size=0 bbWeight=1 PerfScore 0.00
G_M52879_IG02:  ;; offset=0000H
       mov      qword ptr [rcx+08H], 5
       mov      dword ptr [rcx+10H], 10
						;; size=15 bbWeight=1 PerfScore 2.00
G_M52879_IG03:  ;; offset=000FH
       ret
						;; size=1 bbWeight=1 PerfScore 1.00

; Total bytes of code 16, prolog size 0, PerfScore 4.60, instruction count 3, allocated bytes for code 16 (MethodHash=1da13170) for method Program:Foo():this (FullOpts)
```
  • Loading branch information
jakobbotsch committed Jun 30, 2023
1 parent 548aafd commit 5d95eeb
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2109,15 +2109,19 @@ static GetTypeLayoutResult GetTypeLayoutHelper(
parNode.hasSignificantPadding = false;

EEClass* pClass = pMT->GetClass();
if (pClass->IsNotTightlyPacked() && (!pClass->IsManagedSequential() || pClass->HasExplicitSize() || pClass->IsInlineArray()))
if (pClass->IsNotTightlyPacked())
{
// Historically on the JIT side we did not consider types with GC
// pointers to have significant padding, even when they have explicit
// layout attributes. This retains the more liberal treatment and
// lets the JIT still optimize these cases.
if (!pMT->ContainsPointers() && pMT != g_TypedReferenceMT)
if (pClass->HasExplicitFieldOffsetLayout() || (pClass->IsManagedSequential() && pClass->HasExplicitSize()) ||
pClass->IsInlineArray())
{
parNode.hasSignificantPadding = true;
// Historically on the JIT side we did not consider types with GC
// pointers to have significant padding, even when they have explicit
// layout attributes. This retains the more liberal treatment and
// lets the JIT still optimize these cases.
if (!pMT->ContainsPointers())
{
parNode.hasSignificantPadding = true;
}
}
}

Expand Down

0 comments on commit 5d95eeb

Please sign in to comment.