Rust not optimizing out C wrappers for C++ functions with LTO

Viewed 218

In trying to call a C++ function from Rust by first wrapping it in a C function and then calling the latter via Rust's FFI, I've noticed that rustc does not optimize away the C function call even when LTO is enabled. For example, I have the following files:

// foo_cc.h - just a dummy C++ function I want to call from Rust

#pragma once

namespace foo  
{
  __attribute__((noinline))
  void do_something()
  { asm("nop"); }

}
/* foo_c.h - wrapper header for foo_cc.h */

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void foo_do_something();

#ifdef __cplusplus
}
#endif
/* foo_c.cc - wrapper source file for foo_cc.h */

#include "foo_c.h"
#include "foo_cc.h"

void foo_do_something()
{ foo::do_something(); }
// foo.rs - main Rust file calling `foo_do_something`

#[link(name="foo_c")]
extern "C" {
    pub fn foo_do_something();
}

fn main() {
    unsafe { foo_do_something(); }
}

I build on amd64 with LTO and optimization enabled like this:

clang++ -flto=thin -O3 -c foo_c.cc -o foo_c.o
ar rcs libfoo_c.a foo_c.o
rustc -C linker-plugin-lto -C opt-level=3 -Clinker=clang -Clink-arg=-fuse-ld=lld foo.rs -L . -o foo

Now when I run foo through objdump, I see that the main function first performs a jump to foo_do_something which in turn does nothing but to jump to _ZN3foo12do_somethingEv. If I were to call foo_do_something from another C file, LTO would optimize away this intermediate jump, yet rustc doesn't. Is there a technical reason for this? Or am I missing some command line option etc.?

0 Answers
Related