Skip to content

Commit 105ac1c

Browse files
committed
Merge root and inlined item placement.
There's no longer any need for them to be separate, and putting them together reduces the amount of code.
1 parent 6f228e3 commit 105ac1c

File tree

1 file changed

+44
-71
lines changed

1 file changed

+44
-71
lines changed

compiler/rustc_monomorphize/src/partitioning.rs

+44-71
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ struct PartitioningCx<'a, 'tcx> {
125125
usage_map: &'a UsageMap<'tcx>,
126126
}
127127

128-
struct PlacedRootMonoItems<'tcx> {
128+
struct PlacedMonoItems<'tcx> {
129129
/// The codegen units, sorted by name to make things deterministic.
130130
codegen_units: Vec<CodegenUnit<'tcx>>,
131131

@@ -150,36 +150,20 @@ where
150150

151151
let cx = &PartitioningCx { tcx, usage_map };
152152

153-
// In the first step, we place all regular monomorphizations into their
154-
// respective 'home' codegen unit. Regular monomorphizations are all
155-
// functions and statics defined in the local crate.
156-
let PlacedRootMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
157-
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
158-
let mut placed = place_root_mono_items(cx, mono_items);
153+
// Place all mono items into a codegen unit.
154+
let PlacedMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
155+
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_items");
156+
let mut placed = place_mono_items(cx, mono_items);
159157

160158
for cgu in &mut placed.codegen_units {
161159
cgu.create_size_estimate(tcx);
162160
}
163161

164-
debug_dump(tcx, "ROOTS", &placed.codegen_units, placed.unique_inlined_stats);
162+
debug_dump(tcx, "PLACE", &placed.codegen_units, placed.unique_inlined_stats);
165163

166164
placed
167165
};
168166

169-
// Use the usage map to put additional mono items in each codegen unit:
170-
// drop-glue, functions from external crates, and local functions the
171-
// definition of which is marked with `#[inline]`.
172-
{
173-
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
174-
place_inlined_mono_items(cx, &mut codegen_units);
175-
176-
for cgu in &mut codegen_units {
177-
cgu.create_size_estimate(tcx);
178-
}
179-
180-
debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
181-
}
182-
183167
// Merge until we have at most `max_cgu_count` codegen units.
184168
// `merge_codegen_units` is responsible for updating the CGU size
185169
// estimates.
@@ -211,10 +195,7 @@ where
211195
codegen_units
212196
}
213197

