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?)
33 lines
1 KiB
Rust
33 lines
1 KiB
Rust
//@ add-minicore
|
|
//@ revisions: X86 AARCH64 UNSUPPORTED
|
|
//@ [X86] compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu
|
|
//@ [X86] needs-llvm-components: x86
|
|
//@ [AARCH64] compile-flags: -C no-prepopulate-passes --target=aarch64-unknown-linux-gnu
|
|
//@ [AARCH64] needs-llvm-components: aarch64
|
|
//@ [UNSUPPORTED] compile-flags: -C no-prepopulate-passes --target=i686-unknown-linux-gnu
|
|
//@ [UNSUPPORTED] needs-llvm-components: x86
|
|
|
|
#![crate_type = "lib"]
|
|
#![feature(rust_preserve_none_cc)]
|
|
#![feature(no_core, lang_items)]
|
|
#![no_core]
|
|
|
|
extern crate minicore;
|
|
|
|
// X86: define{{( dso_local)?}} preserve_nonecc void @peach(i16
|
|
// AARCH64: define{{( dso_local)?}} preserve_nonecc void @peach(i16
|
|
// UNSUPPORTED: define{{( dso_local)?}} void @peach(i16
|
|
#[no_mangle]
|
|
#[inline(never)]
|
|
pub extern "rust-preserve-none" fn peach(x: u16) {
|
|
loop {}
|
|
}
|
|
|
|
// X86: call preserve_nonecc void @peach(i16
|
|
// AARCH64: call preserve_nonecc void @peach(i16
|
|
// UNSUPPORTED: call void @peach(i16
|
|
pub fn quince(x: u16) {
|
|
if let 12345u16 = x {
|
|
peach(54321);
|
|
}
|
|
}
|