Fix codegen tests by make sure items are translated in AST order.

This commit is contained in:
Michael Woerister 2016-05-26 13:04:35 -04:00
parent 283c94cd49
commit 3a47103f1d
3 changed files with 49 additions and 13 deletions

View File

@ -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);

View File

@ -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,
}
}
}
}

View File

@ -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;