Skip to content

Commit 0bbc9fa

Browse files
committed
for a more even partitioning inline before merge
consider the size of the inlined items for a more even partitioning
1 parent e369d87 commit 0bbc9fa

File tree

1 file changed

+30
-43
lines changed

1 file changed

+30
-43
lines changed

src/librustc_mir/monomorphize/partitioning.rs

+30-43
Original file line numberDiff line numberDiff line change
@@ -139,23 +139,13 @@ where
139139
// In the first step, we place all regular monomorphizations into their
140140
// respective 'home' codegen unit. Regular monomorphizations are all
141141
// functions and statics defined in the local crate.
142-
let mut initial_partitioning = {
142+
let initial_partitioning = {
143143
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
144144
place_root_mono_items(tcx, mono_items)
145145
};
146146

147-
initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx));
148-
149147
debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter());
150148

151-
// If the partitioning should produce a fixed count of codegen units, merge
152-
// until that count is reached.
153-
if let PartitioningStrategy::FixedUnitCount(count) = strategy {
154-
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
155-
merge_codegen_units(tcx, &mut initial_partitioning, count);
156-
debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
157-
}
158-
159149
// In the next step, we use the inlining map to determine which additional
160150
// monomorphizations have to go into each codegen unit. These additional
161151
// monomorphizations can be drop-glue, functions from external crates, and
@@ -170,6 +160,14 @@ where
170160

171161
debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter());
172162

163+
// If the partitioning should produce a fixed count of codegen units, merge
164+
// until that count is reached.
165+
if let PartitioningStrategy::FixedUnitCount(count) = strategy {
166+
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
167+
merge_codegen_units(tcx, &mut post_inlining, count);
168+
debug_dump(tcx, "POST MERGING:", post_inlining.codegen_units.iter());
169+
}
170+
173171
// Next we try to make as many symbols "internal" as possible, so LLVM has
174172
// more freedom to optimize.
175173
if !tcx.sess.opts.cg.link_dead_code {
@@ -181,7 +179,6 @@ where
181179
// Finally, sort by codegen unit name, so that we get deterministic results.
182180
let PostInliningPartitioning {
183181
codegen_units: mut result,
184-
mono_item_placements: _,
185182
internalization_candidates: _,
186183
} = post_inlining;
187184

@@ -209,7 +206,6 @@ enum MonoItemPlacement {
209206

210207
struct PostInliningPartitioning<'tcx> {
211208
codegen_units: Vec<CodegenUnit<'tcx>>,
212-
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
213209
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
214210
}
215211

@@ -477,11 +473,11 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
477473

478474
fn merge_codegen_units<'tcx>(
479475
tcx: TyCtxt<'tcx>,
480-
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
476+
partitioning: &mut PostInliningPartitioning<'tcx>,
481477
target_cgu_count: usize,
482478
) {
483479
assert!(target_cgu_count >= 1);
484-
let codegen_units = &mut initial_partitioning.codegen_units;
480+
let codegen_units = &mut partitioning.codegen_units;
485481

486482
// Note that at this point in time the `codegen_units` here may not be in a
487483
// deterministic order (but we know they're deterministically the same set).
@@ -501,10 +497,10 @@ fn merge_codegen_units<'tcx>(
501497
let mut smallest = codegen_units.pop().unwrap();
502498
let second_smallest = codegen_units.last_mut().unwrap();
503499

504-
second_smallest.modify_size_estimate(smallest.size_estimate());
505500
for (k, v) in smallest.items_mut().drain() {
506501
second_smallest.items_mut().insert(k, v);
507502
}
503+
second_smallest.estimate_size(tcx);
508504
debug!("CodegenUnit {} merged in to CodegenUnit {}",
509505
smallest.name(),
510506
second_smallest.name());
@@ -520,16 +516,13 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning<
520516
inlining_map: &InliningMap<'tcx>)
521517
-> PostInliningPartitioning<'tcx> {
522518
let mut new_partitioning = Vec::new();
523-
let mut mono_item_placements = FxHashMap::default();
524519

525520
let PreInliningPartitioning {
526521
codegen_units: initial_cgus,
527522
roots,
528523
internalization_candidates,
529524
} = initial_partitioning;
530525

531-
let single_codegen_unit = initial_cgus.len() == 1;
532-
533526
for old_codegen_unit in initial_cgus {
534527
// Collect all items that need to be available in this codegen unit.
535528
let mut reachable = FxHashSet::default();
@@ -556,36 +549,13 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning<
556549
(Linkage::Internal, Visibility::Default),
557550
);
558551
}
559-
560-
if !single_codegen_unit {
561-
// If there is more than one codegen unit, we need to keep track
562-
// in which codegen units each monomorphization is placed.
563-
match mono_item_placements.entry(mono_item) {
564-
Entry::Occupied(e) => {
565-
let placement = e.into_mut();
566-
debug_assert!(match *placement {
567-
MonoItemPlacement::SingleCgu { ref cgu_name } => {
568-
*cgu_name != *new_codegen_unit.name()
569-
}
570-
MonoItemPlacement::MultipleCgus => true,
571-
});
572-
*placement = MonoItemPlacement::MultipleCgus;
573-
}
574-
Entry::Vacant(e) => {
575-
e.insert(MonoItemPlacement::SingleCgu {
576-
cgu_name: new_codegen_unit.name().clone()
577-
});
578-
}
579-
}
580-
}
581552
}
582553

583554
new_partitioning.push(new_codegen_unit);
584555
}
585556

586557
return PostInliningPartitioning {
587558
codegen_units: new_partitioning,
588-
mono_item_placements,
589559
internalization_candidates,
590560
};
591561

@@ -632,7 +602,24 @@ fn internalize_symbols<'tcx>(
632602
}
633603
});
634604

635-
let mono_item_placements = &partitioning.mono_item_placements;
605+
// If there is more than one codegen unit, we need to keep track
606+
// in which codegen units each monomorphization is placed.
607+
let mut mono_item_placements = FxHashMap::default();
608+
609+
for cgu in &partitioning.codegen_units {
610+
for mono_item in cgu.items().keys() {
611+
match mono_item_placements.entry(*mono_item) {
612+
Entry::Occupied(e) => {
613+
*e.into_mut() = MonoItemPlacement::MultipleCgus;
614+
}
615+
Entry::Vacant(e) => {
616+
e.insert(MonoItemPlacement::SingleCgu {
617+
cgu_name: cgu.name().clone()
618+
});
619+
}
620+
}
621+
}
622+
}
636623

637624
// For each internalization candidates in each codegen unit, check if it is
638625
// accessed from outside its defining codegen unit.

0 commit comments

Comments
 (0)