Skip to content

Commit b38e0d0

Browse files
Build SymbolMap for symbol name conflict checking and caching.
1 parent 87c1c87 commit b38e0d0

File tree

8 files changed

+237
-54
lines changed

8 files changed

+237
-54
lines changed

src/librustc_trans/base.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ use meth;
8080
use mir;
8181
use monomorphize::{self, Instance};
8282
use partitioning::{self, PartitioningStrategy, CodegenUnit};
83+
use symbol_map::SymbolMap;
8384
use symbol_names_test;
8485
use trans_item::TransItem;
8586
use tvec;
@@ -97,6 +98,7 @@ use libc::c_uint;
9798
use std::ffi::{CStr, CString};
9899
use std::cell::{Cell, RefCell};
99100
use std::collections::{HashMap, HashSet};
101+
use std::rc::Rc;
100102
use std::str;
101103
use std::{i8, i16, i32, i64};
102104
use syntax_pos::{Span, DUMMY_SP};
@@ -2588,14 +2590,18 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
25882590
};
25892591
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
25902592

2591-
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2593+
let (codegen_units, symbol_map) =
2594+
collect_and_partition_translation_items(&shared_ccx);
25922595
let codegen_unit_count = codegen_units.len();
25932596

25942597
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
25952598
tcx.sess.opts.debugging_opts.incremental.is_some());
25962599

2597-
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
2600+
let symbol_map = Rc::new(symbol_map);
25982601

2602+
let crate_context_list = CrateContextList::new(&shared_ccx,
2603+
codegen_units,
2604+
symbol_map.clone());
25992605
let modules = crate_context_list.iter()
26002606
.map(|ccx| ModuleTranslation {
26012607
name: String::from(&ccx.codegen_unit().name[..]),
@@ -2693,8 +2699,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26932699
let sess = shared_ccx.sess();
26942700
let mut reachable_symbols = shared_ccx.reachable().iter().map(|&id| {
26952701
let def_id = shared_ccx.tcx().map.local_def_id(id);
2696-
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
2702+
symbol_for_def_id(def_id, &shared_ccx, &symbol_map)
26972703
}).collect::<Vec<_>>();
2704+
26982705
if sess.entry_fn.borrow().is_some() {
26992706
reachable_symbols.push("main".to_string());
27002707
}
@@ -2716,7 +2723,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27162723
reachable_symbols.extend(syms.into_iter().filter(|did| {
27172724
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
27182725
}).map(|did| {
2719-
Instance::mono(&shared_ccx, did).symbol_name(&shared_ccx)
2726+
symbol_for_def_id(did, &shared_ccx, &symbol_map)
27202727
}));
27212728
}
27222729

@@ -2810,7 +2817,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
28102817
}
28112818

28122819
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
2813-
-> Vec<CodegenUnit<'tcx>> {
2820+
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
28142821
let time_passes = scx.sess().time_passes();
28152822

28162823
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
@@ -2833,10 +2840,13 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
28332840
None => TransItemCollectionMode::Lazy
28342841
};
28352842

2836-
let (items, inlining_map) = time(time_passes, "translation item collection", || {
2837-
collector::collect_crate_translation_items(&scx, collection_mode)
2843+
let (items, inlining_map) =
2844+
time(time_passes, "translation item collection", || {
2845+
collector::collect_crate_translation_items(&scx, collection_mode)
28382846
});
28392847

2848+
let symbol_map = SymbolMap::build(scx, items.iter().cloned());
2849+
28402850
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
28412851
PartitioningStrategy::PerModule
28422852
} else {
@@ -2910,5 +2920,24 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29102920
}
29112921
}
29122922

