Skip to content

Conversation

AndyAyersMS
Copy link
Member

…urns

Now that we're not retyping small structs, the existing transformation works
for methods returning small structs too.

Fixes #51138.

…urns

Now that we're not retyping small structs, the existing transformation works
for methods returning small structs too.

Fixes dotnet#51138.
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 13, 2021
@AndyAyersMS
Copy link
Member Author

@sandreenko PTAL
cc @dotnet/jit-contrib

Will post diffs when I can. SPMI seems out of sync right now.

// needed to fix up the return type.
//
// See for instance fgUpdateInlineReturnExpressionPlaceHolder.
if (origCall->TypeGet() == TYP_STRUCT)
Copy link
Contributor

Choose a reason for hiding this comment

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

was it protecting only from small struct returns and not from multi-reg?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question. I think it was just the small struct returns?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that all struct calls were rejected here because of the one unsupported scenario(small structs). Now we don't need to do anything special for the previously unsupported case but we need to check that it works as expected for all of them.

I have ran the change locally with assert(false) inside the block and we did not go into if (origCall->TypeGet() == TYP_STRUCT) case on framework libraries crossgen/pmi x64/arm64 windows/unix. Is it expected?

However, I saw that we hit it aspnet.run.windows.x64 spmi collection but could not collect the diffs because when we delete this block we start hitting missing answers for the new questions.

Copy link
Member Author

Choose a reason for hiding this comment

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

This optimization requires PGO data, so not too surprising it doesn't fire much for libraries code.

Also by this point any struct return that uses a hidden buffer has been ntransformed and the return type is no longer TYP_STRUCT.

Here's a simple test case where the case does git hit. Run with COMPlus_TieredPGO=1.

using System;
using System.Threading;
using System.Runtime.CompilerServices;

struct P
{
    public int x;
    public int y;
}

class B
{
    virtual public P get() => new P();
}

class D : B
{
    override public P get() => new P() { x = 67, y = 33 };
}

class X
{
    public static int F(B b) => b.get().x + b.get().y;

    [MethodImpl(MethodImplOptions.NoOptimization)]
    public static int Main()
    {
        B b = new D();
        int r = 0;
        for (int i = 0; i < 100; i++)
        {
            r += F(b);
            Thread.Sleep(15);
        }
        
        r = 0;
        for (int i = 0; i < 10000; i++)
        {
            r += F(b);
        }
        
        r /= 10000;
        
        Console.WriteLine($"r={r}");
        
        return r;
    }
}

I also ran jit-experimental CI below which gives us some coverage, and there were no unexpected failures (save for emptystacktrace\OOMException01 which seems to be failing everywhere).

Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

LGTM

@AndyAyersMS
Copy link
Member Author

Did some extra testing on SysV and verified GDV now handles 1 and 2 reg struct returns properly.

@AndyAyersMS AndyAyersMS merged commit c377f41 into dotnet:main Apr 13, 2021
@AndyAyersMS AndyAyersMS deleted the GuardedDevirtStructReturns branch April 13, 2021 20:10
@JulieLeeMSFT JulieLeeMSFT added this to the 6.0.0 milestone Apr 15, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 15, 2021
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.

Update guarded devirtualization to handle struct returns

3 participants