214-
fn place_root_mono_items<'tcx, I>(
215-
cx: &PartitioningCx<'_, 'tcx>,
216-
mono_items: I,
217-
) -> PlacedRootMonoItems<'tcx>
198+
fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> PlacedMonoItems<'tcx>
218199
where
219200
I: Iterator<Item = MonoItem<'tcx>>,
220201
{
@@ -235,6 +216,8 @@ where
235216
let mut num_unique_inlined_items = 0;
236217
let mut unique_inlined_items_size = 0;
237218
for mono_item in mono_items {
219+
// Handle only root items directly here. Inlined items are handled at
220+
// the bottom of the loop based on reachability.
238221
match mono_item.instantiation_mode(cx.tcx) {
239222
InstantiationMode::GloballyShared { .. } => {}
240223
InstantiationMode::LocalCopy => {
@@ -247,7 +230,7 @@ where
247230
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
248231
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
249232

250-
let codegen_unit_name = match characteristic_def_id {
233+
let cgu_name = match characteristic_def_id {
251234
Some(def_id) => compute_codegen_unit_name(
252235
cx.tcx,
253236
cgu_name_builder,
@@ -258,9 +241,7 @@ where
258241
None => fallback_cgu_name(cgu_name_builder),
259242
};
260243

261-
let codegen_unit = codegen_units
262-
.entry(codegen_unit_name)
263-
.or_insert_with(|| CodegenUnit::new(codegen_unit_name));
244+
let cgu = codegen_units.entry(cgu_name).or_insert_with(|| CodegenUnit::new(cgu_name));
264245

265246
let mut can_be_internalized = true;
266247
let (linkage, visibility) = mono_item_linkage_and_visibility(
@@ -273,23 +254,52 @@ where
273254
internalization_candidates.insert(mono_item);
274255
}
275256

276-
codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
257+
cgu.items_mut().insert(mono_item, (linkage, visibility));
258+
259+
// Get all inlined items that are reachable from `mono_item` without
260+
// going via another root item. This includes drop-glue, functions from
261+
// external crates, and local functions the definition of which is
262+
// marked with `#[inline]`.
263+
let mut reachable_inlined_items = FxHashSet::default();
264+
get_reachable_inlined_items(cx.tcx, mono_item, cx.usage_map, &mut reachable_inlined_items);
265+
266+
// Add those inlined items. It's possible an inlined item is reachable
267+
// from multiple root items within a CGU, which is fine, it just means
268+
// the `insert` will be a no-op.
269+
for inlined_item in reachable_inlined_items {
270+
// This is a CGU-private copy.
271+
cgu.items_mut().insert(inlined_item, (Linkage::Internal, Visibility::Default));
272+
}
277273
}
278274

279275
// Always ensure we have at least one CGU; otherwise, if we have a
280276
// crate with just types (for example), we could wind up with no CGU.
281277
if codegen_units.is_empty() {
282-
let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
283-
codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
278+
let cgu_name = fallback_cgu_name(cgu_name_builder);
279+
codegen_units.insert(cgu_name, CodegenUnit::new(cgu_name));
284280
}
285281

286282
let mut codegen_units: Vec<_> = codegen_units.into_values().collect();
287283
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
288284

289-
PlacedRootMonoItems {
285+
return PlacedMonoItems {
290286
codegen_units,
291287
internalization_candidates,
292288
unique_inlined_stats: (num_unique_inlined_items, unique_inlined_items_size),
289+
};
290+
291+
fn get_reachable_inlined_items<'tcx>(
292+
tcx: TyCtxt<'tcx>,
293+
item: MonoItem<'tcx>,
294+
usage_map: &UsageMap<'tcx>,
295+
visited: &mut FxHashSet<MonoItem<'tcx>>,
296+
) {
297+
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
298+
let is_new = visited.insert(inlined_item);
299+
if is_new {
300+
get_reachable_inlined_items(tcx, inlined_item, usage_map, visited);
301+
}
302+
});
293303
}
294304
}
295305

@@ -407,43 +417,6 @@ fn merge_codegen_units<'tcx>(
407417
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
408418
}
409419

410-
fn place_inlined_mono_items<'tcx>(
411-
cx: &PartitioningCx<'_, 'tcx>,
412-
codegen_units: &mut [CodegenUnit<'tcx>],
413-
) {
414-
for cgu in codegen_units.iter_mut() {
415-
// Collect all inlined items that need to be available in this codegen unit.
416-
let mut reachable_inlined_items = FxHashSet::default();
417-
for root in cgu.items().keys() {
418-
// Get all inlined items that are reachable from it without going
419-
// via another root item.
420-
get_reachable_inlined_items(cx.tcx, *root, cx.usage_map, &mut reachable_inlined_items);
421-
}
422-
423-
// Add all monomorphizations that are not already there.
424-
for inlined_item in reachable_inlined_items {
425-
assert!(!cgu.items().contains_key(&inlined_item));
426-
427-
// This is a CGU-private copy.
428-
cgu.items_mut().insert(inlined_item, (Linkage::Internal, Visibility::Default));
429-
}
430-
}
431-
432-
fn get_reachable_inlined_items<'tcx>(
433-
tcx: TyCtxt<'tcx>,
434-
item: MonoItem<'tcx>,
435-
usage_map: &UsageMap<'tcx>,
436-
visited: &mut FxHashSet<MonoItem<'tcx>>,
437-
) {
438-
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
439-
let is_new = visited.insert(inlined_item);
440-
if is_new {
441-
get_reachable_inlined_items(tcx, inlined_item, usage_map, visited);
442-
}
443-
});
444-
}
445-
}
446-
447420
fn internalize_symbols<'tcx>(
448421
cx: &PartitioningCx<'_, 'tcx>,
449422
codegen_units: &mut [CodegenUnit<'tcx>],

0 commit comments

Comments
 (0)