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

Cranelift: Implement tail calls for x86_64 #6635

Merged
merged 1 commit into from Jun 27, 2023

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Jun 23, 2023

No description provided.

@fitzgen fitzgen requested a review from a team as a code owner June 23, 2023 16:30
@fitzgen fitzgen requested review from abrown and removed request for a team June 23, 2023 16:30
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:aarch64 Issues related to AArch64 backend. cranelift:area:x64 Issues related to x64 codegen isle Related to the ISLE domain-specific language labels Jun 23, 2023
@github-actions
Copy link

Subscribe to Label Action

cc @cfallin, @fitzgen

This issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "cranelift:area:machinst", "cranelift:area:x64", "isle"

Thus the following users have been cc'd because of the following labels:

  • cfallin: isle
  • fitzgen: isle

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

@fitzgen fitzgen requested review from cfallin and removed request for abrown June 23, 2023 16:52
@fitzgen fitzgen force-pushed the x64-tail-calls branch 2 times, most recently from 1c6f497 to 047bed7 Compare June 23, 2023 18:16
@afonso360
Copy link
Contributor

afonso360 commented Jun 25, 2023

👋 Hey, I'm not sure if this is ready or not, but I implemented return call's on fuzzgen (#6641) and it found something.

It is possible that this is related to #6640, but it feels quite different. Here we get a segfault, and we don't need the stack probe.

Testcase
test run
set preserve_frame_pointers=true
target x86_64

function %b(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8) -> i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 tail {
    ss0 = explicit_slot 126
    ss1 = explicit_slot 126
    ss2 = explicit_slot 13

block0(v0: i8, v1: i8, v2: i8, v3: i8, v4: i8, v5: i8, v6: i8, v7: i8, v8: i8, v9: i8, v10: i8, v11: i8, v12: i8, v13: i8, v14: i8, v15: i8):
    return v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v9, v9, v9, v9, v9, v9
}


function %a(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8) -> i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 tail {
    sig0 = (i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8) -> i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 tail
    fn0 = %b sig0

block0(v0: i8, v1: i8, v2: i8, v3: i8, v4: i8, v5: i8, v6: i8, v7: i8, v8: i8, v9: i8, v10: i8, v11: i8, v12: i8, v13: i8, v14: i8, v15: i8):
    return_call fn0(v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0, v0)
}

; run: %a(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

@fitzgen
Copy link
Member Author

fitzgen commented Jun 26, 2023

@afonso360 still haven't dug in fully yet, but it is interesting that the second function claims the first function's signature is something other than what it the function is declared as: the second function says the first three arguments are uext but the first function doesn't declare that. That shouldn't matter here I don't think but seems like something that fuzzgen shouldn't generate.

@afonso360
Copy link
Contributor

Oh boy, I removed uext and sext when I was minimizing the test case, but it looks like I accidentally left those in. Please ignore them! Fuzzgen should be generating those correctly, at least I haven't ever caught it not doing so.

I've updated the example above to remove them, and verified that it still reproduces the original issue.

@fitzgen
Copy link
Member Author

fitzgen commented Jun 26, 2023

Fixed that fuzz bug, thanks again for reporting it @afonso360!

Turns out that my codegen-the-arguments sequence was accidentally skipping "hidden" extra parameters like return pointers. Fixed!

cranelift/codegen/src/isa/x64/inst/emit.rs Show resolved Hide resolved
cranelift/codegen/src/isa/x64/inst/emit.rs Outdated Show resolved Hide resolved
cranelift/codegen/src/isa/x64/inst/emit.rs Show resolved Hide resolved
cranelift/codegen/src/machinst/buffer.rs Outdated Show resolved Hide resolved
Copy link
Member

@cfallin cfallin left a comment

Choose a reason for hiding this comment

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

Overall this looks totally reasonable to me -- excited to see the final piece fall into place, at least for x86-64!

In addition to comments above I think it would be nice to see the "extra ret-addr movement" go away for the overwhelmingly common case (no stack args) either in this PR or in an immediate followup -- it seems to me that it shouldn't be too much work (tens of lines of code? Option<Reg> for ret_addr, and check if old_size == new_size?) and it's an important (in)efficiency to clean up soon when using tail-calls as a sort of fine-grained control flow mechanism (BB jumps between funclets etc).

Otherwise, happy to see this merged with comments addressed!

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>
@fitzgen
Copy link
Member Author

fitzgen commented Jun 27, 2023

In addition to comments above I think it would be nice to see the "extra ret-addr movement" go away for the overwhelmingly common case (no stack args) either in this PR or in an immediate followup -- it seems to me that it shouldn't be too much work (tens of lines of code? Option<Reg> for ret_addr, and check if old_size == new_size?) and it's an important (in)efficiency to clean up soon when using tail-calls as a sort of fine-grained control flow mechanism (BB jumps between funclets etc).

Will do this in an immediate follow up.

Thanks for the review!

@fitzgen fitzgen enabled auto-merge June 27, 2023 16:41
@fitzgen fitzgen added this pull request to the merge queue Jun 27, 2023
Merged via the queue into bytecodealliance:main with commit 4154fa4 Jun 27, 2023
25 checks passed
@fitzgen fitzgen deleted the x64-tail-calls branch June 27, 2023 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift:area:aarch64 Issues related to AArch64 backend. cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:x64 Issues related to x64 codegen cranelift Issues related to the Cranelift code generator isle Related to the ISLE domain-specific language
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants