Skip to content

Commit 891c2a0

Browse files
trans: Make translation of statics collector-driven.
1 parent 3fa1cdf commit 891c2a0

File tree

3 files changed

+221
-137
lines changed

3 files changed

+221
-137
lines changed

src/librustc_trans/base.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,8 +2249,10 @@ pub fn update_linkage(ccx: &CrateContext,
22492249
}
22502250
}
22512251

2252-
fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) {
2253-
if let Some(sect) = attr::first_attr_value_str_by_name(&i.attrs, "link_section") {
2252+
pub fn set_link_section(ccx: &CrateContext,
2253+
llval: ValueRef,
2254+
attrs: &[ast::Attribute]) {
2255+
if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") {
22542256
if contains_null(&sect) {
22552257
ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
22562258
}
@@ -2280,7 +2282,7 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22802282
let empty_substs = ccx.empty_substs_for_def_id(def_id);
22812283
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
22822284
trans_fn(ccx, &decl, &body, llfn, empty_substs, item.id);
2283-
set_global_section(ccx, llfn, item);
2285+
set_link_section(ccx, llfn, &item.attrs);
22842286
update_linkage(ccx,
22852287
llfn,
22862288
Some(item.id),
@@ -2336,13 +2338,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
23362338
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
23372339
}
23382340
}
2339-
hir::ItemStatic(_, m, ref expr) => {
2340-
let g = match consts::trans_static(ccx, m, expr, item.id, &item.attrs) {
2341-
Ok(g) => g,
2342-
Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()),
2343-
};
2344-
set_global_section(ccx, g, item);
2345-
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
2341+
hir::ItemStatic(..) => {
2342+
// Don't do anything here. Translation of statics has been moved to
2343+
// being "collector-driven".
23462344
}
23472345
_ => {}
23482346
}
@@ -2700,6 +2698,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27002698

27012699
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
27022700
let codegen_unit_count = codegen_units.len();
2701+
27032702
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
27042703
tcx.sess.opts.debugging_opts.incremental.is_some());
27052704

@@ -2723,6 +2722,33 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27232722
};
27242723
}
27252724

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

src/librustc_trans/consts.rs

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

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

10381045
hir_map::NodeForeignItem(&hir::ForeignItem {
@@ -1083,17 +1090,19 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
10831090
declare::declare_global(ccx, &sym, llty)
10841091
};
10851092

1086-
for attr in attrs {
1087-
if attr.check_name("thread_local") {
1088-
llvm::set_thread_local(g, true);
1089-
}
1090-
}
1091-
1092-
g
1093+
(g, attrs)
10931094
}
10941095

10951096
item => bug!("get_static: expected static, found {:?}", item)
1097+
};
1098+
1099+
for attr in attrs {
1100+
if attr.check_name("thread_local") {
1101+
llvm::set_thread_local(g, true);
1102+
}
10961103
}
1104+
1105+
g
10971106
} else {
10981107
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
10991108
// FIXME(nagisa): investigate whether it can be changed into define_global
@@ -1197,6 +1206,9 @@ pub fn trans_static(ccx: &CrateContext,
11971206
"thread_local") {
11981207
llvm::set_thread_local(g, true);
11991208
}
1209+
1210+
base::set_link_section(ccx, g, attrs);
1211+
12001212
Ok(g)
12011213
}
12021214
}

0 commit comments

Comments
 (0)