Skip to content

Commit 63c65e3

Browse files
Build SymbolMap for symbol name conflict checking and caching.
1 parent 375c522 commit 63c65e3

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::codemap::{Span, DUMMY_SP};
@@ -2589,14 +2591,18 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
25892591
};
25902592
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
25912593

2592-
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2594+
let (codegen_units, symbol_map) =
2595+
collect_and_partition_translation_items(&shared_ccx);
25932596
let codegen_unit_count = codegen_units.len();
25942597

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

2598-
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
2601+
let symbol_map = Rc::new(symbol_map);
25992602

2603+
let crate_context_list = CrateContextList::new(&shared_ccx,
2604+
codegen_units,
2605+
symbol_map.clone());
26002606
let modules = crate_context_list.iter()
26012607
.map(|ccx| ModuleTranslation {
26022608
name: String::from(&ccx.codegen_unit().name[..]),
@@ -2694,8 +2700,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26942700
let sess = shared_ccx.sess();
26952701
let mut reachable_symbols = shared_ccx.reachable().iter().map(|&id| {
26962702
let def_id = shared_ccx.tcx().map.local_def_id(id);
2697-
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
2703+
symbol_for_def_id(def_id, &shared_ccx, &symbol_map)
26982704
}).collect::<Vec<_>>();
2705+
26992706
if sess.entry_fn.borrow().is_some() {
27002707
reachable_symbols.push("main".to_string());
27012708
}
@@ -2717,7 +2724,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27172724
reachable_symbols.extend(syms.into_iter().filter(|did| {
27182725
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
27192726
}).map(|did| {
2720-
Instance::mono(&shared_ccx, did).symbol_name(&shared_ccx)
2727+
symbol_for_def_id(did, &shared_ccx, &symbol_map)
27212728
}));
27222729
}
27232730

@@ -2811,7 +2818,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
28112818
}
28122819

28132820
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
2814-
-> Vec<CodegenUnit<'tcx>> {
2821+
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
28152822
let time_passes = scx.sess().time_passes();
28162823

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

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

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

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

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
@@ -1016,38 +1016,41 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10161016
return Datum::new(g, ty, Lvalue::new("static"));
10171017
}
10181018

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

10301032
let defined_in_current_codegen_unit = ccx.codegen_unit()
10311033
.items
10321034
.contains_key(&TransItem::Static(id));
10331035
if defined_in_current_codegen_unit {
1034-
if declare::get_declared_value(ccx, &sym).is_none() {
1036+
if declare::get_declared_value(ccx, sym).is_none() {
10351037
span_bug!(span, "trans: Static not properly pre-defined?");
10361038
}
10371039
} else {
1038-
if declare::get_declared_value(ccx, &sym).is_some() {
1040+
if declare::get_declared_value(ccx, sym).is_some() {
10391041
span_bug!(span, "trans: Conflicting symbol names for static?");
10401042
}
10411043
}
10421044

1043-
let g = declare::define_global(ccx, &sym, llty).unwrap();
1045+
let g = declare::define_global(ccx, sym, llty).unwrap();
10441046

10451047
(g, attrs)
10461048
}
10471049

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

11081111
g
11091112
} else {
1113+
let sym = instance.symbol_name(ccx.shared());
1114+
11101115
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
11111116
// FIXME(nagisa): investigate whether it can be changed into define_global
11121117
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
@@ -121,6 +121,7 @@ mod meth;
121121
mod mir;
122122
mod monomorphize;
123123
mod partitioning;
124+
mod symbol_map;
124125
mod symbol_names_test;
125126
mod trans_item;
126127
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)