Skip to content
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

[NativeAOT] Accessing static variables, ideally, should not call runtime helpers. #79436

Closed
VSadov opened this issue Dec 9, 2022 · 5 comments
Assignees
Milestone

Comments

@VSadov
Copy link
Member

VSadov commented Dec 9, 2022

It is a bit surprising that in a completely static scenario, statically compiled code calls helpers like __GetGCStaticBase/__GetNonGCStaticBase.

I am porting some c++ code to c#/NativeAOT and I see impact on performance from this in a few tight spots.
Can the emit for statics be closer to the native compilers?

Repro:

using System.Runtime.CompilerServices;

internal class Program
{
    static int something1;
    static string something2;

    private static void Main(string[] args)
    {
        Test();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
        something2 = "qwer";
        Console.WriteLine(something1 + something2);

        System.Diagnostics.Debugger.Break();
    }
}

After compiling for nativeAOT/release, I see in debugger:

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
00007FF6ABFE1CA0  push        rdi  
00007FF6ABFE1CA1  push        rsi  
00007FF6ABFE1CA2  sub         rsp,28h  
00007FF6ABFE1CA6  call        __GetNonGCStaticBase_ConsoleApp11_Program (07FF6ABED12F6h)    <===== ????
00007FF6ABFE1CAB  mov         rsi,rax  
00007FF6ABFE1CAE  mov         dword ptr [rsi],4D2h  
        something2 = "qwer";
00007FF6ABFE1CB4  call        __GetGCStaticBase_ConsoleApp11_Program (07FF6ABED1E0Dh)      <======????
00007FF6ABFE1CB9  mov         rdi,rax  
00007FF6ABFE1CBC  lea         rcx,[__Str_qwer (07FF6AC17D1B8h)]  
00007FF6ABFE1CC3  mov         qword ptr [rdi+8],rcx  
        Console.WriteLine(something1 + something2);
00007FF6ABFE1CC7  mov         ecx,dword ptr [rsi]  
00007FF6ABFE1CC9  call        S_P_CoreLib_System_Number__Int32ToDecStr (07FF6ABF62BD0h)  
00007FF6ABFE1CCE  mov         rcx,rax  
00007FF6ABFE1CD1  mov         rdx,qword ptr [rdi+8]  
00007FF6ABFE1CD5  call        String__Concat_5 (07FF6ABF4D150h)  
00007FF6ABFE1CDA  mov         rcx,rax  
00007FF6ABFE1CDD  call        System_Console_System_Console__WriteLine_12 (07FF6AC00ED00h)  

        System.Diagnostics.Debugger.Break();
00007FF6ABFE1CE2  call        S_P_CoreLib_System_Diagnostics_Debugger__Break (07FF6ABFA6D30h)  
    }
00007FF6ABFE1CE7  nop  
00007FF6ABFE1CE8  add         rsp,28h  
00007FF6ABFE1CEC  pop         rsi  
00007FF6ABFE1CED  pop         rdi  
00007FF6ABFE1CEE  ret  
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Dec 9, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 9, 2022
@ghost
Copy link

ghost commented Dec 9, 2022

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

Issue Details

It is a bit surprising that in a completely static scenario on a completely statically compiled runtime code calls helpers like __GetGCStaticBase/__GetNonGCStaticBase.

I am porting some c++ code and see impact on performance from this in a few tight spots.
Can the emit for statics be closer to the native compilers?

Repro:

using System.Runtime.CompilerServices;

internal class Program
{
    static int something1;
    static string something2;

    private static void Main(string[] args)
    {
        Test();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
        something2 = "qwer";
        Console.WriteLine(something1 + something2);

        System.Diagnostics.Debugger.Break();
    }
}

After compiling for nativeAOT/release, I see in debugger:

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
00007FF6ABFE1CA0  push        rdi  
00007FF6ABFE1CA1  push        rsi  
00007FF6ABFE1CA2  sub         rsp,28h  
00007FF6ABFE1CA6  call        __GetNonGCStaticBase_ConsoleApp11_Program (07FF6ABED12F6h)    <===== ????
00007FF6ABFE1CAB  mov         rsi,rax  
00007FF6ABFE1CAE  mov         dword ptr [rsi],4D2h  
        something2 = "qwer";
00007FF6ABFE1CB4  call        __GetGCStaticBase_ConsoleApp11_Program (07FF6ABED1E0Dh)      <======????
00007FF6ABFE1CB9  mov         rdi,rax  
00007FF6ABFE1CBC  lea         rcx,[__Str_qwer (07FF6AC17D1B8h)]  
00007FF6ABFE1CC3  mov         qword ptr [rdi+8],rcx  
        Console.WriteLine(something1 + something2);
00007FF6ABFE1CC7  mov         ecx,dword ptr [rsi]  
00007FF6ABFE1CC9  call        S_P_CoreLib_System_Number__Int32ToDecStr (07FF6ABF62BD0h)  
00007FF6ABFE1CCE  mov         rcx,rax  
00007FF6ABFE1CD1  mov         rdx,qword ptr [rdi+8]  
00007FF6ABFE1CD5  call        String__Concat_5 (07FF6ABF4D150h)  
00007FF6ABFE1CDA  mov         rcx,rax  
00007FF6ABFE1CDD  call        System_Console_System_Console__WriteLine_12 (07FF6AC00ED00h)  

        System.Diagnostics.Debugger.Break();
00007FF6ABFE1CE2  call        S_P_CoreLib_System_Diagnostics_Debugger__Break (07FF6ABFA6D30h)  
    }
