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

rustc generates a lot of llvm ir for small programs due to inline generated drops #38827

Open
jrmuizel opened this issue Jan 4, 2017 · 14 comments
Labels
A-codegen Area: Code generation A-destructors Area: Destructors (`Drop`, …) 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. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jrmuizel
Copy link
Contributor

jrmuizel commented Jan 4, 2017

Building https://github.com/jrmuizel/webrender/blob/sample-min/sample-min/src/main.rs ends up generating 12MB of LLVM IR (25MB of LLVM IR with debug info turned on). This seems like an excessive amount and it has a big impact on build times.

@jonas-schievink
Copy link
Contributor

webrender marks a lot of functions as #[inline] for performance, which causes their IR to be included in your crate. #[inline] has always been problematic for build times.

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Jan 4, 2017

But shouldn't those inline functions only be emitted if they are used by main.rs?

@RReverser
Copy link
Contributor

@jrmuizel I think you need to use lto = true for final binary if you want such cross-crate optimizations (dead line code elimination, inlining etc.) to happen correctly.

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Jan 4, 2017

I'm not really looking for cross-crate optimizations so lto seems inappropriate.

Why do we need to re-emit the ir for unused inline functions? How could these functions ever be used?

@jonas-schievink
Copy link
Contributor

They are used by the functions used by main.rs. All inline-functions transitively used by your code will be included in the crate's LLVM module IIRC. This gives LLVM the ability to inline all of them (if it decides to do so) into your code.

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Jan 5, 2017

So it looks like the bulk of this code is from the drop function implementations. i.e. mem::forgetting the return values from renderer::Renderer::new(opts) and compiling with -C panic=abort drops the IR size to 1.3MB. Is there a reason the drop functions need to be inline?

@RReverser
Copy link
Contributor

I'm not really looking for cross-crate optimizations so lto seems inappropriate.
Why do we need to re-emit the ir for unused inline functions?

Well, you're looking for dead code elimination (not emitting functions from other crate that are unused), so you do want cross-crate optimization.

@bluss
Copy link
Member

bluss commented Jan 5, 2017

One reason is that automatically generated drop (like for Renderer) can not be marked inline explicitly, so it would limit programs to not have them inlineable by default.

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Jan 5, 2017

It seems like we could avoid having inline generated drop functions in debug builds though.

@jrmuizel jrmuizel changed the title rustc generates a lot of llvm ir for small programs rustc generates a lot of llvm ir for small programs due to inline generated drops Jan 5, 2017
@jrmuizel
Copy link
Contributor Author

jrmuizel commented Apr 5, 2017

It looks like the majority of the code is being added because of monomorphization caused by the inline drop.

@Mark-Simulacrum Mark-Simulacrum added I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 20, 2017
@jrmuizel
Copy link
Contributor Author

running RUST_LOG=rustc_trans rustc on this example shows 4614 functions being translated. I wonder if it would be pursuing polymorphic code gen so that we don't get hammered with monomorphization.

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 26, 2017
@jonas-schievink jonas-schievink added A-codegen Area: Code generation A-destructors Area: Destructors (`Drop`, …) labels Jan 31, 2020
@scottmcm
Copy link
Member

This codegen test suggests that drop glue is not marked for inlining by default:
4ea25da#diff-d13eb81c7eec73d0e1f5f62e9c15e987b7fac6b90e1924401152d1146200b92fR1-R2

@jrmuizel
Copy link
Contributor Author

Indeed. As I understand it, the problem is not that code is marked as inline it's that it's generic code that gets a monomorphized version generated for it instead of sharing it. See #68414 and #84175

@jrmuizel
Copy link
Contributor Author

jrmuizel commented May 15, 2022

More specifically, for an example like:

struct A(String);

fn a(_: A) {}

becomes something like:

a(x: A) {
   core::ptr::drop_in_place::<A>(&x);
}

which even though it's not being inlined gets codegened in place because of monomorphization.

@workingjubilee workingjubilee added the C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such label Oct 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-destructors Area: Destructors (`Drop`, …) 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. 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