Skip to content

Commit 5254f98

Browse files
committed
Change CGU partitioning to put one item in each CGU
1 parent aa82970 commit 5254f98

File tree

3 files changed

+93
-19
lines changed

3 files changed

+93
-19
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,11 +1321,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13211321
}
13221322

13231323
fn cross_crate_inlinable(self, id: DefIndex) -> bool {
1324-
self.root
1325-
.tables
1326-
.cross_crate_inlinable
1327-
.get(self, id)
1328-
.expect(&format!("No cross_crate_inlinable for {:?}", id))
1324+
self.root.tables.cross_crate_inlinable.get(self, id).unwrap_or_else(|| {
1325+
debug!("cross_crate_inlinable missing for {id:?}");
1326+
false
1327+
});
13291328
}
13301329

13311330
fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ impl<'tcx> MonoItem<'tcx> {
113113
return InstantiationMode::GloballyShared { may_conflict: false };
114114
}
115115
if tcx.cross_crate_inlinable(instance.def_id()) {
116-
InstantiationMode::LocalCopy
116+
if tcx.sess.opts.incremental.is_some() {
117+
InstantiationMode::GloballyShared { may_conflict: true }
118+
} else {
119+
InstantiationMode::LocalCopy
120+
}
117121
} else {
118122
InstantiationMode::GloballyShared { may_conflict: false }
119123
}

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 84 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ use std::fs::{self, File};
9898
use std::io::{BufWriter, Write};
9999
use std::path::{Path, PathBuf};
100100

101+
use rustc_data_structures::base_n::ToBaseN;
101102
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
103+
use rustc_data_structures::stable_hasher::Hash64;
104+
use rustc_data_structures::stable_hasher::HashStable;
105+
use rustc_data_structures::stable_hasher::StableHasher;
102106
use rustc_data_structures::sync;
103107
use rustc_data_structures::unord::{UnordMap, UnordSet};
104108
use rustc_hir::def::DefKind;
@@ -195,10 +199,73 @@ where
195199
codegen_units
196200
}
197201

202+
fn place_mono_items_incr<'tcx, I>(
203+
cx: &PartitioningCx<'_, 'tcx>,
204+
mono_items: I,
205+
) -> PlacedMonoItems<'tcx>
206+
where
207+
I: Iterator<Item = MonoItem<'tcx>>,
208+
{
209+
let mut codegen_units = UnordMap::default();
210+
211+
let mut reachable_inlined_items = FxIndexSet::default();
212+
213+
for mono_item in mono_items {
214+
// Instantiate everything as GloballyShared in its own CGU
215+
let symbol_name = mono_item.symbol_name(cx.tcx).name;
216+
217+
let hash = cx.tcx.with_stable_hashing_context(|mut hcx| {
218+
let mut hasher = StableHasher::new();
219+
symbol_name.hash_stable(&mut hcx, &mut hasher);
220+
hasher.finish::<Hash64>().as_u64()
221+
});
222+
223+
let cgu_name = Symbol::intern(&hash.to_base(62));
224+
225+
let cgu = codegen_units.entry(cgu_name).or_insert_with(|| CodegenUnit::new(cgu_name));
226+
227+
let linkage = Linkage::External;
228+
let visibility = Visibility::Default;
229+
230+
let size_estimate = mono_item.size_estimate(cx.tcx);
231+
232+
cgu.items_mut()
233+
.insert(mono_item, MonoItemData { inlined: false, linkage, visibility, size_estimate });
234+
235+
get_reachable_inlined_items(cx.tcx, mono_item, cx.usage_map, &mut reachable_inlined_items);
236+
}
237+
238+
let symbol = Symbol::intern("upstream");
239+
let cgu = codegen_units.entry(symbol).or_insert_with(|| CodegenUnit::new(symbol));
240+
241+
for inlined_item in reachable_inlined_items {
242+
cgu.items_mut().entry(inlined_item).or_insert_with(|| MonoItemData {
243+
inlined: false,
244+
linkage: Linkage::External,
245+
visibility: Visibility::Default,
246+
size_estimate: inlined_item.size_estimate(cx.tcx),
247+
});
248+
}
249+
250+
let mut codegen_units: Vec<_> = cx.tcx.with_stable_hashing_context(|ref hcx| {
251+
codegen_units.into_items().map(|(_, cgu)| cgu).collect_sorted(hcx, true)
252+
});
253+
254+
for cgu in codegen_units.iter_mut() {
255+
cgu.compute_size_estimate();
256+
}
257+
258+
return PlacedMonoItems { codegen_units, internalization_candidates: UnordSet::default() };
259+
}
260+
198261
fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> PlacedMonoItems<'tcx>
199262
where
200263
I: Iterator<Item = MonoItem<'tcx>>,
201264
{
265+
if cx.tcx.sess.opts.incremental.is_some() {
266+
return place_mono_items_incr(cx, mono_items);
267+
}
268+
202269
let mut codegen_units = UnordMap::default();
203270
let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
204271
let mut internalization_candidates = UnordSet::default();
@@ -295,20 +362,20 @@ where
295362
}
296363

297364
return PlacedMonoItems { codegen_units, internalization_candidates };
365+
}
298366

299-
fn get_reachable_inlined_items<'tcx>(
300-
tcx: TyCtxt<'tcx>,
301-
item: MonoItem<'tcx>,
302-
usage_map: &UsageMap<'tcx>,
303-
visited: &mut FxIndexSet<MonoItem<'tcx>>,
304-
) {
305-
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
306-
let is_new = visited.insert(inlined_item);
307-
if is_new {
308-
get_reachable_inlined_items(tcx, inlined_item, usage_map, visited);
309-
}
310-
});
311-
}
367+
fn get_reachable_inlined_items<'tcx>(
368+
tcx: TyCtxt<'tcx>,
369+
item: MonoItem<'tcx>,
370+
usage_map: &UsageMap<'tcx>,
371+
visited: &mut FxIndexSet<MonoItem<'tcx>>,
372+
) {
373+
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
374+
let is_new = visited.insert(inlined_item);
375+
if is_new {
376+
get_reachable_inlined_items(tcx, inlined_item, usage_map, visited);
377+
}
378+
});
312379
}
313380

314381
// This function requires the CGUs to be sorted by name on input, and ensures
@@ -322,6 +389,10 @@ fn merge_codegen_units<'tcx>(
322389
// A sorted order here ensures merging is deterministic.
323390
assert!(codegen_units.is_sorted_by(|a, b| a.name().as_str() <= b.name().as_str()));
324391

392+
if cx.tcx.sess.opts.incremental.is_some() {
393+
return;
394+
}
395+
325396
// This map keeps track of what got merged into what.
326397
let mut cgu_contents: UnordMap<Symbol, Vec<Symbol>> =
327398
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();

0 commit comments

Comments
 (0)