00007FF6ABFE1CE7  nop  
00007FF6ABFE1CE8  add         rsp,28h  
00007FF6ABFE1CEC  pop         rsi  
00007FF6ABFE1CED  pop         rdi  
00007FF6ABFE1CEE  ret  
Author: VSadov
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@ghost
Copy link

ghost commented Dec 9, 2022

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

It is a bit surprising that in a completely static scenario on a completely statically compiled runtime code calls helpers like __GetGCStaticBase/__GetNonGCStaticBase.

I am porting some c++ code and see impact on performance from this in a few tight spots.
Can the emit for statics be closer to the native compilers?

Repro:

using System.Runtime.CompilerServices;

internal class Program
{
    static int something1;
    static string something2;

    private static void Main(string[] args)
    {
        Test();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
        something2 = "qwer";
        Console.WriteLine(something1 + something2);

        System.Diagnostics.Debugger.Break();
    }
}

After compiling for nativeAOT/release, I see in debugger:

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Test()
    {
        something1 = 1234;
00007FF6ABFE1CA0  push        rdi  
00007FF6ABFE1CA1  push        rsi  
00007FF6ABFE1CA2  sub         rsp,28h  
00007FF6ABFE1CA6  call        __GetNonGCStaticBase_ConsoleApp11_Program (07FF6ABED12F6h)    <===== ????
00007FF6ABFE1CAB  mov         rsi,rax  
00007FF6ABFE1CAE  mov         dword ptr [rsi],4D2h  
        something2 = "qwer";
00007FF6ABFE1CB4  call        __GetGCStaticBase_ConsoleApp11_Program (07FF6ABED1E0Dh)      <======????
00007FF6ABFE1CB9  mov         rdi,rax  
00007FF6ABFE1CBC  lea         rcx,[__Str_qwer (07FF6AC17D1B8h)]  
00007FF6ABFE1CC3  mov         qword ptr [rdi+8],rcx  
        Console.WriteLine(something1 + something2);
00007FF6ABFE1CC7  mov         ecx,dword ptr [rsi]  
00007FF6ABFE1CC9  call        S_P_CoreLib_System_Number__Int32ToDecStr (07FF6ABF62BD0h)  
00007FF6ABFE1CCE  mov         rcx,rax  
00007FF6ABFE1CD1  mov         rdx,qword ptr [rdi+8]  
00007FF6ABFE1CD5  call        String__Concat_5 (07FF6ABF4D150h)  
00007FF6ABFE1CDA  mov         rcx,rax  
00007FF6ABFE1CDD  call        System_Console_System_Console__WriteLine_12 (07FF6AC00ED00h)  

        System.Diagnostics.Debugger.Break();
00007FF6ABFE1CE2  call        S_P_CoreLib_System_Diagnostics_Debugger__Break (07FF6ABFA6D30h)  
    }
00007FF6ABFE1CE7  nop  
00007FF6ABFE1CE8  add         rsp,28h  
00007FF6ABFE1CEC  pop         rsi  
00007FF6ABFE1CED  pop         rdi  
00007FF6ABFE1CEE  ret  
Author: VSadov
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged, area-NativeAOT-coreclr

Milestone: -

@VSadov
Copy link
Member Author

VSadov commented Dec 9, 2022

Perhaps there are reasons for dynamic indirection, but it feels like - if compiler knows what helpers to call and compiler has generated those helpers, maybe it could just inline the results instead?

@MichalStrehovsky
Copy link
Member

Perhaps there are reasons for dynamic indirection, but it feels like - if compiler knows what functions to call and compiler has generated those helpers, maybe it could just inline the results instead?

No reason - just a current codegen limitation - we cannot express the access pattern though JitInterface. This is one of the sub-bullets in #64242. Cc @EgorBo this is in your area of interests.

@EgorBo EgorBo self-assigned this Dec 9, 2022
@teo-tsirpanis teo-tsirpanis removed the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Dec 9, 2022
@EgorBo
Copy link
Member

EgorBo commented Mar 6, 2023

Closing as completed. Current codegen for Test()

; Method Program:Test()
G_M24707_IG01:              ;; offset=0000H
       56                   push     rsi
       4883EC20             sub      rsp, 32
G_M24707_IG02:              ;; offset=0005H
       C705FCFFFFFFD2040000 mov      dword ptr [(reloc 0x4000000000423508)], 0x4D2      ; static handle
       488B3500000000       mov      rsi, qword ptr [(reloc 0x4000000000423518)]
       488D0D00000000       lea      rcx, gword ptr [(reloc 0x4000000000423580)]
       48894E08             mov      gword ptr [rsi+08H], rcx
       8B0D00000000         mov      ecx, dword ptr [(reloc 0x4000000000423508)]
       E800000000           call     System.Number:Int32ToDecStr(int):System.String
       488BC8               mov      rcx, rax
       488B5608             mov      rdx, gword ptr [rsi+08H]
       E800000000           call     System.String:Concat(System.String,System.String):System.String
       488BC8               mov      rcx, rax
       E800000000           call     System.Console:WriteLine(System.String)
       E800000000           call     System.Diagnostics.Debugger:Break()
       90                   nop      
G_M24707_IG03:              ;; offset=0046H
       4883C420             add      rsp, 32
       5E                   pop      rsi
       C3                   ret      
; Total bytes of code: 76

@EgorBo EgorBo closed this as completed Mar 6, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Mar 6, 2023
@EgorBo EgorBo added this to the 8.0.0 milestone Mar 6, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Apr 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants