Skip to content
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

replace the implementation of inline functions #14527

Open
thestinger opened this issue May 29, 2014 · 6 comments
Open

replace the implementation of inline functions #14527

thestinger opened this issue May 29, 2014 · 6 comments
Labels
A-codegen Area: Code generation C-enhancement Category: An issue proposing an enhancement or a PR with one. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-compiletime Issue: Problems and improvements with respect to compile times. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@thestinger
Copy link
Contributor

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. The inline pass is not used at --opt-level=0 and --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 for inline, 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 rlib or 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_externally and use the original symbol from the source library, so that if inlining does not occur there will be no duplicate code. At --opt-level=0 and --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.

@emberian
Copy link
Member

cc me

@reem
Copy link
Contributor

reem commented Mar 2, 2015

Visiting for triage. I have nothing to add, but this is very interesting.

@emberian emberian self-assigned this Mar 25, 2015
@emberian emberian removed their assignment Jan 5, 2016
@Mark-Simulacrum Mark-Simulacrum added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 21, 2017
@Mark-Simulacrum
Copy link
Member

@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

@jonas-schievink jonas-schievink added the A-codegen Area: Code generation label Jan 13, 2020
@jonas-schievink
Copy link
Contributor

I expect this issue will be irrelevant when MIR-only rlibs happen (is that still the plan?)

@bstrie
Copy link
Contributor

bstrie commented May 23, 2021

I expect this issue will be irrelevant when MIR-only rlibs happen

This is in reference to #38913 .

@workingjubilee
Copy link
Member

#38913 was closed, so this will probably remain relevant for a while. 🙃

@workingjubilee workingjubilee added the C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such label Oct 8, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 7, 2024
…able-externally, r=<try>

Default-enable share-generics, with available_externally to still allow inlining.

WIP, just experimenting, not clear whether this works for other codegen backends, or how practical of a tradeoff it is.

cc rust-lang#14527

r? `@Mark-Simulacrum` for now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation C-enhancement Category: An issue proposing an enhancement or a PR with one. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-compiletime Issue: Problems and improvements with respect to compile times. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants