Skip to content

Commit 1a08328

Browse files
Make item translation order deterministic by sorting by symbol name.
1 parent 4b09506 commit 1a08328

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

src/librustc_trans/base.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2633,14 +2633,20 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26332633

26342634
// Instantiate translation items without filling out definitions yet...
26352635
for ccx in crate_context_list.iter() {
2636-
for (&trans_item, &linkage) in &ccx.codegen_unit().items {
2636+
let trans_items = ccx.codegen_unit()
2637+
.items_in_deterministic_order(&symbol_map);
2638+
2639+
for (trans_item, linkage) in trans_items {
26372640
trans_item.predefine(&ccx, linkage);
26382641
}
26392642
}
26402643

26412644
// ... and now that we have everything pre-defined, fill out those definitions.
26422645
for ccx in crate_context_list.iter() {
2643-
for (trans_item, _) in &ccx.codegen_unit().items {
2646+
let trans_items = ccx.codegen_unit()
2647+
.items_in_deterministic_order(&symbol_map);
2648+
2649+
for (trans_item, _) in trans_items {
26442650
trans_item.define(&ccx);
26452651
}
26462652
}

src/librustc_trans/partitioning.rs

+31-6
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,11 @@ use rustc::hir::map::DefPathData;
124124
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
125125
use rustc::ty::TyCtxt;
126126
use rustc::ty::item_path::characteristic_def_id_of_type;
127+
use symbol_map::SymbolMap;
127128
use syntax::parse::token::{self, InternedString};
128129
use trans_item::TransItem;
129130
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
130131

131-
pub struct CodegenUnit<'tcx> {
132-
pub name: InternedString,
133-
pub items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
134-
}
135-
136132
pub enum PartitioningStrategy {
137133
/// Generate one codegen unit per source-level module.
138134
PerModule,
@@ -141,6 +137,29 @@ pub enum PartitioningStrategy {
141137
FixedUnitCount(usize)
142138
}
143139

140+
pub struct CodegenUnit<'tcx> {
141+
pub name: InternedString,
142+
pub items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
143+
}
144+
145+
impl<'tcx> CodegenUnit<'tcx> {
146+
pub fn items_in_deterministic_order(&self,
147+
symbol_map: &SymbolMap)
148+
-> Vec<(TransItem<'tcx>, llvm::Linkage)> {
149+
let mut items: Vec<(TransItem<'tcx>, llvm::Linkage)> =
150+
self.items.iter().map(|(item, linkage)| (*item, *linkage)).collect();
151+
152+
items.as_mut_slice().sort_by(|&(trans_item1, _), &(trans_item2, _)| {
153+
let symbol_name1 = symbol_map.get(trans_item1).unwrap();
154+
let symbol_name2 = symbol_map.get(trans_item2).unwrap();
155+
symbol_name1.cmp(symbol_name2)
156+
});
157+
158+
items
159+
}
160+
}
161+
162+
144163
// Anything we can't find a proper codegen unit for goes into this.
145164
const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
146165

@@ -184,7 +203,13 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
184203

185204
debug_dump(tcx, "POST INLINING:", post_inlining.0.iter());
186205

187-
post_inlining.0
206+
// Finally, sort by codegen unit name, so that we get deterministic results
207+
let mut result = post_inlining.0;
208+
result.as_mut_slice().sort_by(|cgu1, cgu2| {
209+
(&cgu1.name[..]).cmp(&cgu2.name[..])
210+
});
211+
212+
result
188213
}
189214

190215
struct PreInliningPartitioning<'tcx> {

0 commit comments

Comments
 (0)