-
Notifications
You must be signed in to change notification settings - Fork 0
Mixed language link time optimization
This can be done with or without the runtime enabled, but the example here will disable it in order to demonstrate a very simple optimization enabled by LTO.
main.c
#include <stdint.h>
#include <stdlib.h>
uint32_t *foo();
int main(void) {
free(foo());
return 0;
}foo.rs
#[no_std];
#[allow(ctypes)];
extern {
fn malloc(size: uint) -> *mut u8;
fn free(ptr: *mut u8);
fn abort() -> !;
}
#[lang = "exchange_malloc"]
unsafe fn exchange_malloc(size: uint) -> *mut u8 {
let ptr = malloc(size);
if ptr == 0 as *mut u8 {
abort()
}
ptr
}
#[lang = "exchange_free"]
unsafe fn exchange_free(ptr: *mut u8) {
free(ptr)
}
#[no_mangle]
extern "C" fn foo() -> ~u32 { ~5 }Build LLVM bytecode from the Rust code:
$ rustc foo.rs --emit-llvm --lib -O
The --lib flag is necessary even if Rust defines main, to avoid treating
the Rust part as the entire application.
Compile together the C and Rust code with clang:
$ clang foo.bc main.c -flto -O3 -o main
Verify that LLVM eliminated the call to foo via inlining and removed the
allocation as a dead store:
$ gdb main
(gdb) disassemble main
Dump of assembler code for function main:
0x00000000004005b0 <+0>: xor %eax,%eax
0x00000000004005b2 <+2>: retq
End of assembler dump.
To do this with the Rust runtime on, define a regular main function in Rust and pass the necessary link flags to clang. The necessary switches can be obtained with rustc -Z print-link-args foo.rs. In order for segmented stacks to work, rustc will likely need to be taught to take LLVM bytecode files as input to combine with the current crate.
All Categories:
- Docs -- For users
- Notes -- For developers
- Libs -- For library authors
- Meeting minutes