Skip to content

The rustc_query_impl crate is too big, which hurts compile times for the compiler itself #65031

Open

Description

@nnethercote

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:
a
Things to note.

  • The rustc crate takes about twice as long to compile as the rustc_mir crate, which is the second-biggest crate.
  • Sixteen dependent crates start and finish their entire compilation while the rustc crate'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 rustc crate 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

  1. petrochenkov commented on Oct 3, 2019

    @petrochenkov
    Contributor

    librustc still 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 to rustc_resolve, stability.rs - just a pass, can be moved to rustc_passes or something.

  2. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    I-compiletimeIssue: Problems and improvements with respect to compile times.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Oct 3, 2019
  3. crlf0710 commented on Oct 4, 2019

    @crlf0710
    Member

    On my windows box, crate rustc takes about 2000 seconds to build... Grateful to anything that makes the compilation process faster.

  4. RalfJung commented on Oct 12, 2019

    @RalfJung
    Member

    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.

  5. Mark-Simulacrum commented on Oct 12, 2019

    @Mark-Simulacrum
    Member

    Can those things not depend on librustc_mir, e.g., being dependencies of librustc_mir? Can @oli-obk comment on that perhaps?

  6. oli-obk commented on Oct 18, 2019

    @oli-obk
    Contributor

    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.

  7. RalfJung commented on Oct 18, 2019

    @RalfJung
    Member

    but we can't add inherent impls in downstream crates, so if we want inherent methods, we need to implement them there.

    If it's just that we could use extension traits.

  8. added a commit that references this issue on Nov 23, 2019
  9. Zoxc commented on Dec 24, 2019

    @Zoxc
    Contributor

    The way we should structure the compiler for compilation speed would be to have n independent crates defining types basically working as header files. Then we'd have a librustc_queries crates which just declares queries which depends on the n header crates. After that we'd fan out to m independent crates containing query definitions and other code.

    Currently n is 1 (libsyntax) and way too much stuff is in librustc which prevents the m crates from starting sooner. I think it would make sense to move types from librustc into crates which librustc can depend on and code from librustc into crates which depends on librustc.

    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 of TyCtxt in librustc except for the query system and then extract the query system into librustc_queries.

    cc @rust-lang/compiler

  10. Zoxc commented on Dec 24, 2019

    @Zoxc
    Contributor

    Another way to deal with TyCtxt would be to have a QueryCtxt trait in each crate and use impl QueryCtxt instead of TyCtxt for the utility methods in these crates. Maybe we could even remove the dependency on librustc_queries for some crates that way?

  11. Zoxc commented on Dec 24, 2019

    @Zoxc
    Contributor

    I ran -Ztimings too on Windows: Results.

    It seems like rustc_driver is taking very long here, probably linker related. We can however see that libsyntax is much shorter after @Centril's changes.

    Here is also a check build.

    02.02.2020 timings.
    27.03.2020 timings.

  12. cjgillot commented on Dec 26, 2019

    @cjgillot
    Contributor

    Please let me know if you need help in this endeavour.

  13. 73 remaining items

  14. jyn514 commented on May 24, 2023

    @jyn514
    Member

    Since #108638 rustc_query_impl takes significantly less time to compile and is no longer the limiting factor, at least for my setup:
    image

    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!

  15. RalfJung commented on May 25, 2023

    @RalfJung
    Member
  16. jyn514 commented on May 25, 2023

    @jyn514
    Member

    Yes, but in a different way than before - now the bottleneck is generating metadata for rustc_middle, not performing codegen.

  17. Zoxc commented on May 25, 2023

    @Zoxc
    Contributor

    @jyn514 Could you try a build with rust.codegen-units = 1? rustc_query_impl is still holding things up slightly for me.

  18. jyn514 commented on May 25, 2023

    @jyn514
    Member

    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.
    image

  19. Zoxc commented on May 25, 2023

    @Zoxc
    Contributor

    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.

  20. jyn514 commented on May 26, 2023

    @jyn514
    Member

    I don't have time in the near future to investigate the difference, happy to reopen in the meantime.

  21. reopened this on May 26, 2023
  22. Zoxc commented on May 27, 2023

    @Zoxc
    Contributor

    @jyn514 Did you build with rust.lto set to thin-local or off? I built with thin-local, and off is the new compiler profile default, so that could explain the divergence.

  23. jyn514 commented on May 27, 2023

    @jyn514
    Member

    ahhhh - yes, that's likely it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-contributor-roadblockArea: Makes things more difficult for new or seasoned contributors to RustA-query-systemArea: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html)C-enhancementCategory: An issue proposing an enhancement or a PR with one.I-compiletimeIssue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions