Skip to content

Commit 4b09506

Browse files
Build SymbolMap for symbol name conflict checking and caching.
1 parent 4595f03 commit 4b09506

File tree

8 files changed

+236
-53
lines changed

8 files changed

+236
-53
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::codemap::{Span, DUMMY_SP};
@@ -2595,14 +2597,18 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
25952597
};
25962598
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
25972599

2598-
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2600+
let (codegen_units, symbol_map) =
2601+
collect_and_partition_translation_items(&shared_ccx);
25992602
let codegen_unit_count = codegen_units.len();
26002603

26012604
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
26022605
tcx.sess.opts.debugging_opts.incremental.is_some());
26032606

2604-
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
2607+
let symbol_map = Rc::new(symbol_map);
26052608

2609+
let crate_context_list = CrateContextList::new(&shared_ccx,
2610+
codegen_units,
2611+
symbol_map.clone());
26062612
let modules = crate_context_list.iter()
26072613
.map(|ccx| ModuleTranslation {
26082614
name: String::from(&ccx.codegen_unit().name[..]),
@@ -2700,8 +2706,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27002706
let sess = shared_ccx.sess();
27012707
let mut reachable_symbols = shared_ccx.reachable().iter().map(|&id| {
27022708
let def_id = shared_ccx.tcx().map.local_def_id(id);
2703-
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
2709+
symbol_for_def_id(def_id, &shared_ccx, &symbol_map)
27042710
}).collect::<Vec<_>>();
2711+
27052712
if sess.entry_fn.borrow().is_some() {
27062713
reachable_symbols.push("main".to_string());
27072714
}
@@ -2723,7 +2730,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27232730
reachable_symbols.extend(syms.into_iter().filter(|did| {
27242731
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
27252732
}).map(|did| {
2726-
Instance::mono(&shared_ccx, did).symbol_name(&shared_ccx)
2733+
symbol_for_def_id(did, &shared_ccx, &symbol_map)
27272734
}));
27282735
}
27292736

@@ -2817,7 +2824,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
28172824
}
28182825

28192826
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
2820-
-> Vec<CodegenUnit<'tcx>> {
2827+
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
28212828
let time_passes = scx.sess().time_passes();
28222829

28232830
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
@@ -2840,10 +2847,13 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
28402847
None => TransItemCollectionMode::Lazy
28412848
};
28422849

2843-
let (items, inlining_map) = time(time_passes, "translation item collection", || {
2844-
collector::collect_crate_translation_items(&scx, collection_mode)
2850+
let (items, inlining_map) =
2851+
time(time_passes, "translation item collection", || {
2852+
collector::collect_crate_translation_items(&scx, collection_mode)
28452853
});
28462854

2855+
let symbol_map = SymbolMap::build(scx, items.iter().cloned());
2856+
28472857
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
28482858
PartitioningStrategy::PerModule
28492859
} else {
@@ -2917,5 +2927,24 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29172927
}
29182928
}
29192929

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

src/librustc_trans/callee.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use intrinsic;
4747
use machine::{llalign_of_min, llsize_of_store};
4848
use meth;
4949
use monomorphize::{self, Instance};
50+
use trans_item::TransItem;
5051
use type_::Type;
5152
use type_of;
5253
use value::Value;
@@ -539,11 +540,18 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
539540
// reference. It also occurs when testing libcore and in some
540541
// other weird situations. Annoying.
541542

