Skip to content

Conversation

hez2010
Copy link
Contributor

@hez2010 hez2010 commented Oct 18, 2025

We first need to stop spilling ldvirtftn before we can take the next step on GVM devirt.
Let's stop spilling them and see what we need to take to handle potential regressions.

Contributes to #112596

@Copilot Copilot AI review requested due to automatic review settings October 18, 2025 13:46
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Oct 18, 2025
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Oct 18, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors devirtualization handling by renaming a field and removing function pointer spilling for ldvirtftn operations. The change aims to improve performance by avoiding unnecessary temporary storage while preparing for further Generic Virtual Method (GVM) devirtualization improvements.

Key changes:

  • Renamed wasArrayInterfaceDevirt to needsMethodContext to better reflect its broader purpose
  • Removed spilling of ldvirtftn function pointers to temporary locals
  • Added better handling for cloned "this" pointers in virtual function calls

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/coreclr/vm/jitinterface.cpp Updated field assignments from wasArrayInterfaceDevirt to needsMethodContext
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp Updated SuperPMI recording/replay to use the renamed field
src/coreclr/tools/superpmi/superpmi-shared/agnostic.h Renamed struct field from wasArrayInterfaceDevirt to needsMethodContext
src/coreclr/jit/importercalls.cpp Removed function pointer spilling, improved "this" pointer handling, updated field references
src/coreclr/jit/compiler.hpp Fixed comment for helper function
src/coreclr/inc/corinfo.h Updated struct definition and comments to use the new field name

CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
bool isInstantiatingStub;
bool wasArrayInterfaceDevirt;
bool needsMethodContext;
Copy link
Contributor Author

@hez2010 hez2010 Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a rename without any meaningful change.

Copy link
Contributor

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

Comment on lines -416 to -418
unsigned lclNum = lvaGrabTemp(true DEBUGARG("VirtualCall through function pointer"));
impStoreToTemp(lclNum, fptr, CHECK_SPILL_ALL);
fptr = gtNewLclvNode(lclNum, TYP_I_IMPL);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only actual change.

@hez2010 hez2010 force-pushed the ldvirtftn-no-spill branch from ee4bd19 to 1c781c1 Compare October 18, 2025 13:54
@hez2010 hez2010 force-pushed the ldvirtftn-no-spill branch from bc516bb to a2a1d86 Compare October 18, 2025 17:27
@hez2010
Copy link
Contributor Author

hez2010 commented Oct 19, 2025

trigger mihubot since spmi jobs are broken @MihuBot

@EgorBo
Copy link
Member

EgorBo commented Oct 19, 2025

It looks like what you're trying to achieve is the devirtualization of indirect calls (GVM specifically), but you seems to be focused on a very specific case where the actual type is created right before the call (judging by your example in #112596 and the fact that you try to avoid spills).

I think we should focus on implementing #44610 for PGO first, e.g.

using System.Runtime.CompilerServices;

for (int i = 0; i < 200; i++)
{
    Test(new MyValueProcessor());
    Thread.Sleep(16);
}


[MethodImpl(MethodImplOptions.NoInlining)]
static void Test(IProcessor p)
{
    p.Process(42); // should devirtualize, but doesn't today.
}

public interface IProcessor
{
    void Process<T>(T item);
}

public class MyValueProcessor : IProcessor
{
    public void Process<T>(T item)
    {
        Console.WriteLine(item?.ToString());
    }
}

today we give up on instrumenting indirect calls.

And then, if you also want to have it divirtualized without the PGO (e.g. NAOT) you can just create fake (speculative) GDVs (which then will be folded once we hit a phase that can see through locals). Instead of just un-spilling the target that might be changed by the args?

cc @AndyAyersMS @dotnet/jit-contrib

ContainCheckIndir(node->AsIndir());
break;
case GT_PUTARG_REG:
case GT_PUTARG_STK:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the motivation behind this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's trying to suppress an assertion before addressing the lowering issue that is specific to windows-x86:

15:32:19.222 Running test: JIT/Directed/tailcall/more_tailcalls/more_tailcalls.cmd

Assert failure(PID 204 [0x000000cc], Thread: 2564 [0x0a04]): Assertion failed 'node->GetRegNum() != REG_NA' in 'GenInstance`2[System.__Canon,int]:VirtForward[System.__Canon,System.__Canon](System.__Canon,int,System.__Canon,System.__Canon):System.String:this' during 'Lowering nodeinfo' (IL size 23; hash 0xb3dc36bf; FullOpts)

    File: D:\a\_work\1\s\src\coreclr\jit\lower.cpp:9445
    Image: C:\h\w\ABFD09AF\p\corerun.exe

15:36:59.890 Running test: JIT/Regression/JitBlue/Runtime_87393/Runtime_87393/Runtime_87393.cmd

Assert failure(PID 9576 [0x00002568], Thread: 9588 [0x2574]): Assertion failed 'node->GetRegNum() != REG_NA' in 'Runtime_87393.Bar:M2[int](int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int):int' during 'Lowering nodeinfo' (IL size 41; hash 0x12b37abb; FullOpts)

    File: D:\a\_work\1\s\src\coreclr\jit\lower.cpp:9445
    Image: C:\h\w\ABFD09AF\p\corerun.exe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants