Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BitCast<TYP_REF>(TypeHandleToRuntimeTypeHandle(clsHandle)) => nongc obj #97955

Merged
merged 8 commits into from
Feb 7, 2024

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Feb 5, 2024

Improves codegen for #97949, new codegen for GetIntType:

; Assembly listing for method LdtokenRepro:Test():System.Type (FullOpts)
G_M57559_IG01:
       sub      rsp, 40
G_M57559_IG02:
       mov      rax, 0x1FA00005580      ; 'System.Int32'
G_M57559_IG03:
       add      rsp, 40
       ret
; Total bytes of code 19

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 5, 2024
@ghost ghost assigned EgorBo Feb 5, 2024
@ghost
Copy link

ghost commented Feb 5, 2024

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

Issue Details

Improves codegen for #97949, new codegen for GetIntType:

; Assembly listing for method LdtokenRepro:Test():System.Type (FullOpts)
G_M57559_IG01:
       sub      rsp, 40
G_M57559_IG02:
       mov      rax, 0x1FA00005580      ; 'System.Int32'
G_M57559_IG03:
       add      rsp, 40
       ret
; Total bytes of code 19
Author: EgorBo
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@EgorBo EgorBo marked this pull request as ready for review February 5, 2024 11:10
@EgorBo
Copy link
Member Author

EgorBo commented Feb 5, 2024

@dotnet/jit-contrib PTAL, simple change. Suprisingly, there were some diffs.

Basically, it optimizes:

RuntimeTypeHandle struct = CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE(constClassHandle);
RuntimeType type = struct.m_handle;

into:

<frozen object handle representing that RuntimeType>

@jkotas
Copy link
Member

jkotas commented Feb 5, 2024

Does the same optimization kick in for native AOT that uses different representation of RuntimeTypeHandle?

@EgorBo
Copy link
Member Author

EgorBo commented Feb 5, 2024

Does the same optimization kick in for native AOT that uses different representation of RuntimeTypeHandle?

Oh, I forgot that RuntimeType objects are already frozen in NAOT. Currently the function in question emits this on NAOT:

; Assembly listing for method LdtokenRepro:Test():System.Type (FullOpts)
G_M57559_IG01:
       sub      rsp, 40
G_M57559_IG02:
       lea      rcx, [(reloc 0x40000000004224d0)]      ; System.Int32
       call     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE
       mov      rcx, rax
       call     System.Type:GetTypeFromHandle(System.RuntimeTypeHandle):System.Type
       nop      
G_M57559_IG03:
       add      rsp, 40
       ret      
; Total bytes of code 30

since GetTypeFromHandle is already marked as jit intrinsic I presume it shouldn't be too hard to handle this.

@EgorBo

This comment was marked as outdated.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 5, 2024

Ah, nvm, @SingleAccretion pointed to an issue on my side

@EgorBo
Copy link
Member Author

EgorBo commented Feb 5, 2024

@SingleAccretion can you take a look?
NAOT made this PR significantly bigger so at this point I am not sure the diffs worth the efforts, although, we fixed a few potential asserts/bugs along the way. E.g. optVNConstantPropOnTree could replace a tree with a non-embeddable GT_CNS_INT on NAOT

@EgorBo
Copy link
Member Author

EgorBo commented Feb 6, 2024

@SingleAccretion I've addressed your feedback, can you give it another look? thanks

@SingleAccretion SingleAccretion self-requested a review February 7, 2024 06:50
Copy link
Contributor

@SingleAccretion SingleAccretion left a comment

Choose a reason for hiding this comment

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

Code changes LGTM!

Comment on lines 1326 to +1330
#if defined(LATE_DISASM)
node = new (this, LargeOpOpcode()) GenTreeIntCon(TYP_I_IMPL, value, fields DEBUGARG(/*largeNode*/ true));
node = new (this, LargeOpOpcode())
GenTreeIntCon(gtGetTypeForIconFlags(flags), value, fields DEBUGARG(/*largeNode*/ true));
#else
node = new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, value, fields);
node = new (this, GT_CNS_INT) GenTreeIntCon(gtGetTypeForIconFlags(flags), value, fields);
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated, but any idea why this needs a large node for LATE_DISASM?

Copy link
Contributor

@SingleAccretion SingleAccretion Feb 7, 2024

Choose a reason for hiding this comment

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

Pretty sure it's dead code.

Copy link
Member

Choose a reason for hiding this comment

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

We revived LATE_DISASM for use in SVE emitter unit tests in #96286, so it's not dead anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but I don't think this large opcode ifdefing is still needed. It seems in the past gtCompileTimeHandle was part of the requirement for a "large" node:

runtime/src/coreclr/jit/morph.cpp

Lines 12663 to 12669 in 24d149c

#if defined(LATE_DISASM)
// GT_CNS_INT is considered small, so ReplaceWith() won't copy all fields
if (tree->IsIconHandle())
{
copy->AsIntCon()->gtCompileTimeHandle = tree->AsIntCon()->gtCompileTimeHandle;
}
#endif

@EgorBo
Copy link
Member Author

EgorBo commented Feb 7, 2024

CI failure is #97049

@EgorBo EgorBo merged commit 765d884 into dotnet:main Feb 7, 2024
127 of 129 checks passed
@EgorBo EgorBo deleted the runtimetype-fix branch February 7, 2024 13:44
@BruceForstall
Copy link
Member

@EgorBo This PR seems to lead to an assert during JitDump:

Assert failure(PID 33704 [0x000083a8], Thread: 21932 [0x55ac]): Assertion failed '&typeid(T) == &typeid(size_t)' in 'C:Test(System.Object)' during 'Do value numbering' (IL size 53; hash 0x1f0881f5; FullOpts)

    File: C:\gh\runtime3\src\coreclr\jit\valuenum.h:1102
    Image: C:\gh\runtime3\artifacts\tests\coreclr\windows.x64.Debug\Tests\Core_Root\corerun.exe

Here's the test case I'm using:

using System;
using System.Runtime.CompilerServices;

public class C
{

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static void Test(object o)
    {
        if (o is string)
        {
            if (o is string)
            {
                Console.WriteLine("yes");
            }
        }
        if (o is string)
        {
            if (o is string)
            {
                Console.WriteLine("yes2");
            }
        }
    }

    public static void Main(string[] args)
    {
        Test("hello");
        Test(2);
    }

}

@EgorBo
Copy link
Member Author

EgorBo commented Feb 15, 2024

@BruceForstall yeah 🙁 I've fixed it in #98337 (ready for final review)

@EgorBo
Copy link
Member Author

EgorBo commented Feb 15, 2024

Ah, wait, it should be fixed in main after https://github.com/dotnet/runtime/pull/98273/files already. I just added ssize_t to that assert since there should be no difference for us what we use to get a handle - we cast it to a CORINFO_OBJECT_HANDLE anyway usually.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 16, 2024
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.

5 participants