Make item translation order deterministic by sorting by symbol name.

This commit is contained in:
Michael Woerister 2016-05-26 11:43:53 -04:00
parent b38e0d0d44
commit 37a10ecbe8
2 changed files with 39 additions and 8 deletions

View File

@ -2626,14 +2626,20 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Instantiate translation items without filling out definitions yet...
for ccx in crate_context_list.iter() {
for (&trans_item, &linkage) in &ccx.codegen_unit().items {
let trans_items = ccx.codegen_unit()
.items_in_deterministic_order(&symbol_map);
for (trans_item, linkage) in trans_items {
trans_item.predefine(&ccx, linkage);
}
}
// ... and now that we have everything pre-defined, fill out those definitions.
for ccx in crate_context_list.iter() {
for (trans_item, _) in &ccx.codegen_unit().items {
let trans_items = ccx.codegen_unit()
.items_in_deterministic_order(&symbol_map);
for (trans_item, _) in trans_items {
trans_item.define(&ccx);
}
}

View File

@ -124,15 +124,11 @@ use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::item_path::characteristic_def_id_of_type;
use symbol_map::SymbolMap;
use syntax::parse::token::{self, InternedString};
use trans_item::TransItem;
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
pub struct CodegenUnit<'tcx> {
pub name: InternedString,
pub items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
}
pub enum PartitioningStrategy {
/// Generate one codegen unit per source-level module.
PerModule,
@ -141,6 +137,29 @@ pub enum PartitioningStrategy {
FixedUnitCount(usize)
}
pub struct CodegenUnit<'tcx> {
pub name: InternedString,
pub items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
}
impl<'tcx> CodegenUnit<'tcx> {
pub fn items_in_deterministic_order(&self,
symbol_map: &SymbolMap)
-> Vec<(TransItem<'tcx>, llvm::Linkage)> {
let mut items: Vec<(TransItem<'tcx>, llvm::Linkage)> =
self.items.iter().map(|(item, linkage)| (*item, *linkage)).collect();
items.as_mut_slice().sort_by(|&(trans_item1, _), &(trans_item2, _)| {
let symbol_name1 = symbol_map.get(trans_item1).unwrap();
let symbol_name2 = symbol_map.get(trans_item2).unwrap();
symbol_name1.cmp(symbol_name2)
});
items
}
}
// Anything we can't find a proper codegen unit for goes into this.
const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
@ -184,7 +203,13 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug_dump(tcx, "POST INLINING:", post_inlining.0.iter());
post_inlining.0
// Finally, sort by codegen unit name, so that we get deterministic results
let mut result = post_inlining.0;
result.as_mut_slice().sort_by(|cgu1, cgu2| {
(&cgu1.name[..]).cmp(&cgu2.name[..])
});
result
}
struct PreInliningPartitioning<'tcx> {