Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upreplace the implementation of inline functions #14527
Comments
thestinger
added
I-slow
labels
May 29, 2014
thestinger
referenced this issue
May 29, 2014
Closed
Consider using available_externally linkage for cross-crate inlined functions #10212
This comment has been minimized.
This comment has been minimized.
|
cc me |
huonw
referenced this issue
Aug 2, 2014
Merged
avoid redundant translation of items during monomorphization #16059
epdtry
referenced this issue
Aug 5, 2014
Closed
use available_externally linkage for cross-crate inlined functions #16270
This comment has been minimized.
This comment has been minimized.
|
Visiting for triage. I have nothing to add, but this is very interesting. |
cmr
self-assigned this
Mar 25, 2015
cmr
removed their assignment
Jan 5, 2016
dotdash
referenced this issue
Jan 15, 2016
Closed
Cross-crate #[inline] functions are handled badly in unoptimized builds #30933
Mark-Simulacrum
added
C-enhancement
T-compiler
labels
Jul 21, 2017
alexcrichton
referenced this issue
Oct 20, 2017
Closed
Tracking issue for enabling multiple CGUs in release mode by default #45320
This comment has been minimized.
This comment has been minimized.
|
@michaelwoerister Is the recent work with reusing upstream codegen for monomorphizations relevant here? It seems like maybe enabling that for inline functions would be good. cc #47317 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thestinger commentedMay 29, 2014
Rust's implementation of
#[inline]functions is far from ideal. It's a major contributor to both slow compile times and bloated binaries.There are an enormous number of
#[inline]functions in the standard libraries, and most have far more than one layer of inner#[inline]function calls. The work to convert these functions to LLVM IR, optimize and translate to machine code is duplicated for every single crate. Theinlinepass is not used at--opt-level=0and--opt-level=1, so the result is wasted time and duplicated code without any benefits.It is possible to implement
#[inline]functions without duplicating the work of converting to LLVM IR and optimizing. The compiler can also entirely avoid any duplicated function bodies when the optimization level is not high enough forinline, the function is used as a function pointer or it is above the threshold.Before compiling all of the functions in a library crate, Rust should create an LLVM module with all of the externally reachable inline functions in the crate. It will run the optimization passes on this LLVM module before continuing to compile, and it end up stored as metadata in the
rlibor dynamic library in the bytecode format.The compiler will then continue on with the compilation of the other functions in the crate. The work to generate optimized LLVM IR from the externally reachable
#[inline]is already complete and can be reused. These functions will not be marked internal, because other crates will be able to call through to these.Now, when Rust is compiling another crate, it can start by fetching the LLVM bytecode for the required inline functions. These functions will be marked
available_externallyand use the original symbol from the source library, so that if inlining does not occur there will be no duplicate code. At--opt-level=0and--opt-level=1, it can simply generate an external call immediately and ignore the bytecode blob.It would also be possible to leverage this for instantiations of generic functions, by making the instantiations already done by the library available externally as LLVM bytecode blobs in the metadata.