forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Mixed language link time optimization
Daniel Micay edited this page Oct 6, 2013
·
11 revisions
main.c
#include <stdint.h>
uint32_t *foo();
int main() {
free(foo());
}
foo.rs
#[no_std];
#[allow(ctypes, cstack)];
extern {
fn malloc(size: uint) -> *mut u8;
fn free(ptr: *mut u8);
fn abort() -> !;
}
#[lang = "exchange_malloc"]
#[inline(always)]
unsafe fn exchange_malloc(size: uint) -> *mut u8 {
let ptr = malloc(size);
if ptr == 0 as *mut u8 {
abort()
}
ptr
}
#[lang = "exchange_free"]
#[inline(always)]
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.