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

JIT: Inline static readonly delegates #85803

Closed
wants to merge 2 commits into from

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented May 5, 2023

static Func<int, int, int> MyFunc { get; } = (x, y) => x + y;

static int Test() => RunFunc(MyFunc);

static int RunFunc(Func<int, int, int> processor)
{
    return processor(10, 20);
}

codegen for Test() with PGO enabled:

       mov      eax, 30
       ret      
; Total bytes of code 6

Not sure it's super useful (how often developers save delegates to static readonly?) but it's the first case when we can inline a lambda without checks 🙂

UPD: Also, it seems to fold typeof(T).TypeHandle.Value; and closes #5973

static nint Test()
{
    return typeof(int).TypeHandle.Value;
}

codegen:

       mov      rax, 0x7FF7A3C3EA58
       ret 
; Total bytes of code 11

@ghost ghost assigned EgorBo May 5, 2023
@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 May 5, 2023
@ghost
Copy link

ghost commented May 5, 2023

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

Issue Details
static Func<int, int, int> MyFunc { get; } = (x, y) => x + y;

static int Test() => RunFunc(MyFunc);

static int RunFunc(Func<int, int, int> processor)
{
    return processor(10, 20);
}

codegen for Test() with PGO enabled:

; Assembly listing for method Program:Foo():int
; Tier-1 compilation
       mov      eax, 30
       ret      
; Total bytes of code 6

Not sure it's super useful (how often developers save delegates to static readonly?) but it's a first case when we can inline a lambda without checks 🙂

Author: EgorBo
Assignees: EgorBo
Labels:

area-CodeGen-coreclr

Milestone: -

@EgorBo EgorBo closed this May 5, 2023
@stephentoub
Copy link
Member

stephentoub commented May 5, 2023

how often developers save delegates to static readonly

This is quite common. However it's much less common to invoke the delegate directly from that field... the primary use is passing it off to another method that will then invoke it, and that method is often not going to be inlined.

@EgorBo
Copy link
Member Author

EgorBo commented May 5, 2023

how often developers save delegates to static readonly

This is quite common. However it's much less common to invoke the delegate directly from that field... the primary use is passing it off to another method that will then invoke it, and that method is often not going to be inlined.

Ah so do we need this? 🙂 The PR should be fully complete, it's just that it's +100 LOC and needs tests, I extracted TypeHandle part into a separate PR

@stephentoub
Copy link
Member

Ah so do we need this?

My gut is it won't help much. But if there's an easy way to see how often it would kick in across runtime, for example, I'd be happy to be proven wrong.

@omariom
Copy link
Contributor

omariom commented May 5, 2023

I need both of the changes. Thanks!

@stephentoub
Copy link
Member

I need both of the changes

Can you comment on where on hot paths you directly invoke delegates stored in static readonly fields? Thanks.

@omariom
Copy link
Contributor

omariom commented May 5, 2023

It was the case I was loading and compiling simple text expressions into delegates, which were then used directly as filters and calculated fields, or in implementations of other filters.
I understand that interface and virtual dispatch are now inlinable when accessed via static readonlies, and I could use them,
but it would be nice if all the dynamic dispatches behaved uniformly in this sense.

@EgorBo
Copy link
Member Author

EgorBo commented May 5, 2023

@omariom we might get this behavior for free and for other lambdas if we land #85014 and Roslyn will start emitting it for lambdas

@ghost ghost locked as resolved and limited conversation to collaborators Jun 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RyuJIT: Intrinsify GetType().TypeHandle.Value and typeof(T).TypeHandle.Value
3 participants