Closed
Description
Cross language Link Time Optimization (LTO) is a nice feature where instead of compiling binary object files, we have clang create llvm bitcode which we link together and optimize when we generate an output binary. This is particularly useful for rust FFI cases, where we can compile a legacy C application and perform LTO when linking it with rust, thus hopefully removing some of the FFI overhead on hot codepaths.
More info can be found here and here
#[macro_use]
extern crate ctor;
use std::collections::HashMap;
#[ctor]
/// This is an immutable static, evaluated at init time
static STATIC_CTOR: HashMap<u32, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
m
};
fn main() {
println!("{:x} -> {}", 1, STATIC_CTOR.get(&1).unwrap());
}
You can compile with:
$ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang-8 -Clink-arg=-fuse-ld=lld-8" cargo run --release
Compiling proc-macro2 v0.4.27
Compiling unicode-xid v0.1.0
Compiling syn v0.15.31
Compiling quote v0.6.12
Compiling ctor v0.1.9
Compiling ctor-opt v0.1.0 (/home/x/ctor-opt)
Finished release [optimized] target(s) in 51.82s
Running `target/release/ctor-opt`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:197
3: std::panicking::default_hook
at src/libstd/panicking.rs:211
4: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:474
5: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:381
6: rust_begin_unwind
at src/libstd/panicking.rs:308
7: core::panicking::panic_fmt
at src/libcore/panicking.rs:85
8: core::panicking::panic
at src/libcore/panicking.rs:49
9: ctor_opt::main
10: std::rt::lang_start::{{closure}}
11: std::panicking::try::do_call
at src/libstd/rt.rs:49
at src/libstd/panicking.rs:293
12: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:85
13: std::rt::lang_start_internal
at src/libstd/panicking.rs:272
at src/libstd/panic.rs:388
at src/libstd/rt.rs:48
14: main
15: __libc_start_main
16: _start
This was tested on debian sid with rust nightly, clang-8 and lld-8 packages installed. Note that the clang and lld version unfortunately do need to match the rust llvm version.
Metadata
Metadata
Assignees
Labels
No labels