2913-
codegen_units
2923+
(codegen_units, symbol_map)
2924+
}
2925+
2926+
fn symbol_for_def_id<'a, 'tcx>(def_id: DefId,
2927+
scx: &SharedCrateContext<'a, 'tcx>,
2928+
symbol_map: &SymbolMap<'tcx>)
2929+
-> String {
2930+
// Just try to look things up in the symbol map. If nothing's there, we
2931+
// recompute.
2932+
if let Some(node_id) = scx.tcx().map.as_local_node_id(def_id) {
2933+
if let Some(sym) = symbol_map.get(TransItem::Static(node_id)) {
2934+
return sym.to_owned();
2935+
}
2936+
}
2937+
2938+
let instance = Instance::mono(scx, def_id);
2939+
2940+
symbol_map.get(TransItem::Fn(instance))
2941+
.map(str::to_owned)
2942+
.unwrap_or_else(|| instance.symbol_name(scx))
29142943
}

src/librustc_trans/callee.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use intrinsic;
4646
use machine::llalign_of_min;
4747
use meth;
4848
use monomorphize::{self, Instance};
49+
use trans_item::TransItem;
4950
use type_::Type;
5051
use type_of;
5152
use value::Value;
@@ -536,11 +537,18 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
536537
// reference. It also occurs when testing libcore and in some
537538
// other weird situations. Annoying.
538539

539-
let sym = instance.symbol_name(ccx.shared());
540+
// Let's see if we can get the symbol name from the symbol_map, so we don't
541+
// have to recompute it.
542+
let mut sym_data = String::new();
543+
let sym = ccx.symbol_map().get(TransItem::Fn(instance)).unwrap_or_else(|| {
544+
sym_data = instance.symbol_name(ccx.shared());
545+
&sym_data[..]
546+
});
547+
540548
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
541-
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
549+
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, sym) {
542550
if let Some(span) = local_item {
543-
if declare::get_defined_value(ccx, &sym).is_some() {
551+
if declare::get_defined_value(ccx, sym).is_some() {
544552
ccx.sess().span_fatal(span,
545553
&format!("symbol `{}` is already defined", sym));
546554
}
@@ -558,7 +566,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
558566
llfn
559567
}
560568
} else {
561-
let llfn = declare::declare_fn(ccx, &sym, ty);
569+
let llfn = declare::declare_fn(ccx, sym, ty);
562570
assert_eq!(common::val_ty(llfn), llptrty);
563571
debug!("get_fn: not casting pointer!");
564572

src/librustc_trans/consts.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,38 +1013,41 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10131013
return Datum::new(g, ty, Lvalue::new("static"));
10141014
}
10151015

1016-
let sym = instance.symbol_name(ccx.shared());
1017-
10181016
let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {
1017+
10191018
let llty = type_of::type_of(ccx, ty);
10201019
let (g, attrs) = match ccx.tcx().map.get(id) {
10211020
hir_map::NodeItem(&hir::Item {
10221021
ref attrs, span, node: hir::ItemStatic(..), ..
10231022
}) => {
1023+
let sym = ccx.symbol_map()
1024+
.get(TransItem::Static(id))
1025+
.expect("Local statics should always be in the SymbolMap");
10241026
// Make sure that this is never executed for something inlined.
10251027
assert!(!ccx.external_srcs().borrow().contains_key(&id));
10261028

10271029
let defined_in_current_codegen_unit = ccx.codegen_unit()
10281030
.items
10291031
.contains_key(&TransItem::Static(id));
10301032
if defined_in_current_codegen_unit {
1031-
if declare::get_declared_value(ccx, &sym).is_none() {
1033+
if declare::get_declared_value(ccx, sym).is_none() {
10321034
span_bug!(span, "trans: Static not properly pre-defined?");
10331035
}
10341036
} else {
1035-
if declare::get_declared_value(ccx, &sym).is_some() {
1037+
if declare::get_declared_value(ccx, sym).is_some() {
10361038
span_bug!(span, "trans: Conflicting symbol names for static?");
10371039
}
10381040
}
10391041

1040-
let g = declare::define_global(ccx, &sym, llty).unwrap();
1042+
let g = declare::define_global(ccx, sym, llty).unwrap();
10411043

10421044
(g, attrs)
10431045
}
10441046

10451047
hir_map::NodeForeignItem(&hir::ForeignItem {
10461048
ref attrs, span, node: hir::ForeignItemStatic(..), ..
10471049
}) => {
1050+
let sym = instance.symbol_name(ccx.shared());
10481051
let g = if let Some(name) =
10491052
attr::first_attr_value_str_by_name(&attrs, "linkage") {
10501053
// If this is a static with a linkage specified, then we need to handle
@@ -1079,7 +1082,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10791082
real_name.push_str(&sym);
10801083
let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{
10811084
ccx.sess().span_fatal(span,
1082-
&format!("symbol `{}` is already defined", sym))
1085+
&format!("symbol `{}` is already defined", &sym))
10831086
});
10841087
llvm::SetLinkage(g2, llvm::InternalLinkage);
10851088
llvm::LLVMSetInitializer(g2, g1);
@@ -1104,6 +1107,8 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
11041107

11051108
g
11061109
} else {
1110+
let sym = instance.symbol_name(ccx.shared());
1111+
11071112
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
11081113
// FIXME(nagisa): investigate whether it can be changed into define_global
11091114
let g = declare::declare_global(ccx, &sym, type_of::type_of(ccx, ty));

src/librustc_trans/context.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc::ty::subst::{Substs, VecPerParamSpace};
3535
use rustc::ty::{self, Ty, TyCtxt};
3636
use session::config::NoDebugInfo;
3737
use session::Session;
38+
use symbol_map::SymbolMap;
3839
use util::sha2::Sha256;
3940
use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap};
4041

@@ -171,6 +172,8 @@ pub struct LocalCrateContext<'tcx> {
171172

172173
/// Depth of the current type-of computation - used to bail out
173174
type_of_depth: Cell<usize>,
175+
176+
symbol_map: Rc<SymbolMap<'tcx>>,
174177
}
175178

176179
// Implement DepTrackingMapConfig for `trait_cache`
@@ -197,12 +200,13 @@ pub struct CrateContextList<'a, 'tcx: 'a> {
197200
impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
198201

199202
pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>,
200-
codegen_units: Vec<CodegenUnit<'tcx>>)
203+
codegen_units: Vec<CodegenUnit<'tcx>>,
204+
symbol_map: Rc<SymbolMap<'tcx>>)
201205
-> CrateContextList<'a, 'tcx> {
202206
CrateContextList {
203207
shared: shared_ccx,
204208
local_ccxs: codegen_units.into_iter().map(|codegen_unit| {
205-
LocalCrateContext::new(shared_ccx, codegen_unit)
209+
LocalCrateContext::new(shared_ccx, codegen_unit, symbol_map.clone())
206210
}).collect()
207211
}
208212
}
@@ -512,7 +516,8 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
512516

513517
impl<'tcx> LocalCrateContext<'tcx> {
514518
fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
515-
codegen_unit: CodegenUnit<'tcx>)
519+
codegen_unit: CodegenUnit<'tcx>,
520+
symbol_map: Rc<SymbolMap<'tcx>>)
516521
-> LocalCrateContext<'tcx> {
517522
unsafe {
518523
// Append ".rs" to LLVM module identifier.
@@ -571,6 +576,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
571576
intrinsics: RefCell::new(FnvHashMap()),
572577
n_llvm_insns: Cell::new(0),
573578
type_of_depth: Cell::new(0),
579+
symbol_map: symbol_map,
574580
};
575581

576582
let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@@ -890,6 +896,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
890896
self.shared.get_mir(def_id)
891897
}
892898

899+
pub fn symbol_map(&self) -> &SymbolMap<'tcx> {
900+
&*self.local().symbol_map
901+
}
902+
893903
pub fn translation_items(&self) -> &RefCell<FnvHashMap<TransItem<'tcx>, TransItemState>> {
894904
&self.shared.translation_items
895905
}

src/librustc_trans/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ mod meth;
122122
mod mir;
123123
mod monomorphize;
124124
mod partitioning;
125+
mod symbol_map;
125126
mod symbol_names_test;
126127
mod trans_item;
127128
mod tvec;

src/librustc_trans/monomorphize.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,24 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
8484
monomorphizing.insert(fn_id, depth + 1);
8585
}
8686

87-
let symbol = instance.symbol_name(ccx.shared());
87+
// Let's see if we can get the symbol name from the symbol_map, so we don't
88+
// have to recompute it.
89+
let mut sym_data = String::new();
90+
let symbol = ccx.symbol_map().get(TransItem::Fn(instance)).unwrap_or_else(|| {
91+
sym_data = instance.symbol_name(ccx.shared());
92+
&sym_data[..]
93+
});
8894

8995
debug!("monomorphize_fn mangled to {}", symbol);
90-
assert!(declare::get_defined_value(ccx, &symbol).is_none());
96+
assert!(declare::get_defined_value(ccx, symbol).is_none());
9197

9298
// FIXME(nagisa): perhaps needs a more fine grained selection?
93-
let lldecl = declare::define_internal_fn(ccx, &symbol, mono_ty);
99+
let lldecl = declare::define_internal_fn(ccx, symbol, mono_ty);
94100
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
95101
attributes::unwind(lldecl, true);
96102

97103
ccx.instances().borrow_mut().insert(instance, lldecl);
98104

99-
100105
// we can only monomorphize things in this crate (or inlined into it)
101106
let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap();
102107
let map_node = errors::expect(

0 commit comments

Comments
 (0)