about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2016-05-26 11:43:53 -0400
committerMichael Woerister <michaelwoerister@posteo.net>2016-07-08 10:42:47 -0400
commit37a10ecbe82c040ae307c48a0a0cdbcd9f05f6a3 (patch)
treee0623917df85771f80ce9f1827282724880ee6cf
parentb38e0d0d44c6de6f0c72a4a1f8f9aa8c74ea842e (diff)
downloadrust-37a10ecbe82c040ae307c48a0a0cdbcd9f05f6a3.tar.gz
rust-37a10ecbe82c040ae307c48a0a0cdbcd9f05f6a3.zip
Make item translation order deterministic by sorting by symbol name.
-rw-r--r--src/librustc_trans/base.rs10
-rw-r--r--src/librustc_trans/partitioning.rs37
2 files changed, 39 insertions, 8 deletions
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<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> {