mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Created Mixed language link time optimization (markdown)
@@ -0,0 +1,67 @@
|
||||
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.
|
||||
Reference in New Issue
Block a user