Skip to content

Commit 5cea43c

Browse files
trans: Make translation of statics collector-driven.
1 parent 3c795e0 commit 5cea43c

File tree

3 files changed

+228
-147
lines changed

3 files changed

+228
-147
lines changed

src/librustc_trans/base.rs

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,18 +2257,17 @@ pub fn update_linkage(ccx: &CrateContext,
22572257
}
22582258
}
22592259

2260-
fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) {
2261-
match attr::first_attr_value_str_by_name(&i.attrs, "link_section") {
2262-
Some(sect) => {
2263-
if contains_null(&sect) {
2264-
ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
2265-
}
2266-
unsafe {
2267-
let buf = CString::new(sect.as_bytes()).unwrap();
2268-
llvm::LLVMSetSection(llval, buf.as_ptr());
2269-
}
2270-
},
2271-
None => ()
2260+
pub fn set_link_section(ccx: &CrateContext,
2261+
llval: ValueRef,
2262+
attrs: &[ast::Attribute]) {
2263+
if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") {
2264+
if contains_null(&sect) {
2265+
ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
2266+
}
2267+
unsafe {
2268+
let buf = CString::new(sect.as_bytes()).unwrap();
2269+
llvm::LLVMSetSection(llval, buf.as_ptr());
2270+
}
22722271
}
22732272
}
22742273

@@ -2291,7 +2290,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22912290
let empty_substs = ccx.empty_substs_for_def_id(def_id);
22922291
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
22932292
trans_fn(ccx, &decl, &body, llfn, empty_substs, item.id);
2294-
set_global_section(ccx, llfn, item);
2293+
set_link_section(ccx, llfn, &item.attrs);
22952294
update_linkage(ccx,
22962295
llfn,
22972296
Some(item.id),
@@ -2347,13 +2346,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
23472346
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
23482347
}
23492348
}
2350-
hir::ItemStatic(_, m, ref expr) => {
2351-
let g = match consts::trans_static(ccx, m, expr, item.id, &item.attrs) {
2352-
Ok(g) => g,
2353-
Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()),
2354-
};
2355-
set_global_section(ccx, g, item);
2356-
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
2349+
hir::ItemStatic(..) => {
2350+
// Don't do anything here. Translation of statics has been moved to
2351+
// being "collector-driven".
23572352
}
23582353
_ => {}
23592354
}
@@ -2711,6 +2706,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27112706

27122707
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
27132708
let codegen_unit_count = codegen_units.len();
2709+
27142710
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
27152711
tcx.sess.opts.debugging_opts.incremental.is_some());
27162712

@@ -2734,6 +2730,33 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27342730
};
27352731
}
27362732

2733+
// Instantiate translation items without filling out definitions yet...
2734+
for ccx in crate_context_list.iter() {
2735+
for (&trans_item, &linkage) in &ccx.codegen_unit().items {
2736+
trans_item.predefine(&ccx, linkage);
2737+
}
2738+
}
2739+
2740+
// ... and now that we have everything pre-defined, fill out those definitions.
2741+
for ccx in crate_context_list.iter() {
2742+
for (&trans_item, _) in &ccx.codegen_unit().items {
2743+
match trans_item {
2744+
TransItem::Static(node_id) => {
2745+
let item = ccx.tcx().map.expect_item(node_id);
2746+
if let hir::ItemStatic(_, m, ref expr) = item.node {
2747+
match consts::trans_static(&ccx, m, expr, item.id, &item.attrs) {
2748+
Ok(_) => { /* Cool, everything's alright. */ },
2749+
Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()),
2750+
};
2751+
} else {
2752+
span_bug!(item.span, "Mismatch between hir::Item type and TransItem type")
2753+
}
2754+
}
2755+
_ => { }
2756+
}
2757+
}
2758+
}
2759+
27372760
{
27382761
let ccx = crate_context_list.get_ccx(0);
27392762

src/librustc_trans/consts.rs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,22 +1021,29 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10211021

10221022
let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {
10231023
let llty = type_of::type_of(ccx, ty);
1024-
match ccx.tcx().map.get(id) {
1024+
let (g, attrs) = match ccx.tcx().map.get(id) {
10251025
hir_map::NodeItem(&hir::Item {
1026-
span, node: hir::ItemStatic(..), ..
1026+
ref attrs, span, node: hir::ItemStatic(..), ..
10271027
}) => {
1028-
// If this static came from an external crate, then
1029-
// we need to get the symbol from metadata instead of
1030-
// using the current crate's name/version
1031-
// information in the hash of the symbol
1032-
debug!("making {}", sym);
1033-
1034-
// Create the global before evaluating the initializer;
1035-
// this is necessary to allow recursive statics.
1036-
declare::define_global(ccx, &sym, llty).unwrap_or_else(|| {
1037-
ccx.sess().span_fatal(span,
1038-
&format!("symbol `{}` is already defined", sym))
1039-
})
1028+
// Make sure that this is never executed for something inlined.
1029+
assert!(!ccx.external_srcs().borrow().contains_key(&id));
1030+
1031+
let defined_in_current_codegen_unit = ccx.codegen_unit()
1032+
.items
1033+
.contains_key(&TransItem::Static(id));
1034+
if defined_in_current_codegen_unit {
1035+
if declare::get_declared_value(ccx, &sym).is_none() {
1036+
span_bug!(span, "trans: Static not properly pre-defined?");
1037+
}
1038+
} else {
1039+
if declare::get_declared_value(ccx, &sym).is_some() {
1040+
span_bug!(span, "trans: Conflicting symbol names for static?");
1041+
}
1042+
}
1043+
1044+
let g = declare::define_global(ccx, &sym, llty).unwrap();
1045+
1046+
(g, attrs)
10401047
}
10411048

10421049
hir_map::NodeForeignItem(&hir::ForeignItem {
@@ -1087,17 +1094,19 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10871094
declare::declare_global(ccx, &sym, llty)
10881095
};
10891096

1090-
for attr in attrs {
1091-
if attr.check_name("thread_local") {
1092-
llvm::set_thread_local(g, true);
1093-
}
1094-
}
1095-
1096-
g
1097+
(g, attrs)
10971098
}
10981099

10991100
item => bug!("get_static: expected static, found {:?}", item)
1101+
};
1102+
1103+
for attr in attrs {
1104+
if attr.check_name("thread_local") {
1105+
llvm::set_thread_local(g, true);
1106+
}
11001107
}
1108+
1109+
g
11011110
} else {
11021111
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
11031112
// FIXME(nagisa): investigate whether it can be changed into define_global
@@ -1201,6 +1210,9 @@ pub fn trans_static(ccx: &CrateContext,
12011210
"thread_local") {
12021211
llvm::set_thread_local(g, true);
12031212
}
1213+
1214+
base::set_link_section(ccx, g, attrs);
1215+
12041216
Ok(g)
12051217
}
12061218
}

0 commit comments

Comments
 (0)