Skip to content

OSR + dynamic PGO not optimizing interface dispatch as expected #74081

@stephentoub

Description

@stephentoub

Consider this code:

class Program
{
    static void Main()
    {
        IPrinter printer = new Printer();
        for (int i = 0; ; i++)
        {
            DoWork(printer, i);
        }
    }

    static void DoWork(IPrinter printer, int i)
    {
        printer.PrintIfTrue(i == int.MaxValue);
    }

    interface IPrinter
    {
        void PrintIfTrue(bool condition);
    }

    class Printer : IPrinter
    {
        public void PrintIfTrue(bool condition)
        {
            if (condition) Console.WriteLine("Print!");
        }
    }
}

When I run that, the OSR variant of Main includes the properly devirtualized and inlined invocation of Printer.PrintIfTrue:

; Assembly listing for method Program:Main()
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; OSR variant for entry point 0x8
; optimized code
; instrumented for collecting profile data
; rsp based frame
; fully interruptible
; with Dynamic PGO: edge weights are invalid, and fgCalledCount is 9999
; 2 inlinees with PGO data; 0 single block inlinees; 0 inlinees without PGO data

G_M000_IG01:                ;; offset=0000H
       4883EC38             sub      rsp, 56
       4889BC24B8000000     mov      qword ptr [rsp+B8H], rdi
       4889B424B0000000     mov      qword ptr [rsp+B0H], rsi
       488BBC2480000000     mov      rdi, gword ptr [rsp+80H]
       8B74247C             mov      esi, dword ptr [rsp+7CH]

G_M000_IG02:                ;; offset=0020H
       48B9982D1F3FFC7F0000 mov      rcx, 0x7FFC3F1F2D98
       48390F               cmp      qword ptr [rdi], rcx
       7521                 jne      SHORT G_M000_IG05
       81FEFFFFFF7F         cmp      esi, 0x7FFFFFFF
       7404                 je       SHORT G_M000_IG04

G_M000_IG03:                ;; offset=0037H
       FFC6                 inc      esi
       EBE5                 jmp      SHORT G_M000_IG02

G_M000_IG04:                ;; offset=003BH
       48B9D820C02F5A020000 mov      rcx, 0x25A2FC020D8
       488B09               mov      rcx, gword ptr [rcx]
       FF1572CD0D00         call     [Console:WriteLine(String)]
       EBE7                 jmp      SHORT G_M000_IG03

G_M000_IG05:                ;; offset=0050H
       33D2                 xor      edx, edx
       81FEFFFFFF7F         cmp      esi, 0x7FFFFFFF
       0F94C2               sete     dl
       488BCF               mov      rcx, rdi
       49BB1000F53EFC7F0000 mov      r11, 0x7FFC3EF50010
       41FF13               call     [r11]IPrinter:PrintIfTrue(bool):this
       EBCA                 jmp      SHORT G_M000_IG03

However, if change the code to manually inline DoWork:

class Program
{
    static void Main()
    {
        IPrinter printer = new Printer();
        for (int i = 0; ; i++)
        {
            printer.PrintIfTrue(i == int.MaxValue);
        }
    }

    interface IPrinter
    {
        void PrintIfTrue(bool condition);
    }

    class Printer : IPrinter
    {
        public void PrintIfTrue(bool condition)
        {
            if (condition) Console.WriteLine("Print!");
        }
    }
}

then the PrintIfTrue method is not devirtualized/inlined:

; Assembly listing for method Program:Main()
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; OSR variant for entry point 0x8
; optimized code
; instrumented for collecting profile data
; rsp based frame
; partially interruptible
; with Dynamic PGO: edge weights are invalid, and fgCalledCount is 9999

G_M000_IG01:                ;; offset=0000H
       4883EC38             sub      rsp, 56
       4889BC24C8000000     mov      qword ptr [rsp+C8H], rdi
       4889B424C0000000     mov      qword ptr [rsp+C0H], rsi
       488BBC2490000000     mov      rdi, gword ptr [rsp+90H]
       8BB4248C000000       mov      esi, dword ptr [rsp+8CH]

G_M000_IG02:                ;; offset=0023H
       FF05AB210F00         inc      dword ptr [(reloc 0x7ffc3c5f2e54)]
       488BCF               mov      rcx, rdi
       48BA582E5F3CFC7F0000 mov      rdx, 0x7FFC3C5F2E58
       E8157EC25F           call     CORINFO_HELP_CLASSPROFILE32
       488BCF               mov      rcx, rdi
       33D2                 xor      edx, edx
       81FEFFFFFF7F         cmp      esi, 0x7FFFFFFF
       0F94C2               sete     dl
       49BB1000353CFC7F0000 mov      r11, 0x7FFC3C350010
       41FF13               call     [r11]IPrinter:PrintIfTrue(bool):this
       FFC6                 inc      esi
       EBC9                 jmp      SHORT G_M000_IG02

cc: @EgorBo, @AndyAyersMS

category:cq
theme:osr

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions