Skip to content

Commit 6f228e3

Browse files
committed
Inline before merging CGUs.
Because CGU merging relies on CGU sizes, but the CGU sizes before inlining aren't accurate. This requires tweaking how the sizes are updated during merging: if CGU A and B both have an inlined function F, then `size(A + B)` will be a little less than `size(A) + size(B)`, because `A + B` will only have one copy of F. Also, the minimum CGU size is increased because it now has to account for inlined functions. This change doesn't have much effect on compile perf, but it makes follow-on changes that involve more sophisticated reasoning about CGU sizes much easier.
1 parent f6cadae commit 6f228e3

File tree

2 files changed

+14
-16
lines changed

2 files changed

+14
-16
lines changed

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,6 @@ impl<'tcx> CodegenUnit<'tcx> {
335335
.expect("create_size_estimate must be called before getting a size_estimate")
336336
}
337337

338-
pub fn modify_size_estimate(&mut self, delta: usize) {
339-
*self.size_estimate.as_mut().unwrap() += delta;
340-
}
341-
342338
pub fn contains_item(&self, item: &MonoItem<'tcx>) -> bool {
343339
self.items().contains_key(item)
344340
}

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,6 @@ where
166166
placed
167167
};
168168

169-
// Merge until we have at most `max_cgu_count` codegen units.
170-
// `merge_codegen_units` is responsible for updating the CGU size
171-
// estimates.
172-
{
173-
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
174-
merge_codegen_units(cx, &mut codegen_units);
175-
debug_dump(tcx, "MERGE", &codegen_units, unique_inlined_stats);
176-
}
177-
178169
// Use the usage map to put additional mono items in each codegen unit:
179170
// drop-glue, functions from external crates, and local functions the
180171
// definition of which is marked with `#[inline]`.
@@ -189,6 +180,15 @@ where
189180
debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
190181
}
191182

183+
// Merge until we have at most `max_cgu_count` codegen units.
184+
// `merge_codegen_units` is responsible for updating the CGU size
185+
// estimates.
186+
{
187+
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
188+
merge_codegen_units(cx, &mut codegen_units);
189+
debug_dump(tcx, "MERGE", &codegen_units, unique_inlined_stats);
190+
}
191+
192192
// Make as many symbols "internal" as possible, so LLVM has more freedom to
193193
// optimize.
194194
if !tcx.sess.link_dead_code() {
@@ -313,7 +313,7 @@ fn merge_codegen_units<'tcx>(
313313
// worse generated code. So we don't allow CGUs smaller than this (unless
314314
// there is just one CGU, of course). Note that CGU sizes of 100,000+ are
315315
// common in larger programs, so this isn't all that large.
316-
const NON_INCR_MIN_CGU_SIZE: usize = 1000;
316+
const NON_INCR_MIN_CGU_SIZE: usize = 1800;
317317

318318
// Repeatedly merge the two smallest codegen units as long as:
319319
// - we have more CGUs than the upper limit, or
@@ -337,9 +337,11 @@ fn merge_codegen_units<'tcx>(
337337
let mut smallest = codegen_units.pop().unwrap();
338338
let second_smallest = codegen_units.last_mut().unwrap();
339339

340-
// Move the mono-items from `smallest` to `second_smallest`
341-
second_smallest.modify_size_estimate(smallest.size_estimate());
340+
// Move the items from `smallest` to `second_smallest`. Some of them
341+
// may be duplicate inlined items, in which case the destination CGU is
342+
// unaffected. Recalculate size estimates afterwards.
342343
second_smallest.items_mut().extend(smallest.items_mut().drain());
344+
second_smallest.create_size_estimate(cx.tcx);
343345

344346
// Record that `second_smallest` now contains all the stuff that was
345347
// in `smallest` before.

0 commit comments

Comments
 (0)