Skip to content

Guarded devirtualization based on whole program view #86235

Closed
@MichalStrehovsky

Description

@MichalStrehovsky

In Native AOT we have a whole program view that often knows the full set of types that could be implementing an interface. RyuJIT already takes advantage of it for the case of interfaces implemented by exactly one class.

It would be nice if RyuJIT could also do guarded devirtualization for the case of multiple implementing classes. I'm looking at the ASP.NET Stage1 Goldilocks app profiles where I see we're spending about 3% of samples in RhpInterfaceDispatch1. This helper performs cached interface dispatch on monomorphic callsites and looks like this:

00007FF787DFFC80 4D 8B 5A 08          mov         r11,qword ptr [r10+8]  
00007FF787DFFC84 48 8B 01             mov         rax,qword ptr [rcx]  
00007FF787DFFC87 49 3B 43 20          cmp         rax,qword ptr [r11+20h]  
00007FF787DFFC8B 75 04                jne         Attempt1 (07FF787DFFC91h)  
00007FF787DFFC8D 41 FF 63 28          jmp         qword ptr [r11+28h]  
00007FF787DFFC91 E9 CA 07 00 00       jmp         RhpInterfaceDispatchSlow (07FF787E00460h)  

The fact that we see 3% of samples in these 6 assembly instructions means that:

  1. Monomorphic interface dispatch is very common in ASP.NET
  2. We're getting guaranteed CPU pipeline stalls very often: there's only one such helper shared for all interface calls and it's getting guaranteed mispredicted every time more than one interface call is in the hot path.

I had a look at the places where this happens and there's often only 2-3 classes that implement the interface in the whole program. It would likely help a ton if RyuJIT could generate inline if/else if/else if/else checks for these. It would be nice if the number of supported targets would be configurable through --codegenopt so that we can tune the right value of it for BLENDED/SPEED_OPT settings.

Cc @EgorBo

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