-
Notifications
You must be signed in to change notification settings - Fork 13k
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
The rustc_query_impl
crate is too big, which hurts compile times for the compiler itself
#65031
Comments
If we look e.g. at |
On my windows box, crate |
One thing that would be nice to move back from librustc to librustc_mir is all the memory access logic of the Miri interpreter, which these days lives in |
Can those things not depend on librustc_mir, e.g., being dependencies of librustc_mir? Can @oli-obk comment on that perhaps? |
Most of the datastructures need to live there, because the incremental serializer lives there (though we could probably move both out) and because some of the interners intern types like I've tried a few times to split things out of librustc, it's just so entangled with everything that I failed. |
If it's just that we could use extension traits. |
Move def collector from `rustc` to `rustc_resolve` It's used only from `rustc_resolve`, so we can move it there, thus reducing the size of `rustc` (rust-lang#65031). It's quite possible that we can merge the def collector pass into the "build reduced graph" pass (they are always run together and do similar things), but it's some larger work. r? @eddyb
The way we should structure the compiler for compilation speed would be to have Currently I see that @Centril is kind of doing this already, but I think it would be a good idea to gain some compiler team sign-off here. The thing preventing moves of types tend to be inherent utility methods which require cc @rust-lang/compiler |
Another way to deal with |
Please let me know if you need help in this endeavour. |
…imulacrum Extract `rustc_ast_lowering` crate from `rustc` Working towards rust-lang#65031. This PR moves `src/librustc/hir/lowering{/, .rs}` to its own crate (`librustc_ast_lowering`) which is very self-contained (only `fn lower_crate` and `trait Resolver` are exposed). r? @Mark-Simulacrum
Extract `rustc_hir` out of `rustc` The new crate contains: ```rust pub mod def; pub mod def_id; mod hir; pub mod hir_id; pub mod itemlikevisit; pub mod pat_util; pub mod print; mod stable_hash_impls; pub use hir::*; pub use hir_id::*; pub use stable_hash_impls::HashStableContext; ``` Remains to be done in follow-up PRs: - Move `rustc::hir::map` into `rustc_hir_map` -- this has to be a separate crate due to the `dep_graph` (blocked on #67761). - Move references to `rustc::hir` to `rustc_hir` where possible. cc #65031 r? @Zoxc
rustc_middle
crate is too big, which hurts compile times for the compiler itselfrustc_query_impl
crate is too big, which hurts compile times for the compiler itself
Allow cleaning individual crates As a bonus, this stops special casing `clean` in `Builder`. ## Motivation Cleaning artifacts isn't strictly necessary to get cargo to rebuild; `touch compiler/rustc_driver/src/lib.rs` (for example) will also work. There's two reasons I thought making this part of bootstrap proper was a better approach: 1. `touch` does not *remove* artifacts, it just causes a rebuild. This is unhelpful for when you want to measure how long the compiler itself takes to build (e.g. for rust-lang#65031). 2. It seems a little more discoverable; and I want to extend it in the future to things like `x clean --stage 1 rustc`, which makes it easier to work around rust-lang#76720 without having to completely wipe all the stage 0 artifacts, or having to be intimately familiar with which directories to remove.
Here is the output of There are some very surprising things here: $ jq 'sort_by(.total_estimate) | .[-10:] | .[] | { name, total_estimate, instantiation_count }' rustc_query_impl.mono_items.json -c
{"name":"<plumbing::QueryCtxt<'_> as rustc_query_system::query::QueryContext>::start_query::{closure#0}","total_estimate":75240,"instantiation_count":684}
{"name":"std::ptr::mut_ptr::<impl *mut T>::is_null","total_estimate":77119,"instantiation_count":3353}
{"name":"std::ptr::const_ptr::<impl *const T>::is_aligned_to","total_estimate":79212,"instantiation_count":1722}
{"name":"plumbing::force_from_dep_node","total_estimate":84360,"instantiation_count":285}
{"name":"rustc_middle::ty::tls::with_context_opt","total_estimate":84747,"instantiation_count":1599}
{"name":"rustc_query_system::query::plumbing::execute_job","total_estimate":85728,"instantiation_count":228}
{"name":"rustc_query_system::dep_graph::DepGraph::<K>::with_task_impl","total_estimate":89148,"instantiation_count":228}
{"name":"rustc_query_system::query::plumbing::try_load_from_disk_and_cache_in_memory","total_estimate":102372,"instantiation_count":228}
{"name":"hashbrown::raw::RawTable::<T, A>::reserve_rehash","total_estimate":111354,"instantiation_count":277}
{"name":"std::thread::LocalKey::<T>::try_with","total_estimate":186412,"instantiation_count":3214}
|
…compile-time, r=thomcc Use some more `const_eval_select` in pointer methods for compile times Builds on top of rust-lang#105435 `is_aligned_to` is _huge_ with calling `align_offset`, so this should cut it down a lot. This shows up in rust-lang#65031 (comment)
…ime, r=thomcc Use some more `const_eval_select` in pointer methods for compile times Builds on top of #105435 `is_aligned_to` is _huge_ with calling `align_offset`, so this should cut it down a lot. This shows up in rust-lang/rust#65031 (comment)
Since #108638 rustc_query_impl takes significantly less time to compile and is no longer the limiting factor, at least for my setup: I'm going to close this issue as completed - there's always more perf work to do, but I think query_impl is now fast enough we don't have to single it out :) Thank you to everyone who worked on this! |
Looks like we are back to rustc_middle being the bottleneck, as was the case when this issue originally got created? ;)
|
Yes, but in a different way than before - now the bottleneck is generating metadata for rustc_middle, not performing codegen. |
@jyn514 Could you try a build with rust.codegen-units = 1? |
It's for benchmarking and LLVM IR inspection purposes. The total build time is similar for 16 and 1 CGUs for me on my Ryzen 7 1700. What are you building on? There seems to be a bit of a divergence in build behavior. |
I don't have time in the near future to investigate the difference, happy to reopen in the meantime. |
@jyn514 Did you build with |
ahhhh - yes, that's likely it. |
…ime, r=thomcc Use some more `const_eval_select` in pointer methods for compile times Builds on top of #105435 `is_aligned_to` is _huge_ with calling `align_offset`, so this should cut it down a lot. This shows up in rust-lang/rust#65031 (comment)
EDIT(Centril): The crate was renamed to
rustc_middle
in #70536.EDIT(jyn514): Most of rustc_middle was split into
rustc_query_impl
in #70951.The results from @ehuss's new
cargo -Ztimings
feature really drive home how the size of therustc
crate hurts compile times for the compiler. Here's a picture:Things to note.
rustc
crate takes about twice as long to compile as therustc_mir
crate, which is the second-biggest crate.rustc
crate's codegen is happening. (Thank goodness for pipelining, it really makes a difference in this case.)rustc
crate without anything else happening in parallel (from 42-67s, and from 141-174s).Also, even doing
check
builds onrustc
code is painful. On my fast 28-core Linux box it takes 10-15 seconds even for the first compile error to come up. This is much longer than other crates. Refactorings within therustc
crate that require many edit/compile cycles are painful.I've been told that
rustc
is quite tangled and splitting it up could be difficult. That may well be true. The good news is that the picture shows we don't need to split it into 10 equal-sized pieces to get benefits. Even splitting off small chunks into separate crates will have an outsized effect on compilation times.The text was updated successfully, but these errors were encountered: