about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-12-22 02:50:59 +0800
committerkennytm <kennytm@gmail.com>2017-12-22 05:00:41 +0800
commit0787ad92614df48096dbb5cbd6f2cf7833c97293 (patch)
tree38b95e40adadf6e894c6389fab4f13613b370a61
parentb60e6f82855d387c0ad98179c33e6c019e8a7d26 (diff)
parent427e6308bcb1e47d253848b35bef051151a3212c (diff)
downloadrust-0787ad92614df48096dbb5cbd6f2cf7833c97293.tar.gz
rust-0787ad92614df48096dbb5cbd6f2cf7833c97293.zip
Rollup merge of #46918 - alexcrichton:fix-ordering, r=michaelwoerister
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 #46846
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index e2640d695c6..b1fef274cba 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -377,6 +377,17 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
     assert!(target_cgu_count >= 1);
     let codegen_units = &mut initial_partitioning.codegen_units;
 
+    // Note that at this point in time the `codegen_units` here may not be in a
+    // deterministic order (but we know they're deterministically the same set).
+    // We want this merging to produce a deterministic ordering of codegen units
+    // from the input.
+    //
+    // Due to basically how we've implemented the merging below (merge the two
+    // smallest into each other) we're sure to start off with a deterministic
+    // order (sorted by name). This'll mean that if two cgus have the same size
+    // the stable sort below will keep everything nice and deterministic.
+    codegen_units.sort_by_key(|cgu| cgu.name().clone());
+
     // Merge the two smallest codegen units until the target size is reached.
     // Note that "size" is estimated here rather inaccurately as the number of
     // translation items in a given unit. This could be improved on.