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

JIT: Support loading Swift self register from SwiftSelf struct #99132

Merged
merged 4 commits into from
Mar 1, 2024

Conversation

amanasifkhalid
Copy link
Member

Adds JIT support for loading the Swift self/context register value from the SwiftSelf struct argument passed to a Swift call. Also enables corresponding tests.

@ghost ghost assigned amanasifkhalid Feb 29, 2024
@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 29, 2024
@ghost
Copy link

ghost commented Feb 29, 2024

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

Issue Details

Adds JIT support for loading the Swift self/context register value from the SwiftSelf struct argument passed to a Swift call. Also enables corresponding tests.

Author: amanasifkhalid
Assignees: amanasifkhalid
Labels:

area-CodeGen-coreclr

Milestone: -

@amanasifkhalid amanasifkhalid marked this pull request as ready for review March 1, 2024 04:19
@amanasifkhalid
Copy link
Member Author

cc @jakobbotsch @kotlarmilos @jkoritzinsky. Here's a snippet of what the codegen looks like on x64, where the self register is r13:

       mov      r13, qword ptr [rbp-0x48]
       mov      rax, 0x7FF8FF2F59B8      ; function address
       mov      qword ptr [rbp-0x90], rax
       lea      rax, G_M44653_IG07
       mov      qword ptr [rbp-0x78], rax
       mov      rax, qword ptr [rbp-0x58]
       lea      rcx, bword ptr [rbp-0xA0]
       mov      qword ptr [rax+0x10], rcx
       mov      rax, qword ptr [rbp-0x58]
       mov      byte  ptr [rax+0x0C], 0
       call     [SelfContextTests:getMagicNumber(System.Runtime.InteropServices.Swift.SwiftSelf):long]

And on arm64, where the self register is x20:

            ldr     x20, [fp, #0x80]	// [V01 loc1]
            movz    x0, #0x4988
            movk    x0, #0x2103 LSL #16
            movk    x0, #0x7FF9 LSL #32
            str     x0, [fp, #0x30]	// [V05 PInvokeFrame+0x18]
            adr     x0, [G_M44653_IG09]
            str     x0, [fp, #0x48]	// [V05 PInvokeFrame+0x30]
            ldr     x0, [fp, #0x70]	// [V04 FramesRoot]
            add     x1, fp, #32	// [V05 PInvokeFrame+0x08]
            str     x1, [x0, #0x10]
            ldr     x0, [fp, #0x70]	// [V04 FramesRoot]
            strb    wzr, [x0, #0x0C]
            movz    x0, #0x49C8      // code for SelfContextTests:getMagicNumber(System.Runtime.InteropServices.Swift.SwiftSelf):long
            movk    x0, #0x2103 LSL #16
            movk    x0, #0x7FF9 LSL #32
            ldr     x0, [x0]
            blr     x0

Comment on lines +3184 to 3187
// Exception: Lower SwiftSelf struct arg to GT_LCL_FLD
if (call->gtArgs.IsNonStandard(this, call, &arg) && arg.AbiInfo.IsPassedInRegisters() &&
(arg.GetWellKnownArg() != WellKnownArg::SwiftSelf))
{
Copy link
Member

Choose a reason for hiding this comment

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

Why is this necessary? That doesn't seem right.

Copy link
Member

Choose a reason for hiding this comment

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

Likely we should instead insert a new arg in the importer that represents "self" as a primitive instead of keeping this as a struct argument. It being a struct argument is just an artifact of the design and it wouldn't work to keep it as a struct on all ABIs.

Copy link
Member

Choose a reason for hiding this comment

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

Let's just keep it as is for now. I'm refactoring stuff for the struct work which should make this change simple to make.

Copy link
Member Author

Choose a reason for hiding this comment

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

Likely we should instead insert a new arg in the importer that represents "self" as a primitive instead of keeping this as a struct argument.

Yeah, the fact that the argument was being kept as TYP_STRUCT was causing asserts in later phases.

Let's just keep it as is for now. I'm refactoring stuff for the struct work which should make this change simple to make.

Sure thing.

@@ -4401,7 +4401,7 @@ enum class CFGCallKind

class CallArgs;

enum class WellKnownArg
enum class WellKnownArg : unsigned
Copy link
Member

Choose a reason for hiding this comment

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

Why this change? (Seems fine, just curious)

Copy link
Member Author

Choose a reason for hiding this comment

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

CallArg::m_wellKnownArg is 5 bits, and WellKnownArg::SwiftSelf has a value of 16 (also 5 bits). If m_wellKnownArg is signed, then we lose the most-significant bit, so comparisons like m_wellKnownArg == WellKnownArg::SwiftSelf fail.

@amanasifkhalid
Copy link
Member Author

ryujit-bot doesn't seem to be running, so I'll point out here that this is a no-diff change.

@amanasifkhalid amanasifkhalid merged commit f135699 into dotnet:main Mar 1, 2024
139 checks passed
@amanasifkhalid amanasifkhalid deleted the swift-self-reg branch March 1, 2024 15:53
@github-actions github-actions bot locked and limited conversation to collaborators Apr 1, 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.

2 participants