about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2016-05-26 13:04:35 -0400
committerMichael Woerister <michaelwoerister@posteo.net>2016-07-08 10:42:47 -0400
commit3a47103f1d2bbf144d3866abc9fe74a9143d2988 (patch)
tree5f961e354bb3720b36c19a0c2c8c3dec2a2d90ba
parent283c94cd49c8b7cf0b565902686db5fb0cf3e6fd (diff)
downloadrust-3a47103f1d2bbf144d3866abc9fe74a9143d2988.tar.gz
rust-3a47103f1d2bbf144d3866abc9fe74a9143d2988.zip
Fix codegen tests by make sure items are translated in AST order.
-rw-r--r--src/librustc_trans/base.rs4
-rw-r--r--src/librustc_trans/partitioning.rs44
-rw-r--r--src/test/codegen/drop.rs14
3 files changed, 49 insertions, 13 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 234ed800c47..e13eea6f8ce 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -2626,7 +2626,7 @@ 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() {
         let trans_items = ccx.codegen_unit()
-                             .items_in_deterministic_order(&symbol_map);
+                             .items_in_deterministic_order(tcx, &symbol_map);
 
         for (trans_item, linkage) in trans_items {
             trans_item.predefine(&ccx, linkage);
@@ -2636,7 +2636,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // ... and now that we have everything pre-defined, fill out those definitions.
     for ccx in crate_context_list.iter() {
         let trans_items = ccx.codegen_unit()
-                             .items_in_deterministic_order(&symbol_map);
+                             .items_in_deterministic_order(tcx, &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 0e06fd6235e..2f1961ac9f8 100644
--- a/src/librustc_trans/partitioning.rs
+++ b/src/librustc_trans/partitioning.rs
@@ -124,7 +124,9 @@ 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 std::cmp::Ordering;
 use symbol_map::SymbolMap;
+use syntax::ast::NodeId;
 use syntax::parse::token::{self, InternedString};
 use trans_item::TransItem;
 use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
@@ -144,18 +146,52 @@ pub struct CodegenUnit<'tcx> {
 
 impl<'tcx> CodegenUnit<'tcx> {
     pub fn items_in_deterministic_order(&self,
+                                        tcx: TyCtxt,
                                         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();
 
+        // The codegen tests rely on items being process in the same order as
+        // they appear in the file, so for local items, we sort by node_id first
         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)
+
+            let node_id1 = local_node_id(tcx, trans_item1);
+            let node_id2 = local_node_id(tcx, trans_item2);
+
+            match (node_id1, node_id2) {
+                (None, None) => {
+                    let symbol_name1 = symbol_map.get(trans_item1).unwrap();
+                    let symbol_name2 = symbol_map.get(trans_item2).unwrap();
+                    symbol_name1.cmp(symbol_name2)
+                }
+                (None, Some(_)) => Ordering::Less,
+                (Some(_), None) => Ordering::Greater,
+                (Some(node_id1), Some(node_id2)) => {
+                    let ordering = node_id1.cmp(&node_id2);
+
+                    if ordering != Ordering::Equal {
+                        return ordering;
+                    }
+
+                    let symbol_name1 = symbol_map.get(trans_item1).unwrap();
+                    let symbol_name2 = symbol_map.get(trans_item2).unwrap();
+                    symbol_name1.cmp(symbol_name2)
+                }
+            }
         });
 
-        items
+        return items;
+
+        fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option<NodeId> {
+            match trans_item {
+                TransItem::Fn(instance) => {
+                    tcx.map.as_local_node_id(instance.def)
+                }
+                TransItem::Static(node_id) => Some(node_id),
+                TransItem::DropGlue(_) => None,
+            }
+        }
     }
 }
 
diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs
index 83dd6a3b002..25f8c130469 100644
--- a/src/test/codegen/drop.rs
+++ b/src/test/codegen/drop.rs
@@ -31,13 +31,13 @@ pub fn droppy() {
 // that's one new drop call per call to possibly_unwinding(), and finally 3 drop calls for the
 // regular function exit. We used to have problems with quadratic growths of drop calls in such
 // functions.
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK: call{{.*}}SomeUniqueName{{.*}}drop
-// CHECK-NOT: call{{.*}}SomeUniqueName{{.*}}drop
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
+// CHECK-NOT: call{{.*}}drop{{.*}}SomeUniqueName
 // The next line checks for the } that ends the function definition
 // CHECK-LABEL: {{^[}]}}
     let _s = SomeUniqueName;