diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 3fc7fe51288..4bbbae85fb2 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -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); } } diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index a0360a8ed22..0e06fd6235e 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -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, 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, 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> {