542-
let sym = instance.symbol_name(ccx.shared());
543+
// Let's see if we can get the symbol name from the symbol_map, so we don't
544+
// have to recompute it.
545+
let mut sym_data = String::new();
546+
let sym = ccx.symbol_map().get(TransItem::Fn(instance)).unwrap_or_else(|| {
547+
sym_data = instance.symbol_name(ccx.shared());
548+
&sym_data[..]
549+
});
550+
543551
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
544-
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
552+
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, sym) {
545553
if let Some(span) = local_item {
546-
if declare::get_defined_value(ccx, &sym).is_some() {
554+
if declare::get_defined_value(ccx, sym).is_some() {
547555
ccx.sess().span_fatal(span,
548556
&format!("symbol `{}` is already defined", sym));
549557
}
@@ -561,7 +569,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
561569
llfn
562570
}
563571
} else {
564-
let llfn = declare::declare_fn(ccx, &sym, ty);
572+
let llfn = declare::declare_fn(ccx, sym, ty);
565573
assert_eq!(common::val_ty(llfn), llptrty);
566574
debug!("get_fn: not casting pointer!");
567575

src/librustc_trans/consts.rs

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

1020-
let sym = instance.symbol_name(ccx.shared());
1021-
10221020
let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {
1021+
10231022
let llty = type_of::type_of(ccx, ty);
10241023
let (g, attrs) = match ccx.tcx().map.get(id) {
10251024
hir_map::NodeItem(&hir::Item {
10261025
ref attrs, span, node: hir::ItemStatic(..), ..
10271026
}) => {
1027+
let sym = ccx.symbol_map()
1028+
.get(TransItem::Static(id))
1029+
.expect("Local statics should always be in the SymbolMap");
10281030
// Make sure that this is never executed for something inlined.
10291031
assert!(!ccx.external_srcs().borrow().contains_key(&id));
10301032

10311033
let defined_in_current_codegen_unit = ccx.codegen_unit()
10321034
.items
10331035
.contains_key(&TransItem::Static(id));
10341036
if defined_in_current_codegen_unit {
1035-
if declare::get_declared_value(ccx, &sym).is_none() {
1037+
if declare::get_declared_value(ccx, sym).is_none() {
10361038
span_bug!(span, "trans: Static not properly pre-defined?");
10371039
}
10381040
} else {
1039-
if declare::get_declared_value(ccx, &sym).is_some() {
1041+
if declare::get_declared_value(ccx, sym).is_some() {
10401042
span_bug!(span, "trans: Conflicting symbol names for static?");
10411043
}
10421044
}
10431045

1044-
let g = declare::define_global(ccx, &sym, llty).unwrap();
1046+
let g = declare::define_global(ccx, sym, llty).unwrap();
10451047

10461048
(g, attrs)
10471049
}
10481050

10491051
hir_map::NodeForeignItem(&hir::ForeignItem {
10501052
ref attrs, span, node: hir::ForeignItemStatic(..), ..
10511053
}) => {
1054+
let sym = instance.symbol_name(ccx.shared());
10521055
let g = if let Some(name) =
10531056
attr::first_attr_value_str_by_name(&attrs, "linkage") {
10541057
// If this is a static with a linkage specified, then we need to handle
@@ -1083,7 +1086,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10831086
real_name.push_str(&sym);
10841087
let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{
10851088
ccx.sess().span_fatal(span,
1086-
&format!("symbol `{}` is already defined", sym))
1089+
&format!("symbol `{}` is already defined", &sym))
10871090
});
10881091
llvm::SetLinkage(g2, llvm::InternalLinkage);
10891092
llvm::LLVMSetInitializer(g2, g1);
@@ -1108,6 +1111,8 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
11081111

11091112
g
11101113
} else {
1114+
let sym = instance.symbol_name(ccx.shared());
1115+
11111116
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
11121117
// FIXME(nagisa): investigate whether it can be changed into define_global
11131118
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
@@ -87,19 +87,24 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
8787
monomorphizing.insert(fn_id, depth + 1);
8888
}
8989

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

9298
debug!("monomorphize_fn mangled to {}", symbol);
93-
assert!(declare::get_defined_value(ccx, &symbol).is_none());
99+
assert!(declare::get_defined_value(ccx, symbol).is_none());
94100

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

100106
ccx.instances().borrow_mut().insert(instance, lldecl);
101107

102-
103108
// we can only monomorphize things in this crate (or inlined into it)
104109
let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap();
105110
let map_node = errors::expect(

0 commit comments

Comments
 (0)