Repository navigation
The rustc_query_impl crate is too big, which hurts compile times for the compiler itself #65031
Description
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 the rustc crate hurts compile times for the compiler. Here's a picture:

Things to note.
- The
rustccrate takes about twice as long to compile as therustc_mircrate, which is the second-biggest crate. - Sixteen dependent crates start and finish their entire compilation while the
rustccrate's codegen is happening. (Thank goodness for pipelining, it really makes a difference in this case.) - Almost 1/3 of the total build time occurs while building the
rustccrate without anything else happening in parallel (from 42-67s, and from 141-174s).
Also, even doing check builds on rustc 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 the rustc 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.
Activity
petrochenkov commentedon Oct 3, 2019
librustcstill has a lot of code that's "just implementation code" and not something infrastructural like types or traits used in the rest of the compiler.If we look e.g. at
rustc/middle:resolve_lifetime.rs- just a pass, can be moved torustc_resolve,stability.rs- just a pass, can be moved torustc_passesor something.crlf0710 commentedon Oct 4, 2019
On my windows box, crate
rustctakes about 2000 seconds to build... Grateful to anything that makes the compilation process faster.RalfJung commentedon Oct 12, 2019
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
librustc::mir::interpret::allocation. But @oli-obk moved it there because it is used by things that do not depend on librustc_mir, so I am not sure what it would take to make that happen.Mark-Simulacrum commentedon Oct 12, 2019
Can those things not depend on librustc_mir, e.g., being dependencies of librustc_mir? Can @oli-obk comment on that perhaps?
oli-obk commentedon Oct 18, 2019
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
Allocation. I'm not sure how much of the code is needed there, but we can't add inherent impls in downstream crates, so if we want inherent methods, we need to implement them there.I've tried a few times to split things out of librustc, it's just so entangled with everything that I failed.
RalfJung commentedon Oct 18, 2019
If it's just that we could use extension traits.
Rollup merge of rust-lang#66673 - petrochenkov:toresolve, r=Centril
Zoxc commentedon Dec 24, 2019
The way we should structure the compiler for compilation speed would be to have
nindependent crates defining types basically working as header files. Then we'd have alibrustc_queriescrates which just declares queries which depends on thenheader crates. After that we'd fan out tomindependent crates containing query definitions and other code.Currently
nis 1 (libsyntax) and way too much stuff is inlibrustcwhich prevents themcrates from starting sooner. I think it would make sense to move types fromlibrustcinto crates whichlibrustccan depend on and code fromlibrustcinto crates which depends onlibrustc.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
TyCtxt. Maybe we could move these to extension traits instead? (with maybe a prelude for these?) One goal could be to remove all uses ofTyCtxtinlibrustcexcept for the query system and then extract the query system intolibrustc_queries.cc @rust-lang/compiler
Zoxc commentedon Dec 24, 2019
Another way to deal with
TyCtxtwould be to have aQueryCtxttrait in each crate and useimpl QueryCtxtinstead ofTyCtxtfor the utility methods in these crates. Maybe we could even remove the dependency onlibrustc_queriesfor some crates that way?Zoxc commentedon Dec 24, 2019
I ran
-Ztimingstoo on Windows: Results.It seems like
rustc_driveris taking very long here, probably linker related. We can however see thatlibsyntaxis much shorter after @Centril's changes.Here is also a check build.
02.02.2020 timings.
27.03.2020 timings.
cjgillot commentedon Dec 26, 2019
Please let me know if you need help in this endeavour.
73 remaining items
jyn514 commentedon May 24, 2023
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!
RalfJung commentedon May 25, 2023
jyn514 commentedon May 25, 2023
Yes, but in a different way than before - now the bottleneck is generating metadata for rustc_middle, not performing codegen.
Zoxc commentedon May 25, 2023
@jyn514 Could you try a build with rust.codegen-units = 1?
rustc_query_implis still holding things up slightly for me.jyn514 commentedon May 25, 2023
Hmm, do you have codegen-units=1 set for local benchmarking or some other reason?
Here's the graph with 1 CGU - I do see query_impl causing a slight delay now.

Zoxc commentedon May 25, 2023
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.
jyn514 commentedon May 26, 2023
I don't have time in the near future to investigate the difference, happy to reopen in the meantime.
Zoxc commentedon May 27, 2023
@jyn514 Did you build with
rust.ltoset tothin-localoroff? I built withthin-local, andoffis the new compiler profile default, so that could explain the divergence.jyn514 commentedon May 27, 2023
ahhhh - yes, that's likely it.
Auto merge of #106275 - Nilstrieb:const-eval-select-me-some-compile-t…