dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

Consider expanding casts in late phases #84025

Open EgorBo opened 1 year ago

EgorBo commented 1 year ago
void Foo(object o)
{
    for (int i = 0; i < 100; i++)
    {
        if (o is string)
            Console.WriteLine("str!");
        if (o is string)
            Console.WriteLine("str!");
    }
}

Current codegen:

; Method Prog:Foo(System.Object):this
G_M20911_IG01:              ;; offset=0000H
       57                   push     rdi
       56                   push     rsi
       4883EC28             sub      rsp, 40
       488BF2               mov      rsi, rdx
       33FF                 xor      edi, edi
;; ========= loop start =========
G_M20911_IG03:              
       488BCE               mov      rcx, rsi
       4885C9               test     rcx, rcx
       741F                 je       SHORT G_M20911_IG06
       48B830A9B604F97F0000 mov      rax, 0x7FF904B6A930      ; System.String
       483901               cmp      qword ptr [rcx], rax
       7510                 jne      SHORT G_M20911_IG06
       48B9C09530808C020000 mov      rcx, 0x28C803095C0      ; 'str!'
       FF1576C79000         call     [System.Console:WriteLine(System.String)]
G_M20911_IG06:              
       488BCE               mov      rcx, rsi
       4885C9               test     rcx, rcx
       741F                 je       SHORT G_M20911_IG09
       48B830A9B604F97F0000 mov      rax, 0x7FF904B6A930      ; System.String
       483901               cmp      qword ptr [rcx], rax
       7510                 jne      SHORT G_M20911_IG09
       48B9C09530808C020000 mov      rcx, 0x28C803095C0      ; 'str!'
       FF154FC79000         call     [System.Console:WriteLine(System.String)]
G_M20911_IG09:              
       FFC7                 inc      edi
       83FF64               cmp      edi, 100
       7CAB                 jl       SHORT G_M20911_IG03
;; ========= loop end ===========
       4883C428             add      rsp, 40
       5E                   pop      rsi
       5F                   pop      rdi
       C3                   ret      
; Total bytes of code: 103

Due to early expansion, we don't hoist and don't perform CSE for it. Expected codegen if we do the expansion in late phases:

; Method Prog:Foo(System.Object):this
G_M20911_IG01:              ;; offset=0000H
       57                   push     rdi
       56                   push     rsi
       53                   push     rbx
       4883EC20             sub      rsp, 32
       4885D2               test     rdx, rdx
       7413                 je       SHORT G_M20911_IG04
       48B930A934F6F87F0000 mov      rcx, 0x7FF8F634A930      ; System.String
       33C0                 xor      rax, rax
       48390A               cmp      qword ptr [rdx], rcx
       480F45D0             cmovne   rdx, rax
G_M20911_IG04:              ;; offset=001FH
       33F6                 xor      esi, esi
       4885D2               test     rdx, rdx
       400F95C6             setne    sil
       33FF                 xor      edi, edi
;; ========= loop start =========
G_M20911_IG05:              ;; offset=002AH
       85F6                 test     esi, esi
       741C                 je       SHORT G_M20911_IG07
       48BBC095200048020000 mov      rbx, 0x248002095C0      ; 'str!'
       488BCB               mov      rcx, rbx
       FF1567C79000         call     [System.Console:WriteLine(System.String)]
       488BCB               mov      rcx, rbx
       FF155EC79000         call     [System.Console:WriteLine(System.String)]
G_M20911_IG07:              ;; offset=004AH
       FFC7                 inc      edi
       83FF64               cmp      edi, 100
       7CD9                 jl       SHORT G_M20911_IG05
;; ========= loop end ===========
       4883C420             add      rsp, 32
       5B                   pop      rbx
       5E                   pop      rsi
       5F                   pop      rdi
       C3                   ret      
; Total bytes of code: 89
ghost commented 1 year ago

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak See info in area-owners.md if you want to be subscribed.

Issue Details
```csharp void Foo(object o) { for (int i = 0; i < 100; i++) { if (o is string) Console.WriteLine("str!"); if (o is string) Console.WriteLine("str!"); } } ``` Current codegen: ```asm ; Method Prog:Foo(System.Object):this G_M20911_IG01: ;; offset=0000H 57 push rdi 56 push rsi 4883EC28 sub rsp, 40 488BF2 mov rsi, rdx 33FF xor edi, edi ;; ========= loop start ========= G_M20911_IG03: 488BCE mov rcx, rsi 4885C9 test rcx, rcx 741F je SHORT G_M20911_IG06 48B830A9B604F97F0000 mov rax, 0x7FF904B6A930 ; System.String 483901 cmp qword ptr [rcx], rax 7510 jne SHORT G_M20911_IG06 48B9C09530808C020000 mov rcx, 0x28C803095C0 ; 'str!' FF1576C79000 call [System.Console:WriteLine(System.String)] G_M20911_IG06: 488BCE mov rcx, rsi 4885C9 test rcx, rcx 741F je SHORT G_M20911_IG09 48B830A9B604F97F0000 mov rax, 0x7FF904B6A930 ; System.String 483901 cmp qword ptr [rcx], rax 7510 jne SHORT G_M20911_IG09 48B9C09530808C020000 mov rcx, 0x28C803095C0 ; 'str!' FF154FC79000 call [System.Console:WriteLine(System.String)] G_M20911_IG09: FFC7 inc edi 83FF64 cmp edi, 100 7CAB jl SHORT G_M20911_IG03 ;; ========= loop end =========== 4883C428 add rsp, 40 5E pop rsi 5F pop rdi C3 ret ; Total bytes of code: 103 ``` Due to early expansion, we don't hoist and don't perform CSE for it. Expected codegen if we do the expansion in late phases: ```asm ; Method Prog:Foo(System.Object):this G_M20911_IG01: ;; offset=0000H 57 push rdi 56 push rsi 53 push rbx 4883EC20 sub rsp, 32 4885D2 test rdx, rdx 7413 je SHORT G_M20911_IG04 48B930A934F6F87F0000 mov rcx, 0x7FF8F634A930 ; System.String 33C0 xor rax, rax 48390A cmp qword ptr [rdx], rcx 480F45D0 cmovne rdx, rax G_M20911_IG04: ;; offset=001FH 33F6 xor esi, esi 4885D2 test rdx, rdx 400F95C6 setne sil 33FF xor edi, edi ;; ========= loop start ========= G_M20911_IG05: ;; offset=002AH 85F6 test esi, esi 741C je SHORT G_M20911_IG07 48BBC095200048020000 mov rbx, 0x248002095C0 ; 'str!' 488BCB mov rcx, rbx FF1567C79000 call [System.Console:WriteLine(System.String)] 488BCB mov rcx, rbx FF155EC79000 call [System.Console:WriteLine(System.String)] G_M20911_IG07: ;; offset=004AH FFC7 inc edi 83FF64 cmp edi, 100 7CD9 jl SHORT G_M20911_IG05 ;; ========= loop end =========== 4883C420 add rsp, 32 5B pop rbx 5E pop rsi 5F pop rdi C3 ret ; Total bytes of code: 89 ```
Author: EgorBo
Assignees: -
Labels: `area-CodeGen-coreclr`
Milestone: -
kunalspathak commented 1 year ago

I think we have recently taken advantage of expanding nodes in late phase (e.g. https://github.com/dotnet/runtime/pull/83911, https://github.com/dotnet/runtime/pull/82973, https://github.com/dotnet/runtime/pull/81635), wondering if we should have a top-level issue to revisit phases that should be expanded in late phase and have consolidated code to do this instead of having copies.