Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 97d4a38

Browse files
committedMay 30, 2023
Remove -Zcgu-partitioning-strategy.
This option was introduced three years ago, but it's never been meaningfully used, and `default` is the only acceptable value. Also, I think the `Partition` trait presents an interface that is too closely tied to the existing strategy and would probably be wrong for other strategies. (My rule of thumb is to not make something generic until there are at least two instances of it, to avoid this kind of problem.) Also, I don't think providing multiple partitioning strategies to the user is a good idea, because the compiler already has enough obscure knobs. This commit removes the option, along with the `Partition` trait, and the `Partitioner` and `DefaultPartitioning` types. I left the existing code in `compiler/rustc_monomorphize/src/partitioning/default.rs`, though I could be persuaded that moving it into `compiler/rustc_monomorphize/src/partitioning/mod.rs` is better.
1 parent 1c53407 commit 97d4a38

File tree

3 files changed

+276
-396
lines changed

3 files changed

+276
-396
lines changed
 

‎compiler/rustc_monomorphize/src/partitioning/default.rs

Lines changed: 271 additions & 278 deletions
Original file line numberDiff line numberDiff line change
@@ -15,326 +15,319 @@ use rustc_span::symbol::Symbol;
1515

1616
use super::PartitioningCx;
1717
use crate::collector::InliningMap;
18-
use crate::partitioning::{MonoItemPlacement, Partition, PlacedRootMonoItems};
19-
20-
pub struct DefaultPartitioning;
21-
22-
impl<'tcx> Partition<'tcx> for DefaultPartitioning {
23-
fn place_root_mono_items<I>(
24-
&mut self,
25-
cx: &PartitioningCx<'_, 'tcx>,
26-
mono_items: &mut I,
27-
) -> PlacedRootMonoItems<'tcx>
28-
where
29-
I: Iterator<Item = MonoItem<'tcx>>,
30-
{
31-
let mut roots = FxHashSet::default();
32-
let mut codegen_units = FxHashMap::default();
33-
let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
34-
let mut internalization_candidates = FxHashSet::default();
35-
36-
// Determine if monomorphizations instantiated in this crate will be made
37-
// available to downstream crates. This depends on whether we are in
38-
// share-generics mode and whether the current crate can even have
39-
// downstream crates.
40-
let export_generics =
41-
cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
42-
43-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
44-
let cgu_name_cache = &mut FxHashMap::default();
45-
46-
for mono_item in mono_items {
47-
match mono_item.instantiation_mode(cx.tcx) {
48-
InstantiationMode::GloballyShared { .. } => {}
49-
InstantiationMode::LocalCopy => continue,
50-
}
18+
use crate::partitioning::{MonoItemPlacement, PlacedRootMonoItems};
19+
20+
// This modules implements the default (and only) partitioning strategy.
21+
22+
pub(super) fn place_root_mono_items<'tcx, I>(
23+
cx: &PartitioningCx<'_, 'tcx>,
24+
mono_items: &mut I,
25+
) -> PlacedRootMonoItems<'tcx>
26+
where
27+
I: Iterator<Item = MonoItem<'tcx>>,
28+
{
29+
let mut roots = FxHashSet::default();
30+
let mut codegen_units = FxHashMap::default();
31+
let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
32+
let mut internalization_candidates = FxHashSet::default();
33+
34+
// Determine if monomorphizations instantiated in this crate will be made
35+
// available to downstream crates. This depends on whether we are in
36+
// share-generics mode and whether the current crate can even have
37+
// downstream crates.
38+
let export_generics =
39+
cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
5140

52-
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
53-
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
54-
55-
let codegen_unit_name = match characteristic_def_id {
56-
Some(def_id) => compute_codegen_unit_name(
57-
cx.tcx,
58-
cgu_name_builder,
59-
def_id,
60-
is_volatile,
61-
cgu_name_cache,
62-
),
63-
None => fallback_cgu_name(cgu_name_builder),
64-
};
41+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
42+
let cgu_name_cache = &mut FxHashMap::default();
43+
44+
for mono_item in mono_items {
45+
match mono_item.instantiation_mode(cx.tcx) {
46+
InstantiationMode::GloballyShared { .. } => {}
47+
InstantiationMode::LocalCopy => continue,
48+
}
6549

66-
let codegen_unit = codegen_units
67-
.entry(codegen_unit_name)
68-
.or_insert_with(|| CodegenUnit::new(codegen_unit_name));
50+
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
51+
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
6952

70-
let mut can_be_internalized = true;
71-
let (linkage, visibility) = mono_item_linkage_and_visibility(
53+
let codegen_unit_name = match characteristic_def_id {
54+
Some(def_id) => compute_codegen_unit_name(
7255
cx.tcx,
73-
&mono_item,
74-
&mut can_be_internalized,
75-
export_generics,
76-
);
77-
if visibility == Visibility::Hidden && can_be_internalized {
78-
internalization_candidates.insert(mono_item);
79-
}
80-
81-
codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
82-
roots.insert(mono_item);
83-
}
56+
cgu_name_builder,
57+
def_id,
58+
is_volatile,
59+
cgu_name_cache,
60+
),
61+
None => fallback_cgu_name(cgu_name_builder),
62+
};
8463

85-
// Always ensure we have at least one CGU; otherwise, if we have a
86-
// crate with just types (for example), we could wind up with no CGU.
87-
if codegen_units.is_empty() {
88-
let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
89-
codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
64+
let codegen_unit = codegen_units
65+
.entry(codegen_unit_name)
66+
.or_insert_with(|| CodegenUnit::new(codegen_unit_name));
67+
68+
let mut can_be_internalized = true;
69+
let (linkage, visibility) = mono_item_linkage_and_visibility(
70+
cx.tcx,
71+
&mono_item,
72+
&mut can_be_internalized,
73+
export_generics,
74+
);
75+
if visibility == Visibility::Hidden && can_be_internalized {
76+
internalization_candidates.insert(mono_item);
9077
}
9178

92-
let codegen_units = codegen_units.into_values().collect();
93-
PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
79+
codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
80+
roots.insert(mono_item);
9481
}
9582

96-
fn merge_codegen_units(
97-
&mut self,
98-
cx: &PartitioningCx<'_, 'tcx>,
99-
codegen_units: &mut Vec<CodegenUnit<'tcx>>,
100-
) {
101-
assert!(cx.target_cgu_count >= 1);
83+
// Always ensure we have at least one CGU; otherwise, if we have a
84+
// crate with just types (for example), we could wind up with no CGU.
85+
if codegen_units.is_empty() {
86+
let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
87+
codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
88+
}
10289

103-
// Note that at this point in time the `codegen_units` here may not be
104-
// in a deterministic order (but we know they're deterministically the
105-
// same set). We want this merging to produce a deterministic ordering
106-
// of codegen units from the input.
107-
//
108-
// Due to basically how we've implemented the merging below (merge the
109-
// two smallest into each other) we're sure to start off with a
110-
// deterministic order (sorted by name). This'll mean that if two cgus
111-
// have the same size the stable sort below will keep everything nice
112-
// and deterministic.
113-
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
114-
115-
// This map keeps track of what got merged into what.
116-
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
117-
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
118-
119-
// Merge the two smallest codegen units until the target size is
120-
// reached.
121-
while codegen_units.len() > cx.target_cgu_count {
122-
// Sort small cgus to the back
123-
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
124-
let mut smallest = codegen_units.pop().unwrap();
125-
let second_smallest = codegen_units.last_mut().unwrap();
126-
127-
// Move the mono-items from `smallest` to `second_smallest`
128-
second_smallest.modify_size_estimate(smallest.size_estimate());
129-
for (k, v) in smallest.items_mut().drain() {
130-
second_smallest.items_mut().insert(k, v);
131-
}
90+
let codegen_units = codegen_units.into_values().collect();
91+
PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
92+
}
13293

133-
// Record that `second_smallest` now contains all the stuff that was
134-
// in `smallest` before.
135-
let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
136-
cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
94+
pub(super) fn merge_codegen_units<'tcx>(
95+
cx: &PartitioningCx<'_, 'tcx>,
96+
codegen_units: &mut Vec<CodegenUnit<'tcx>>,
97+
) {
98+
assert!(cx.target_cgu_count >= 1);
13799

138-
debug!(
139-
"CodegenUnit {} merged into CodegenUnit {}",
140-
smallest.name(),
141-
second_smallest.name()
142-
);
100+
// Note that at this point in time the `codegen_units` here may not be
101+
// in a deterministic order (but we know they're deterministically the
102+
// same set). We want this merging to produce a deterministic ordering
103+
// of codegen units from the input.
104+
//
105+
// Due to basically how we've implemented the merging below (merge the
106+
// two smallest into each other) we're sure to start off with a
107+
// deterministic order (sorted by name). This'll mean that if two cgus
108+
// have the same size the stable sort below will keep everything nice
109+
// and deterministic.
110+
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
111+
112+
// This map keeps track of what got merged into what.
113+
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
114+
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
115+
116+
// Merge the two smallest codegen units until the target size is
117+
// reached.
118+
while codegen_units.len() > cx.target_cgu_count {
119+
// Sort small cgus to the back
120+
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
121+
let mut smallest = codegen_units.pop().unwrap();
122+
let second_smallest = codegen_units.last_mut().unwrap();
123+
124+
// Move the mono-items from `smallest` to `second_smallest`
125+
second_smallest.modify_size_estimate(smallest.size_estimate());
126+
for (k, v) in smallest.items_mut().drain() {
127+
second_smallest.items_mut().insert(k, v);
143128
}
144129

145-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
146-
147-
if cx.tcx.sess.opts.incremental.is_some() {
148-
// If we are doing incremental compilation, we want CGU names to
149-
// reflect the path of the source level module they correspond to.
150-
// For CGUs that contain the code of multiple modules because of the
151-
// merging done above, we use a concatenation of the names of all
152-
// contained CGUs.
153-
let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
154-
.into_iter()
155-
// This `filter` makes sure we only update the name of CGUs that
156-
// were actually modified by merging.
157-
.filter(|(_, cgu_contents)| cgu_contents.len() > 1)
158-
.map(|(current_cgu_name, cgu_contents)| {
159-
let mut cgu_contents: Vec<&str> =
160-
cgu_contents.iter().map(|s| s.as_str()).collect();
161-
162-
// Sort the names, so things are deterministic and easy to
163-
// predict. We are sorting primitive `&str`s here so we can
164-
// use unstable sort.
165-
cgu_contents.sort_unstable();
166-
167-
(current_cgu_name, cgu_contents.join("--"))
168-
})
169-
.collect();
170-
171-
for cgu in codegen_units.iter_mut() {
172-
if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
173-
if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
174-
cgu.set_name(Symbol::intern(&new_cgu_name));
175-
} else {
176-
// If we don't require CGU names to be human-readable,
177-
// we use a fixed length hash of the composite CGU name
178-
// instead.
179-
let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
180-
cgu.set_name(Symbol::intern(&new_cgu_name));
181-
}
130+
// Record that `second_smallest` now contains all the stuff that was
131+
// in `smallest` before.
132+
let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
133+
cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
134+
135+
debug!(
136+
"CodegenUnit {} merged into CodegenUnit {}",
137+
smallest.name(),
138+
second_smallest.name()
139+
);
140+
}
141+
142+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
143+
144+
if cx.tcx.sess.opts.incremental.is_some() {
145+
// If we are doing incremental compilation, we want CGU names to
146+
// reflect the path of the source level module they correspond to.
147+
// For CGUs that contain the code of multiple modules because of the
148+
// merging done above, we use a concatenation of the names of all
149+
// contained CGUs.
150+
let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
151+
.into_iter()
152+
// This `filter` makes sure we only update the name of CGUs that
153+
// were actually modified by merging.
154+
.filter(|(_, cgu_contents)| cgu_contents.len() > 1)
155+
.map(|(current_cgu_name, cgu_contents)| {
156+
let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| s.as_str()).collect();
157+
158+
// Sort the names, so things are deterministic and easy to
159+
// predict. We are sorting primitive `&str`s here so we can
160+
// use unstable sort.
161+
cgu_contents.sort_unstable();
162+
163+
(current_cgu_name, cgu_contents.join("--"))
164+
})
165+
.collect();
166+
167+
for cgu in codegen_units.iter_mut() {
168+
if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
169+
if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
170+
cgu.set_name(Symbol::intern(&new_cgu_name));
171+
} else {
172+
// If we don't require CGU names to be human-readable,
173+
// we use a fixed length hash of the composite CGU name
174+
// instead.
175+
let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
176+
cgu.set_name(Symbol::intern(&new_cgu_name));
182177
}
183178
}
184-
} else {
185-
// If we are compiling non-incrementally we just generate simple CGU
186-
// names containing an index.
187-
for (index, cgu) in codegen_units.iter_mut().enumerate() {
188-
let numbered_codegen_unit_name =
189-
cgu_name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index));
190-
cgu.set_name(numbered_codegen_unit_name);
191-
}
179+
}
180+
} else {
181+
// If we are compiling non-incrementally we just generate simple CGU
182+
// names containing an index.
183+
for (index, cgu) in codegen_units.iter_mut().enumerate() {
184+
let numbered_codegen_unit_name =
185+
cgu_name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index));
186+
cgu.set_name(numbered_codegen_unit_name);
192187
}
193188
}
189+
}
194190

