Skip to content

Commit 5005ebb

Browse files
committed
XXX: fix non-determinism
1 parent 1076b01 commit 5005ebb

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt
33
use rustc_attr::InlineAttr;
44
use rustc_data_structures::base_n;
55
use rustc_data_structures::fingerprint::Fingerprint;
6-
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
77
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
88
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
99
use rustc_hir::ItemId;
@@ -230,7 +230,7 @@ pub struct CodegenUnit<'tcx> {
230230
/// contain something unique to this crate (e.g., a module path)
231231
/// as well as the crate name and disambiguator.
232232
name: Symbol,
233-
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
233+
items: FxIndexMap<MonoItem<'tcx>, (Linkage, Visibility)>,
234234
size_estimate: Option<usize>,
235235
primary: bool,
236236
/// True if this is CGU is used to hold code coverage information for dead code,
@@ -291,11 +291,11 @@ impl<'tcx> CodegenUnit<'tcx> {
291291
self.primary = true;
292292
}
293293

294-
pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
294+
pub fn items(&self) -> &FxIndexMap<MonoItem<'tcx>, (Linkage, Visibility)> {
295295
&self.items
296296
}
297297

298-
pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
298+
pub fn items_mut(&mut self) -> &mut FxIndexMap<MonoItem<'tcx>, (Linkage, Visibility)> {
299299
&mut self.items
300300
}
301301

@@ -364,6 +364,47 @@ impl<'tcx> CodegenUnit<'tcx> {
364364
.unwrap_or_else(|| panic!("Could not find work-product for CGU `{}`", self.name()))
365365
}
366366

367+
// njn: dups code in items_in_deterministic_order
368+
pub fn sort_items(&mut self, tcx: TyCtxt<'tcx>) {
369+
// The codegen tests rely on items being process in the same order as
370+
// they appear in the file, so for local items, we sort by node_id first
371+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
372+
pub struct ItemSortKey<'tcx>(Option<usize>, SymbolName<'tcx>);
373+
374+
fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey<'tcx> {
375+
ItemSortKey(
376+
match item {
377+
MonoItem::Fn(ref instance) => {
378+
match instance.def {
379+
// We only want to take HirIds of user-defined
380+
// instances into account. The others don't matter for
381+
// the codegen tests and can even make item order
382+
// unstable.
383+
InstanceDef::Item(def) => def.as_local().map(Idx::index),
384+
InstanceDef::VTableShim(..)
385+
| InstanceDef::ReifyShim(..)
386+
| InstanceDef::Intrinsic(..)
387+
| InstanceDef::FnPtrShim(..)
388+
| InstanceDef::Virtual(..)
389+
| InstanceDef::ClosureOnceShim { .. }
390+
| InstanceDef::DropGlue(..)
391+
| InstanceDef::CloneShim(..)
392+
| InstanceDef::ThreadLocalShim(..)
393+
| InstanceDef::FnPtrAddrShim(..) => None,
394+
}
395+
}
396+
MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
397+
MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.def_id.index()),
398+
},
399+
item.symbol_name(tcx),
400+
)
401+
}
402+
403+
self.items_mut().sort_by(|&i1, _, &i2, _| {
404+
std::cmp::Ord::cmp(&item_sort_key(tcx, i1), &item_sort_key(tcx, i2))
405+
});
406+
}
407+
367408
pub fn items_in_deterministic_order(
368409
&self,
369410
tcx: TyCtxt<'tcx>,

compiler/rustc_monomorphize/src/partitioning/default.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -148,20 +148,27 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
148148
// non-deterministic splitting, which messes up incremental
149149
// compilation
150150

151+
old_cgu.sort_items(cx.tcx);
152+
while moved_size < target_size {
153+
let (item, rest) = old_cgu.items_mut().pop().unwrap();
154+
moved_size += item.size_estimate(cx.tcx);
155+
new_cgu.items_mut().insert(item, rest);
156+
}
157+
151158
// njn: nicer way to do this?
152159
// njn: don't move if it's the last item
153-
old_cgu.items_mut().drain_filter(|item, rest| {
154-
// njn: true->remove
155-
if moved_size < target_size {
156-
let item_size = item.size_estimate(cx.tcx);
157-
//eprintln!("MOVE: {}", item_size);
158-
moved_size += item_size;
159-
new_cgu.items_mut().insert(*item, *rest);
160-
true
161-
} else {
162-
false
163-
}
164-
});
160+
//old_cgu.items_mut().drain_filter(|item, rest| {
161+
// // njn: true->remove
162+
// if moved_size < target_size {
163+
// let item_size = item.size_estimate(cx.tcx);
164+
// //eprintln!("MOVE: {}", item_size);
165+
// moved_size += item_size;
166+
// new_cgu.items_mut().insert(*item, *rest);
167+
// true
168+
// } else {
169+
// false
170+
// }
171+
//});
165172
new_cgu.increase_size_estimate(moved_size);
166173
old_cgu.decrease_size_estimate(moved_size);
167174

@@ -193,7 +200,7 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
193200

194201
// Move the mono-items from `cgu_n` to `cgu_n_minus_1`
195202
cgu_n_minus_1.increase_size_estimate(cgu_n.size_estimate());
196-
for (k, v) in cgu_n.items_mut().drain() {
203+
for (k, v) in cgu_n.items_mut().drain(..) {
197204
cgu_n_minus_1.items_mut().insert(k, v);
198205
}
199206

0 commit comments

Comments
 (0)