-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
serde compilation is not deterministic #46846
Comments
Looking into this a bit. I had to run the build a few times but eventually was able to reproduce as well (on stable, but nightly also seems affected) I found that the
Emitting the LLVM IR for all the stages yields two diffs: Looks like those objects files may have been swapped! cc @michaelwoerister, is this perhaps related to the partitioning code? Can you think of anything that may cause two codegen units to be swapped between two compilations? I also have a sinking feeling this may have been introduced with the thinlto work... |
Maybe this code can introduce instabilities if there are codegen units with the same number of trans items in them?: rust/src/librustc_mir/monomorphize/partitioning.rs Lines 374 to 397 in de38f49
|
A minimal reproduction of this locally for me is: pub fn foo(bar: &str) {
bar.find('\n');
} When compiled with |
This commit fixes some nondeterminism in compilation when using multiple codegen units. The algorithm for splitting codegen units currently takes the otherwise-would-be-for-incremental partitioning and then continuously merges the two smallest codegen units until the desired number of codegen units are reached. We want to be sure to merge the same codegen units each time a compilation is run but there's some subtle reorderings amongst all the items which was causing this step to be slightly buggy. Notably this step involves sorting codegen units by size, but if two codegen units had the same size they would appear in different locations in the list each time. This commit fixes this issue by sorting codegen units by name before doing the loop to merge the two smallest. This means that we've got a deterministic order going in and since we're using a stable sort this should mean that we're always now getting a deterministic merging of codegen units. Closes rust-lang#46846
…lwoerister rustc: Sort CGUs before merging This commit fixes some nondeterminism in compilation when using multiple codegen units. The algorithm for splitting codegen units currently takes the otherwise-would-be-for-incremental partitioning and then continuously merges the two smallest codegen units until the desired number of codegen units are reached. We want to be sure to merge the same codegen units each time a compilation is run but there's some subtle reorderings amongst all the items which was causing this step to be slightly buggy. Notably this step involves sorting codegen units by size, but if two codegen units had the same size they would appear in different locations in the list each time. This commit fixes this issue by sorting codegen units by name before doing the loop to merge the two smallest. This means that we've got a deterministic order going in and since we're using a stable sort this should mean that we're always now getting a deterministic merging of codegen units. Closes rust-lang#46846
I was looking into why sccache was missing more than expected, and it looks like serde_derive compiles are not deterministic.
I tried this code on OSX 10.12 (Xcode 7.3.1)
I expected that the MD5s would be identical after deleting and re-running cargo build. I ran with just the underlying
rustc
command, and that also generated different files each time. Here is the underlying rustc command:rustc --crate-name serde_derive serde_derive/src/lib.rs --crate-type proc-macro --emit=dep-info,link -C prefer-dynamic -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="deserialize_from"' -C metadata=c403614b534b4e94 -C extra-filename=-c403614b534b4e94 --out-dir /Users/jklai/serde/target/debug/deps -L dependency=/Users/jklai/serde/target/debug/deps --extern syn=/Users/jklai/serde/target/debug/deps/libsyn-b667971f1cdadd98.rlib --extern quote=/Users/jklai/serde/target/debug/deps/libquote-34dfebedcb580111.rlib --extern serde_derive_internals=/Users/jklai/serde/target/debug/deps/libserde_derive_internals-3788ef8c57ed9e45.rlib
I have also tried this on Windows and Linux, and it also generates different serde_derive libraries when rebuilding.
Meta
rustc --version --verbose
: rustc 1.24.0-nightly (dc39c31 2017-12-17)The text was updated successfully, but these errors were encountered: