Conversation
Implement direct and indirect tail calls on x86-64 and AArch64 using the Winch callee-pop convention. Include semantic, trampoline, trap, stack-result, ABI, and disassembly coverage with the implementation.
Reclaim alignment padding and consumed operand spills together when no stack return area must be preserved. Cover live operands, consumed results, and direct, imported, and indirect calls on both supported architectures.
Use a short SP-relative return sequence for compact stack-argument frames and retain the FP-relative fallback for larger frames. Include runtime, disassembly, and exact imm8-boundary encoding tests.
Label Messager: wasmtime:configIt looks like you are changing Wasmtime's configuration options. Make sure to
DetailsTo modify this label's message, edit the To add new label messages or remove existing label messages, edit the |
|
Thanks for this -- I will be able to review next week (currently on a work trip with limited availability). |
There was a problem hiding this comment.
Did a first pass; thanks for all the changes here. FWIW, @macovedj and myself discussed some of the trade-offs here between a caller and callee pop approach.
The following programs fail to compile:
(module
(type $t (func (result i32)))
(table 1 funcref)
(func (export "f") (param i32) (result i32)
(if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
(if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
(if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
(if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
(if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
(i32.const 0)
)
)
When invoked via
target/release/wasmtime -C compiler=winch -W tail-call <wasm>
It fails with
Winch internal error: Expected register to be available.
I think we are failing to free the register in emit_return?
(module
(func $f
(return_call $f)
(loop)
)
)When invoked using epoch or using fuel interruption, like:
wasmtime compile -C compiler=winch -W tail-call,fuel=1000 <wasm>wasmtime compile -C compiler=winch -W tail-call,epoch-interruption=y <wasm>
It fails with:
Winch internal error: Invalid local offset
Is it possible that we are not handling SP correctly at emit_return?
Aside from the issues above, I think we'd also want to:
- Enable tail calls in the fuzzer configuration
- Update the doc comment in
Config::wasm_tail_call
|
Thanks @saulecabrera! |
Subscribe to Label Actioncc @fitzgen DetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "cranelift:area:machinst", "cranelift:area:x64", "fuzzing", "wasmtime:api", "wasmtime:config"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
Adds support for
return_callandreturn_call_indirectto Winch on x86-64 and AArch64.The implementation changes Winch’s internal calling convention so callees reclaim their aligned incoming stack-argument area before returning. This applies to ordinary calls as well as tail calls. Tail calls can then replace the current frame and resize the argument area without requiring the original caller to recover SP afterward. Cranelift-generated trampolines use the existing
callee_pop_sizemachinery to follow the same convention.Includes two performance optimizations: