-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross-language inlining with LTO #45865
Comments
Any comments on this? Is there some technical limitation that blocks enabling LTO for external libs? |
I think the best way to implement this for Rust is to basically make Rust object files "LTO compatible" and rely on users to use the right linker. I believe that almost all LTO solutions for C/C++ actually use linker plugins (hence the "link" in "link-time optimization") and Rust is the odd-one-out that uses a compiler-specific implementation for LTO. I unfortunately do not personally know what the format of the object files are going into the linker plugins for C/C++ LTO. I think the best way to enable this feature, however, is to basically do just that. Users of C/C++ that want LTO are presumably somewhat familiar with how to do it in C/C++ and with Rust we just want to enable the same thing. Rust should be able to just look like C/C++. I believe the primary change here will be to alter the way that rustc generates object files. This may embed LLVM IR in some special section (not sure) or may even involve not generating an object file at all! (unsure) Some research will need to be done into how C/C++ do this and how its done with LLVM to see what our options are. After that we can probably start out by adding a flag like At that point users will need to probably ensure that they're using clang for C/C++ (sorry Windows) as well as that their LTO plugin version is greater than that of rustc's and clang's LLVM version (or the same). I think once all that is in place then LTO should "just work" as it'll just do the normal C/C++ thing. |
Alex: doesn't rustc use ThinLTO which implies LLVM bitcode object files? In theory this should "Just Work (tm)" as long as the cc crate passes |
@alkis getting this to work likely entails storing object files in a particular format, which isn't currently done. |
@alexcrichton (Apologies if I'm telling you things you already know.) From what I can tell,
|
@jdub oh awesome! That means that this may not be all that hard :) |
@alexcrichton Ah, I didn't realise rlibs include compressed bitcode! Makes sense, really. My rlib also includes the machine code objects from the static archive, so perhaps if I produced a static archive of bitcode instead, the linker would "just work"? |
@jdub it does actually sort of sound like it'll "just work" although I haven't tried it myself, would certainly be worth a shot! We've already got target-specific options for things like |
Here's a silly sample to muck around with.
With proper LTO optimisation, I would expect everything to be inlined, and no
Indeed, all the functions are inlined into Let's make a bitcode static archive of the non-
And run
How did we go?
D'oh. |
@jdub I think that's because Rust code isn't participating in LTO there with C. Rust's LTO option does LTO internally without relying on the linker currently, so the linker still just sees an object file from us |
Yes, they are tracking the same thing after all. |
I link against a C library with a very small function, and I would like its code to be inlined in the Rust function that calls it. I had hoped that it would be possible by setting
lto = true
inCargo.toml
, but there is still a call in the final executable. This comment confirms that at the moment there is no LTO between Rust and C.I remember seeing an issue comment here that explained how to do it manually by emitting LLVM IR with
rustc
andclang
and linking it together withllvm-link
, thenopt
, but I cannot seem to find it any more.The call overhead can be substantial. For my current use case that calls a C function in an inner loop, it causes the running time to be 9 times as long as the equivalent program where the function is inlined. (It relies on a number of unstable features to be able to express the function in Rust.)
So for “efficient C bindings”, LTO that can inline across C and Rust objects would be nice to have.
The text was updated successfully, but these errors were encountered: