-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
abi: add a rust-preserve-none calling convention #151065
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
base: main
Are you sure you want to change the base?
Conversation
|
This PR changes rustc_public cc @oli-obk, @celinval, @ouz-a, @makai410 rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead. cc @rust-lang/rust-analyzer |
|
Note well: I'm planning to create a tracking issue and perhaps update other relevant projects (e.g. rust analyzer cares about abis) once we establish that there are no fundamental blockers to move forward with the approach. Does that sound reasonable? |
This is the conceptual opposite of the rust-cold calling convention and
is particularly useful in combination with the new `explicit_tail_calls`
feature.
For relatively tight loops implemented with tail calling (`become`) each
of the function with the regular calling convention is still responsible
for restoring the initial value of the preserved registers. So it is not
unusual to end up with a situation where each step in the tail call loop
is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers
are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived
and more like a conceptual inverse of `rust-cold`, but could not come
with a great name (`rust-cold` is itself not a great name: cold in what
context? from which perspective? is it supposed to mean that the
function is rarely called?)
ecf300a to
6d27ba9
Compare
| #[no_mangle] | ||
| #[inline(never)] | ||
| pub extern "rust-preserve-none" fn peach(x: u16) { | ||
| panic!("unwinding works too") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably wants a run-test too...
|
The job Click to see the possible cause of the failure (guessed by this bot) |
|
This seems somewhat related: I believe that there is no way to make tail calls work with ABIs that pass values using This calling convention is probably still useful, but adding another calling convention that uses the (unstable!) rust ABI won't actually help with moving tail call support forward. So maybe there is a possible design of an Also for completeness, using |
|
I don't intend this PR to be a solution to the indirect argument passing problem, although I see how having a calling convention with more registers available would help with indirectly passed arguments. My primary incentive is really just performance – spilling registers in the top level caller once is much more efficient than spilling and reloading on every jump. Normally I would probably look for a solution that is transparent to the user, but unfortunately in this case the decision is callee's and it cannot know if it'll be become'd or called regularly in the general case. That reminds me, I guess I'll have to verify if I don't need to change the abi computation code here... |
This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new
explicit_tail_callsfeature.For relatively tight loops implemented with tail calling (
become) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of
rust-cold, but could not come with a great name (rust-coldis itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)