-
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
Clear incremental cache when stage1 compiler is rebuilt #86641
Conversation
This comment has been minimized.
This comment has been minimized.
FWIW I already did that years ago and it (mostly) works fine.^^ |
@RalfJung how's this - x.py has the info itself to know if it did a rebuild or not. If it rebuilds the stage 1 compiler, it can force off incremental when building with it; otherwise, |
Doesn't that still have the problem that the first build of stage 1 will be without incremental, and then rebuilds will be with incremental but there's no incremental cache (and I have no idea what that does)? I think there's two different problems here, and they probably have different solutions:
Then people can set Maybe |
@RalfJung I like the idea of wiping the cache instead of forcing incremental to off, that seems more correct. I don't see why |
Last time I tried (which is to say more than a year ago), the initial incremental build was significantly slower than a non-incremental build -- certainly >10%. So that seems like time well saved when you usually can't make use of that incremental cache anyway. |
Hmm, ok. I'm not necessarily opposed to that but I don't think the change should happen here. The UI I imagine is we add new |
If the point of this PR is to fix the ICE (the first item on my list), then I agree that this is orthogonal. |
Disabling incremental seems like a patch that would work, but it doesn't seem like the right approach. Rustbuild should already be clearing the output directory on changes to the rustc binary (and that should include incremental state), and if we're not we would expect to see other bugs crop up (e.g., reuse unrelated to incremental is also wrong). I think the actual bug is that Lines 1080 to 1081 in 17ea490
It's pretty likely that there's not a dependency edge in Cargo from the incremental state to std/core (for "obvious" reasons; this is desirable in the general case as you want to avoid clearing out incremental state when rebuilding due to changes in dependencies as you might be able to save work in theory). So what we probably need to do in rustbuild is to clear out the incremental directory ourselves on changes to rustc, via a line similar to the one linked above. I think this patch as-is would likely help with the majority of the ICEs as it'll disable incremental in stage 1, but it won't help when we bump the bootstrap compiler with the incremental state in stage 0, for example. Probably what we want is:
|
Bumping the bootstrap compiler will give us different hashes, because even with
👍 |
Hm, it's certainly true that we've bumped bootstrap compilers within a cycle before (where the version number wouldn't change; beta releases are separately numbered IIRC with a -beta.X). I'm not sure if that's enough to force separate caching; it seems like a good idea to add a test to cargo ensuring it's enough to change -vV output without changing the binary being run (when rustc is replaced by a wrapper). |
Oh - I don't think
Sure, I can test this, but why |
Changing the version while keeping the name of the wrapper the same does indeed rebuild.
|
0d924b7
to
202ae35
Compare
I changed this to implement 1, which should fix the ICEs (and works well with |
This comment has been minimized.
This comment has been minimized.
Sounds reasonable to me. Could you update the PR title and description? |
src/bootstrap/builder.rs
Outdated
@@ -1079,7 +1079,7 @@ impl<'a> Builder<'a> { | |||
// | |||
// Only clear out the directory if we're compiling std; otherwise, we | |||
// should let Cargo take care of things for us (via depdep info) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update this comment, too.
I am a little wary of making this change -- IIRC, and based on description of the commit that added this, it was quite intentional to limit it so harshly in #67760... but presuming we don't get a scattering of bug reports, it seems like we could do this.
I think one thing we can do, in theory, is not do this if we're not using incremental, but that seems worse to me right now. If we start getting bug reports due to extra rebuilds that users don't expect, then we can revisit this decision and figure out a more targeted fix. AFAICT, it should only be necessary to clear out the incremental state for rustc, while this targets all output directories (in build/check invocations). My guess is that will lead to some problems, but we'll see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update this comment, too.
Sure, done.
I think one thing we can do, in theory, is not do this if we're not using incremental, but that seems worse to me right now.
Hmm, that makes sense to me. Do you want me to do that now? I think the only case this can cause bugs is when using incremental; or I guess if cargo assumes that output artifacts are the same. Not sure when that could happen though.
This avoids incremental ICEs when building with stage 1 (see 76720). This also checks for `check`, since `x.py check --stage 1` could also hit the same issue (now that `check` supports a --stage argument).
I was going to suggest a re-write of the comment in this code, but I actually now think that this is possibly the wrong fix. Currently, it looks like rustc does not emit incremental files as outputs into the depinfo it gives Cargo. I think that's actually the reason compiler builds break here -- Cargo isn't deleting those output files prior to running rustc, because it doesn't know about them. If we fix the code here to include incremental output files in the output paths list, I think that should fix this without needing changes to bootstrap, which seems preferable. I'm not sure if this suggestion would cause other problems, but it seems loosely like a better idea than just deleting the whole compiler/ directory. This would, I believe, also avoid rebuilding the whole compiler on changes to libtest (with keep-stage to limit to a single stage build) since there isn't a dependency edge between libtest and most compiler crates. That seems like a good feature to keep. We still need to delete std as there's not a dependency edge from std crates to the real compiler file known to Cargo, but that is already the behavior on master. |
FYI: I am not planning to work on this until I have a way to replicate the build failures, since I don't trust my understanding of incremental enough to just "eyeball" it like I was doing before. If someone can come up with a series of git + x.py commands that reproduces a stage1 ICE, that would be helpful. |
I won't have time to work on this in the near future. |
Previously, this would cause ICEs because the stage1 compiler would see incremental state from a different compiler with a different ABI.
As a performance optimization, it might be possible to turn incremental off by default for stage1 builds, which would speed them up in the common case where the compiler is rebuilt. But that seems complicated and I don't have time to work on it at the moment.
Closes #76720.
r? @Mark-Simulacrum
cc @rust-lang/compiler @rust-lang/compiler-contributors: this should allow you to see
incremental = true
unconditionally in config.toml, modulo any remaining bugs in incremental.