Skip to content

Commit 9db09fa

Browse files
committed
improve cgu schedule with greedy partition
1 parent 0c2c243 commit 9db09fa

File tree

1 file changed

+27
-23
lines changed

1 file changed

+27
-23
lines changed

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,13 @@ fn merge_codegen_units<'tcx>(
309309
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
310310
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
311311

312+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
312313
// Having multiple CGUs can drastically speed up compilation. But for
313314
// non-incremental builds, tiny CGUs slow down compilation *and* result in
314315
// worse generated code. So we don't allow CGUs smaller than this (unless
315316
// there is just one CGU, of course). Note that CGU sizes of 100,000+ are
316317
// common in larger programs, so this isn't all that large.
317-
const NON_INCR_MIN_CGU_SIZE: usize = 1000;
318+
//const NON_INCR_MIN_CGU_SIZE: usize = 1000;
318319

319320
// Repeatedly merge the two smallest codegen units as long as:
320321
// - we have more CGUs than the upper limit, or
@@ -326,36 +327,39 @@ fn merge_codegen_units<'tcx>(
326327
// the `compiler_builtins` crate sets `codegen-units = 10000` and it's
327328
// critical they aren't merged. Also, some tests use explicit small values
328329
// and likewise won't work if small CGUs are merged.
329-
while codegen_units.len() > cx.tcx.sess.codegen_units().as_usize()
330+
331+
if codegen_units.len() > cx.tcx.sess.codegen_units().as_usize()
330332
|| (cx.tcx.sess.opts.incremental.is_none()
331333
&& matches!(cx.tcx.sess.codegen_units(), CodegenUnits::Default(_))
332-
&& codegen_units.len() > 1
333-
&& codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE))
334+
&& codegen_units.len() > 1)
334335
{
335336
// Sort small cgus to the back.
336337
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
338+
let fallback_cgu_name = fallback_cgu_name(cgu_name_builder);
339+
let mut merged_subsets: Vec<CodegenUnit<'_>> =
340+
vec![CodegenUnit::new(fallback_cgu_name); cx.tcx.sess.codegen_units().as_usize()];
337341

338-
let mut smallest = codegen_units.pop().unwrap();
339-
let second_smallest = codegen_units.last_mut().unwrap();
340-
341-
// Move the mono-items from `smallest` to `second_smallest`
342-
second_smallest.modify_size_estimate(smallest.size_estimate());
343-
second_smallest.items_mut().extend(smallest.items_mut().drain());
344-
345-
// Record that `second_smallest` now contains all the stuff that was
346-
// in `smallest` before.
347-
let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
348-
cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
349-
350-
debug!(
351-
"CodegenUnit {} merged into CodegenUnit {}",
352-
smallest.name(),
353-
second_smallest.name()
354-
);
342+
for cgu in codegen_units.iter_mut() {
343+
let min = merged_subsets
344+
.iter()
345+
.enumerate()
346+
.min_by_key(|(_, cgu)| cgu.size_estimate())
347+
.map(|(i, _)| i)
348+
.unwrap_or(0);
349+
let min_cgu = &mut merged_subsets[min];
350+
if min_cgu.name() == fallback_cgu_name {
351+
*min_cgu = std::mem::replace(cgu, CodegenUnit::new(fallback_cgu_name));
352+
} else {
353+
min_cgu.modify_size_estimate(cgu.size_estimate());
354+
min_cgu.items_mut().extend(cgu.items_mut().drain());
355+
let mut consumed_cgu_names = cgu_contents.remove(&cgu.name()).unwrap();
356+
cgu_contents.get_mut(&min_cgu.name()).unwrap().append(&mut consumed_cgu_names);
357+
debug!("CodegenUnit {} merged into CodegenUnit {}", cgu.name(), min_cgu.name());
358+
}
359+
}
360+
*codegen_units = merged_subsets;
355361
}
356362

357-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
358-
359363
if cx.tcx.sess.opts.incremental.is_some() {
360364
// If we are doing incremental compilation, we want CGU names to
361365
// reflect the path of the source level module they correspond to.

0 commit comments

Comments
 (0)