195-
fn place_inlined_mono_items(
196-
&mut self,
197-
cx: &PartitioningCx<'_, 'tcx>,
198-
codegen_units: &mut [CodegenUnit<'tcx>],
199-
roots: FxHashSet<MonoItem<'tcx>>,
200-
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
201-
let mut mono_item_placements = FxHashMap::default();
202-
203-
let single_codegen_unit = codegen_units.len() == 1;
204-
205-
for old_codegen_unit in codegen_units.iter_mut() {
206-
// Collect all items that need to be available in this codegen unit.
207-
let mut reachable = FxHashSet::default();
208-
for root in old_codegen_unit.items().keys() {
209-
follow_inlining(*root, cx.inlining_map, &mut reachable);
210-
}
191+
pub(super) fn place_inlined_mono_items<'tcx>(
192+
cx: &PartitioningCx<'_, 'tcx>,
193+
codegen_units: &mut [CodegenUnit<'tcx>],
194+
roots: FxHashSet<MonoItem<'tcx>>,
195+
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
196+
let mut mono_item_placements = FxHashMap::default();
211197

212-
let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
198+
let single_codegen_unit = codegen_units.len() == 1;
213199

214-
// Add all monomorphizations that are not already there.
215-
for mono_item in reachable {
216-
if let Some(linkage) = old_codegen_unit.items().get(&mono_item) {
217-
// This is a root, just copy it over.
218-
new_codegen_unit.items_mut().insert(mono_item, *linkage);
219-
} else {
220-
if roots.contains(&mono_item) {
221-
bug!(
222-
"GloballyShared mono-item inlined into other CGU: \
223-
{:?}",
224-
mono_item
225-
);
226-
}
200+
for old_codegen_unit in codegen_units.iter_mut() {
201+
// Collect all items that need to be available in this codegen unit.
202+
let mut reachable = FxHashSet::default();
203+
for root in old_codegen_unit.items().keys() {
204+
follow_inlining(*root, cx.inlining_map, &mut reachable);
205+
}
206+
207+
let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
227208

228-
// This is a CGU-private copy.
229-
new_codegen_unit
230-
.items_mut()
231-
.insert(mono_item, (Linkage::Internal, Visibility::Default));
209+
// Add all monomorphizations that are not already there.
210+
for mono_item in reachable {
211+
if let Some(linkage) = old_codegen_unit.items().get(&mono_item) {
212+
// This is a root, just copy it over.
213+
new_codegen_unit.items_mut().insert(mono_item, *linkage);
214+
} else {
215+
if roots.contains(&mono_item) {
216+
bug!(
217+
"GloballyShared mono-item inlined into other CGU: \
218+
{:?}",
219+
mono_item
220+
);
232221
}
233222

234-
if !single_codegen_unit {
235-
// If there is more than one codegen unit, we need to keep track
236-
// in which codegen units each monomorphization is placed.
237-
match mono_item_placements.entry(mono_item) {
238-
Entry::Occupied(e) => {
239-
let placement = e.into_mut();
240-
debug_assert!(match *placement {
241-
MonoItemPlacement::SingleCgu { cgu_name } => {
242-
cgu_name != new_codegen_unit.name()
243-
}
244-
MonoItemPlacement::MultipleCgus => true,
245-
});
246-
*placement = MonoItemPlacement::MultipleCgus;
247-
}
248-
Entry::Vacant(e) => {
249-
e.insert(MonoItemPlacement::SingleCgu {
250-
cgu_name: new_codegen_unit.name(),
251-
});
252-
}
223+
// This is a CGU-private copy.
224+
new_codegen_unit
225+
.items_mut()
226+
.insert(mono_item, (Linkage::Internal, Visibility::Default));
227+
}
228+
229+
if !single_codegen_unit {
230+
// If there is more than one codegen unit, we need to keep track
231+
// in which codegen units each monomorphization is placed.
232+
match mono_item_placements.entry(mono_item) {
233+
Entry::Occupied(e) => {
234+
let placement = e.into_mut();
235+
debug_assert!(match *placement {
236+
MonoItemPlacement::SingleCgu { cgu_name } => {
237+
cgu_name != new_codegen_unit.name()
238+
}
239+
MonoItemPlacement::MultipleCgus => true,
240+
});
241+
*placement = MonoItemPlacement::MultipleCgus;
242+
}
243+
Entry::Vacant(e) => {
244+
e.insert(MonoItemPlacement::SingleCgu {
245+
cgu_name: new_codegen_unit.name(),
246+
});
253247
}
254248
}
255249
}
256-
257-
*old_codegen_unit = new_codegen_unit;
258250
}
259251

260-
return mono_item_placements;
261-
262-
fn follow_inlining<'tcx>(
263-
mono_item: MonoItem<'tcx>,
264-
inlining_map: &InliningMap<'tcx>,
265-
visited: &mut FxHashSet<MonoItem<'tcx>>,
266-
) {
267-
if !visited.insert(mono_item) {
268-
return;
269-
}
270-
271-
inlining_map.with_inlining_candidates(mono_item, |target| {
272-
follow_inlining(target, inlining_map, visited);
273-
});
274-
}
252+
*old_codegen_unit = new_codegen_unit;
275253
}
276254

277-
fn internalize_symbols(
278-
&mut self,
279-
cx: &PartitioningCx<'_, 'tcx>,
280-
codegen_units: &mut [CodegenUnit<'tcx>],
281-
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
282-
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
283-
) {
284-
if codegen_units.len() == 1 {
285-
// Fast path for when there is only one codegen unit. In this case we
286-
// can internalize all candidates, since there is nowhere else they
287-
// could be accessed from.
288-
for cgu in codegen_units {
289-
for candidate in &internalization_candidates {
290-
cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
291-
}
292-
}
255+
return mono_item_placements;
293256

257+
fn follow_inlining<'tcx>(
258+
mono_item: MonoItem<'tcx>,
259+
inlining_map: &InliningMap<'tcx>,
260+
visited: &mut FxHashSet<MonoItem<'tcx>>,
261+
) {
262+
if !visited.insert(mono_item) {
294263
return;
295264
}
296265

297-
// Build a map from every monomorphization to all the monomorphizations that
298-
// reference it.
299-
let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
300-
cx.inlining_map.iter_accesses(|accessor, accessees| {
301-
for accessee in accessees {
302-
accessor_map.entry(*accessee).or_default().push(accessor);
303-
}
266+
inlining_map.with_inlining_candidates(mono_item, |target| {
267+
follow_inlining(target, inlining_map, visited);
304268
});
269+
}
270+
}
305271

306-
// For each internalization candidates in each codegen unit, check if it is
307-
// accessed from outside its defining codegen unit.
272+
pub(super) fn internalize_symbols<'tcx>(
273+
cx: &PartitioningCx<'_, 'tcx>,
274+
codegen_units: &mut [CodegenUnit<'tcx>],
275+
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
276+
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
277+
) {
278+
if codegen_units.len() == 1 {
279+
// Fast path for when there is only one codegen unit. In this case we
280+
// can internalize all candidates, since there is nowhere else they
281+
// could be accessed from.
308282
for cgu in codegen_units {
309-
let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
283+
for candidate in &internalization_candidates {
284+
cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
285+
}
286+
}
287+
288+
return;
289+
}
290+
291+
// Build a map from every monomorphization to all the monomorphizations that
292+
// reference it.
293+
let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
294+
cx.inlining_map.iter_accesses(|accessor, accessees| {
295+
for accessee in accessees {
296+
accessor_map.entry(*accessee).or_default().push(accessor);
297+
}
298+
});
310299

311-
for (accessee, linkage_and_visibility) in cgu.items_mut() {
312-
if !internalization_candidates.contains(accessee) {
313-
// This item is no candidate for internalizing, so skip it.
300+
// For each internalization candidates in each codegen unit, check if it is
301+
// accessed from outside its defining codegen unit.
302+
for cgu in codegen_units {
303+
let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
304+
305+
for (accessee, linkage_and_visibility) in cgu.items_mut() {
306+
if !internalization_candidates.contains(accessee) {
307+
// This item is no candidate for internalizing, so skip it.
308+
continue;
309+
}
310+
debug_assert_eq!(mono_item_placements[accessee], home_cgu);
311+
312+
if let Some(accessors) = accessor_map.get(accessee) {
313+
if accessors
314+
.iter()
315+
.filter_map(|accessor| {
316+
// Some accessors might not have been
317+
// instantiated. We can safely ignore those.
318+
mono_item_placements.get(accessor)
319+
})
320+
.any(|placement| *placement != home_cgu)
321+
{
322+
// Found an accessor from another CGU, so skip to the next
323+
// item without marking this one as internal.
314324
continue;
315325
}
316-
debug_assert_eq!(mono_item_placements[accessee], home_cgu);
317-
318-
if let Some(accessors) = accessor_map.get(accessee) {
319-
if accessors
320-
.iter()
321-
.filter_map(|accessor| {
322-
// Some accessors might not have been
323-
// instantiated. We can safely ignore those.
324-
mono_item_placements.get(accessor)
325-
})
326-
.any(|placement| *placement != home_cgu)
327-
{
328-
// Found an accessor from another CGU, so skip to the next
329-
// item without marking this one as internal.
330-
continue;
331-
}
332-
}
333-
334-
// If we got here, we did not find any accesses from other CGUs,
335-
// so it's fine to make this monomorphization internal.
336-
*linkage_and_visibility = (Linkage::Internal, Visibility::Default);
337326
}
327+
328+
// If we got here, we did not find any accesses from other CGUs,
329+
// so it's fine to make this monomorphization internal.
330+
*linkage_and_visibility = (Linkage::Internal, Visibility::Default);
338331
}
339332
}
340333
}

‎compiler/rustc_monomorphize/src/partitioning/mod.rs

Lines changed: 5 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -113,74 +113,7 @@ use rustc_span::symbol::Symbol;
113113

114114
use crate::collector::InliningMap;
115115
use crate::collector::{self, MonoItemCollectionMode};
116-
use crate::errors::{
117-
CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode, UnknownPartitionStrategy,
118-
};
119-
120-
enum Partitioner {
121-
Default(default::DefaultPartitioning),
122-
// Other partitioning strategies can go here.
123-
Unknown,
124-
}
125-
126-
impl<'tcx> Partition<'tcx> for Partitioner {
127-
fn place_root_mono_items<I>(
128-
&mut self,
129-
cx: &PartitioningCx<'_, 'tcx>,
130-
mono_items: &mut I,
131-
) -> PlacedRootMonoItems<'tcx>
132-
where
133-
I: Iterator<Item = MonoItem<'tcx>>,
134-
{
135-
match self {
136-
Partitioner::Default(partitioner) => partitioner.place_root_mono_items(cx, mono_items),
137-
Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
138-
}
139-
}
140-
141-
fn merge_codegen_units(
142-
&mut self,
143-
cx: &PartitioningCx<'_, 'tcx>,
144-
codegen_units: &mut Vec<CodegenUnit<'tcx>>,
145-
) {
146-
match self {
147-
Partitioner::Default(partitioner) => partitioner.merge_codegen_units(cx, codegen_units),
148-
Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
149-
}
150-
}
151-
152-
fn place_inlined_mono_items(
153-
&mut self,
154-
cx: &PartitioningCx<'_, 'tcx>,
155-
codegen_units: &mut [CodegenUnit<'tcx>],
156-
roots: FxHashSet<MonoItem<'tcx>>,
157-
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
158-
match self {
159-
Partitioner::Default(partitioner) => {
160-
partitioner.place_inlined_mono_items(cx, codegen_units, roots)
161-
}
162-
Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
163-
}
164-
}
165-
166-
fn internalize_symbols(
167-
&mut self,
168-
cx: &PartitioningCx<'_, 'tcx>,
169-
codegen_units: &mut [CodegenUnit<'tcx>],
170-
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
171-
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
172-
) {
173-
match self {
174-
Partitioner::Default(partitioner) => partitioner.internalize_symbols(
175-
cx,
176-
codegen_units,
177-
mono_item_placements,
178-
internalization_candidates,
179-
),
180-
Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
181-
}
182-
}
183-
}
116+
use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode};
184117

185118
struct PartitioningCx<'a, 'tcx> {
186119
tcx: TyCtxt<'tcx>,
@@ -194,49 +127,6 @@ pub struct PlacedRootMonoItems<'tcx> {
194127
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
195128
}
196129

197-
trait Partition<'tcx> {
198-
fn place_root_mono_items<I>(
199-
&mut self,
200-
cx: &PartitioningCx<'_, 'tcx>,
201-
mono_items: &mut I,
202-
) -> PlacedRootMonoItems<'tcx>
203-
where
204-
I: Iterator<Item = MonoItem<'tcx>>;
205-
206-
fn merge_codegen_units(
207-
&mut self,
208-
cx: &PartitioningCx<'_, 'tcx>,
209-
codegen_units: &mut Vec<CodegenUnit<'tcx>>,
210-
);
211-
212-
fn place_inlined_mono_items(
213-
&mut self,
214-
cx: &PartitioningCx<'_, 'tcx>,
215-
codegen_units: &mut [CodegenUnit<'tcx>],
216-
roots: FxHashSet<MonoItem<'tcx>>,
217-
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement>;
218-
219-
fn internalize_symbols(
220-
&mut self,
221-
cx: &PartitioningCx<'_, 'tcx>,
222-
codegen_units: &mut [CodegenUnit<'tcx>],
223-
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
224-
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
225-
);
226-
}
227-
228-
fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner {
229-
let strategy = match &tcx.sess.opts.unstable_opts.cgu_partitioning_strategy {
230-
None => "default",
231-
Some(s) => &s[..],
232-
};
233-
234-
match strategy {
235-
"default" => Partitioner::Default(default::DefaultPartitioning),
236-
_ => Partitioner::Unknown,
237-
}
238-
}
239-
240130
fn partition<'tcx, I>(
241131
tcx: TyCtxt<'tcx>,
242132
mono_items: &mut I,
@@ -248,14 +138,13 @@ where
248138
{
249139
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
250140

251-
let mut partitioner = get_partitioner(tcx);
252141
let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
253142
// In the first step, we place all regular monomorphizations into their
254143
// respective 'home' codegen unit. Regular monomorphizations are all
255144
// functions and statics defined in the local crate.
256145
let PlacedRootMonoItems { mut codegen_units, roots, internalization_candidates } = {
257146
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
258-
partitioner.place_root_mono_items(cx, mono_items)
147+
default::place_root_mono_items(cx, mono_items)
259148
};
260149

261150
for cgu in &mut codegen_units {
@@ -269,7 +158,7 @@ where
269158
// estimates.
270159
{
271160
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
272-
partitioner.merge_codegen_units(cx, &mut codegen_units);
161+
default::merge_codegen_units(cx, &mut codegen_units);
273162
debug_dump(tcx, "POST MERGING", &codegen_units);
274163
}
275164

@@ -279,7 +168,7 @@ where
279168
// local functions the definition of which is marked with `#[inline]`.
280169
let mono_item_placements = {
281170
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
282-
partitioner.place_inlined_mono_items(cx, &mut codegen_units, roots)
171+
default::place_inlined_mono_items(cx, &mut codegen_units, roots)
283172
};
284173

285174
for cgu in &mut codegen_units {
@@ -292,7 +181,7 @@ where
292181
// more freedom to optimize.
293182
if !tcx.sess.link_dead_code() {
294183
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
295-
partitioner.internalize_symbols(
184+
default::internalize_symbols(
296185
cx,
297186
&mut codegen_units,
298187
mono_item_placements,

‎compiler/rustc_session/src/options.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,8 +1372,6 @@ options! {
13721372
"set options for branch target identification and pointer authentication on AArch64"),
13731373
cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],
13741374
"instrument control-flow architecture protection"),
1375-
cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED],
1376-
"the codegen unit partitioning strategy to use"),
13771375
codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
13781376
"the backend to use"),
13791377
combine_cgu: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)
Please sign in to comment.