-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Today, CoreCLR heavily relies on Dynamic PGO to inline delegates even when in theory it doesn't need any profile when the target is known. Since normally NativeAOT doesn't have any profile, it basically almost never inlines delegates. We can workaround it by synthesizing a fake static pgo data during ILC compilation where for every delegate invocation site we try to detect if there is only one (or a few) address-taken methods exist with the same signature, so then ILC can create such a fake static profile and JIT will use its existing infrastructure to perform a GDV-based inlining for delegates.
Example:
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test() => Invoke(() => new Program());
static void Invoke(Func<Program> func) => func(); // only one method matches this delegate invokeCoreCLR with Dynamic PGO:
G_M24707_IG01: ;; offset=0x0000
push rbx
sub rsp, 32
G_M24707_IG02:
mov rcx, 0x26622C001F8
mov rax, gword ptr [rcx]
test rax, rax
je SHORT G_M24707_IG05
G_M24707_IG03:
mov rcx, 0x7FFA8B7F0948
cmp qword ptr [rax+0x18], rcx
jne SHORT G_M24707_IG06
G_M24707_IG04:
add rsp, 32
pop rbx
ret
G_M24707_IG05:
<cold section>(The delegate was inlined and the new Program allocation was optimized out as unused)
PS: Presumably for this specific case we don't even need the GDV check, but that is irrelevant to the issue.
NativeAOT codegen:
G_M24707_IG01: ;; offset=0x0000
push rbx
sub rsp, 32
G_M24707_IG02: ;; offset=0x0005
mov rcx, qword ptr [(reloc 0x4000000000420b10)]
mov rax, gword ptr [rcx+0x10]
test rax, rax
jne SHORT G_M24707_IG04
G_M24707_IG03: ;; offset=0x0015
lea rcx, [(reloc 0x4000000000420b80)] ; System.Func`1[Program]
call CORINFO_HELP_NEWSFAST
mov rbx, rax
mov rcx, rbx
lea rdx, gword ptr [(reloc 0x4000000000420b40)] ; 'Frozen Program.<>c object'
call CORINFO_HELP_READYTORUN_DELEGATE_CTOR
mov rcx, qword ptr [(reloc 0x4000000000420b10)]
lea rcx, [rcx+0x10]
mov rdx, rbx
call CORINFO_HELP_ASSIGN_REF
mov rax, rbx
G_M24707_IG04: ;; offset=0x0049
mov rcx, gword ptr [rax+0x08]
call [rax+0x20]System.Func`1[System.__Canon]:Invoke():System.__Canon:this
nop
G_M24707_IG05: ;; offset=0x0051
add rsp, 32
pop rbx
ret Not inlined, the non-inlined target allocates since the return value escapes.
cc @dotnet/ilc-contrib
Metadata
Metadata
Assignees
Labels
Type
Projects
Status