Skip to content

Commit 427e630

Browse files
committed
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
1 parent de38f49 commit 427e630

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/librustc_mir/monomorphize/partitioning.rs

+11
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
377377
assert!(target_cgu_count >= 1);
378378
let codegen_units = &mut initial_partitioning.codegen_units;
379379

380+
// Note that at this point in time the `codegen_units` here may not be in a
381+
// deterministic order (but we know they're deterministically the same set).
382+
// We want this merging to produce a deterministic ordering of codegen units
383+
// from the input.
384+
//
385+
// Due to basically how we've implemented the merging below (merge the two
386+
// smallest into each other) we're sure to start off with a deterministic
387+
// order (sorted by name). This'll mean that if two cgus have the same size
388+
// the stable sort below will keep everything nice and deterministic.
389+
codegen_units.sort_by_key(|cgu| cgu.name().clone());
390+
380391
// Merge the two smallest codegen units until the target size is reached.
381392
// Note that "size" is estimated here rather inaccurately as the number of
382393
// translation items in a given unit. This could be improved on.

0 commit comments

Comments
 (0)