Skip to content

Commit 1c03bfe

Browse files
trans: Adjust linkage assignment so that we don't need weak linkage.
1 parent 051d391 commit 1c03bfe

10 files changed

+85
-60
lines changed

src/librustc_trans/glue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
255255
// on MIR. Thus, we'll instantiate the missing function on demand in
256256
// this codegen unit, so that things keep working.
257257

258-
TransItem::DropGlue(g).predefine(ccx, llvm::LinkOnceODRLinkage);
258+
TransItem::DropGlue(g).predefine(ccx, llvm::InternalLinkage);
259259
TransItem::DropGlue(g).define(ccx);
260260

261261
// Now that we made sure that the glue function is in ccx.drop_glues,

src/librustc_trans/monomorphize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
137137
ccx.stats().n_fallback_instantiations.set(ccx.stats()
138138
.n_fallback_instantiations
139139
.get() + 1);
140-
trans_item.predefine(ccx, llvm::PrivateLinkage);
140+
trans_item.predefine(ccx, llvm::InternalLinkage);
141141
trans_item.define(ccx);
142142
}
143143
}

src/librustc_trans/partitioning.rs

+54-34
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,11 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
265265
let mut codegen_units = FnvHashMap();
266266

267267
for trans_item in trans_items {
268-
let is_root = match trans_item {
269-
TransItem::Static(..) => true,
270-
TransItem::DropGlue(..) => false,
271-
TransItem::Fn(_) => !trans_item.is_from_extern_crate(),
272-
};
268+
let is_root = !trans_item.is_instantiated_only_on_demand();
273269

274270
if is_root {
275271
let characteristic_def_id = characteristic_def_id_of_trans_item(tcx, trans_item);
276-
let is_volatile = trans_item.is_lazily_instantiated();
272+
let is_volatile = trans_item.is_generic_fn();
277273

278274
let codegen_unit_name = match characteristic_def_id {
279275
Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
@@ -304,9 +300,9 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
304300
// it might be used in another codegen unit.
305301
llvm::ExternalLinkage
306302
} else {
307-
// Monomorphizations of generic functions are
308-
// always weak-odr
309-
llvm::WeakODRLinkage
303+
// In the current setup, generic functions cannot
304+
// be roots.
305+
unreachable!()
310306
}
311307
}
312308
}
@@ -395,25 +391,30 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
395391
if let Some(linkage) = codegen_unit.items.get(&trans_item) {
396392
// This is a root, just copy it over
397393
new_codegen_unit.items.insert(trans_item, *linkage);
394+
} else if initial_partitioning.roots.contains(&trans_item) {
395+
// This item will be instantiated in some other codegen unit,
396+
// so we just add it here with AvailableExternallyLinkage
397+
// FIXME(mw): I have not seen it happening yet but having
398+
// available_externally here could potentially lead
399+
// to the same problem with exception handling tables
400+
// as in the case below.
401+
new_codegen_unit.items.insert(trans_item,
402+
llvm::AvailableExternallyLinkage);
403+
} else if trans_item.is_from_extern_crate() && !trans_item.is_generic_fn() {
404+
// FIXME(mw): It would be nice if we could mark these as
405+
// `AvailableExternallyLinkage`, since they should have
406+
// been instantiated in the extern crate. But this
407+
// sometimes leads to crashes on Windows because LLVM
408+
// does not handle exception handling table instantiation
409+
// reliably in that case.
410+
new_codegen_unit.items.insert(trans_item, llvm::InternalLinkage);
398411
} else {
399-
if initial_partitioning.roots.contains(&trans_item) {
400-
// This item will be instantiated in some other codegen unit,
401-
// so we just add it here with AvailableExternallyLinkage
402-
new_codegen_unit.items.insert(trans_item,
403-
llvm::AvailableExternallyLinkage);
404-
} else if trans_item.is_from_extern_crate() && !trans_item.is_generic_fn() {
405-
// An instantiation of this item is always available in the
406-
// crate it was imported from.
407-
new_codegen_unit.items.insert(trans_item,
408-
llvm::AvailableExternallyLinkage);
409-
} else {
410-
// We can't be sure if this will also be instantiated
411-
// somewhere else, so we add an instance here with
412-
// LinkOnceODRLinkage. That way the item can be discarded if
413-
// it's not needed (inlined) after all.
414-
new_codegen_unit.items.insert(trans_item,
415-
llvm::LinkOnceODRLinkage);
416-
}
412+
assert!(trans_item.is_instantiated_only_on_demand());
413+
// We can't be sure if this will also be instantiated
414+
// somewhere else, so we add an instance here with
415+
// InternalLinkage so we don't get any conflicts.
416+
new_codegen_unit.items.insert(trans_item,
417+
llvm::InternalLinkage);
417418
}
418419
}
419420

@@ -521,17 +522,36 @@ fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
521522
}
522523
}
523524
TransItem::DropGlue(_) => {
524-
llvm::PrivateLinkage
525+
llvm::InternalLinkage
525526
}
526527
TransItem::Fn(instance) => {
527-
if trans_item.is_generic_fn() ||
528-
trans_item.is_from_extern_crate() ||
529-
!reachable.contains(&tcx.map
530-
.as_local_node_id(instance.def)
531-
.unwrap()) {
528+
if trans_item.is_generic_fn() {
529+
// FIXME(mw): Assigning internal linkage to all
530+
// monomorphizations is potentially a waste of space
531+
// since monomorphizations could be shared between
532+
// crates. The main reason for making them internal is
533+
// a limitation in MingW's binutils that cannot deal
534+
// with COFF object that have more than 2^15 sections,
535+
// which is something that can happen for large programs
536+
// when every function gets put into its own COMDAT
537+
// section.
532538
llvm::InternalLinkage
533-
} else {
539+
} else if trans_item.is_from_extern_crate() {
540+
// FIXME(mw): It would be nice if we could mark these as
541+
// `AvailableExternallyLinkage`, since they should have
542+
// been instantiated in the extern crate. But this
543+
// sometimes leads to crashes on Windows because LLVM
544+
// does not handle exception handling table instantiation
545+
// reliably in that case.
546+
llvm::InternalLinkage
547+
} else if reachable.contains(&tcx.map
548+
.as_local_node_id(instance.def)
549+
.unwrap()) {
534550
llvm::ExternalLinkage
551+
} else {
552+
// Functions that are not visible outside this crate can
553+
// be marked as internal.
554+
llvm::InternalLinkage
535555
}
536556
}
537557
}

src/librustc_trans/trans_item.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,10 @@ impl<'a, 'tcx> TransItem<'tcx> {
256256
pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
257257
match *self {
258258
TransItem::Fn(ref instance) => {
259-
let attributes = tcx.get_attrs(instance.def);
260-
attr::requests_inline(&attributes[..])
259+
!instance.substs.types.is_empty() || {
260+
let attributes = tcx.get_attrs(instance.def);
261+
attr::requests_inline(&attributes[..])
262+
}
261263
}
262264
TransItem::DropGlue(..) => true,
263265
TransItem::Static(..) => false,
@@ -272,9 +274,10 @@ impl<'a, 'tcx> TransItem<'tcx> {
272274
}
273275
}
274276

275-
pub fn is_lazily_instantiated(&self) -> bool {
277+
pub fn is_instantiated_only_on_demand(&self) -> bool {
276278
match *self {
277-
TransItem::Fn(ref instance) => !instance.substs.types.is_empty(),
279+
TransItem::Fn(ref instance) => !instance.def.is_local() ||
280+
!instance.substs.types.is_empty(),
278281
TransItem::DropGlue(..) => true,
279282
TransItem::Static(..) => false,
280283
}

src/test/codegen-units/partitioning/extern-drop-glue.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
// aux-build:cgu_extern_drop_glue.rs
2121
extern crate cgu_extern_drop_glue;
2222

23-
//~ TRANS_ITEM drop-glue cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[OnceODR] extern_drop_glue-mod1[OnceODR]
24-
//~ TRANS_ITEM drop-glue-contents cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[OnceODR] extern_drop_glue-mod1[OnceODR]
23+
//~ TRANS_ITEM drop-glue cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
24+
//~ TRANS_ITEM drop-glue-contents cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
2525

2626
struct LocalStruct(cgu_extern_drop_glue::Struct);
2727

2828
//~ TRANS_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
2929
fn user()
3030
{
31-
//~ TRANS_ITEM drop-glue extern_drop_glue::LocalStruct[0] @@ extern_drop_glue[OnceODR]
31+
//~ TRANS_ITEM drop-glue extern_drop_glue::LocalStruct[0] @@ extern_drop_glue[Internal]
3232
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
3333
}
3434

@@ -40,7 +40,7 @@ mod mod1 {
4040
//~ TRANS_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
4141
fn user()
4242
{
43-
//~ TRANS_ITEM drop-glue extern_drop_glue::mod1[0]::LocalStruct[0] @@ extern_drop_glue-mod1[OnceODR]
43+
//~ TRANS_ITEM drop-glue extern_drop_glue::mod1[0]::LocalStruct[0] @@ extern_drop_glue-mod1[Internal]
4444
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
4545
}
4646
}

src/test/codegen-units/partitioning/extern-generic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ mod mod3 {
5858

5959
// Make sure the two generic functions from the extern crate get instantiated
6060
// privately in every module they are use in.
61-
//~ TRANS_ITEM fn cgu_generic_function::foo[0]<&str> @@ extern_generic[OnceODR] extern_generic-mod1[OnceODR] extern_generic-mod2[OnceODR] extern_generic-mod1-mod1[OnceODR]
62-
//~ TRANS_ITEM fn cgu_generic_function::bar[0]<&str> @@ extern_generic[OnceODR] extern_generic-mod1[OnceODR] extern_generic-mod2[OnceODR] extern_generic-mod1-mod1[OnceODR]
61+
//~ TRANS_ITEM fn cgu_generic_function::foo[0]<&str> @@ extern_generic[Internal] extern_generic-mod1[Internal] extern_generic-mod2[Internal] extern_generic-mod1-mod1[Internal]
62+
//~ TRANS_ITEM fn cgu_generic_function::bar[0]<&str> @@ extern_generic[Internal] extern_generic-mod1[Internal] extern_generic-mod2[Internal] extern_generic-mod1-mod1[Internal]
6363

6464
//~ TRANS_ITEM drop-glue i8

src/test/codegen-units/partitioning/inlining-from-extern-crate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ extern crate cgu_explicit_inlining;
2121
// This test makes sure that items inlined from external crates are privately
2222
// instantiated in every codegen unit they are used in.
2323

24-
//~ TRANS_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[Available] inlining_from_extern_crate-mod1[Available]
25-
//~ TRANS_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[Available] inlining_from_extern_crate-mod2[Available]
24+
//~ TRANS_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal]
25+
//~ TRANS_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal]
2626

2727
//~ TRANS_ITEM fn inlining_from_extern_crate::user[0] @@ inlining_from_extern_crate[External]
2828
pub fn user()

src/test/codegen-units/partitioning/local-drop-glue.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
#![allow(dead_code)]
1717
#![crate_type="lib"]
1818

19-
//~ TRANS_ITEM drop-glue local_drop_glue::Struct[0] @@ local_drop_glue[OnceODR] local_drop_glue-mod1[OnceODR]
20-
//~ TRANS_ITEM drop-glue-contents local_drop_glue::Struct[0] @@ local_drop_glue[OnceODR] local_drop_glue-mod1[OnceODR]
19+
//~ TRANS_ITEM drop-glue local_drop_glue::Struct[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
20+
//~ TRANS_ITEM drop-glue-contents local_drop_glue::Struct[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
2121
struct Struct {
2222
_a: u32
2323
}
@@ -27,7 +27,7 @@ impl Drop for Struct {
2727
fn drop(&mut self) {}
2828
}
2929

30-
//~ TRANS_ITEM drop-glue local_drop_glue::Outer[0] @@ local_drop_glue[OnceODR]
30+
//~ TRANS_ITEM drop-glue local_drop_glue::Outer[0] @@ local_drop_glue[Internal]
3131
struct Outer {
3232
_a: Struct
3333
}
@@ -46,10 +46,10 @@ mod mod1
4646
{
4747
use super::Struct;
4848

49-
//~ TRANS_ITEM drop-glue local_drop_glue::mod1[0]::Struct2[0] @@ local_drop_glue-mod1[OnceODR]
49+
//~ TRANS_ITEM drop-glue local_drop_glue::mod1[0]::Struct2[0] @@ local_drop_glue-mod1[Internal]
5050
struct Struct2 {
5151
_a: Struct,
52-
//~ TRANS_ITEM drop-glue (u32, local_drop_glue::Struct[0]) @@ local_drop_glue-mod1[OnceODR]
52+
//~ TRANS_ITEM drop-glue (u32, local_drop_glue::Struct[0]) @@ local_drop_glue-mod1[Internal]
5353
_b: (u32, Struct),
5454
}
5555

src/test/codegen-units/partitioning/local-generic.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@
1616
#![allow(dead_code)]
1717
#![crate_type="lib"]
1818

19-
// Used in different modules/codegen units but always instantiated in the same
20-
// codegen unit.
21-
22-
//~ TRANS_ITEM fn local_generic::generic[0]<u32> @@ local_generic.volatile[WeakODR]
23-
//~ TRANS_ITEM fn local_generic::generic[0]<u64> @@ local_generic.volatile[WeakODR]
24-
//~ TRANS_ITEM fn local_generic::generic[0]<char> @@ local_generic.volatile[WeakODR]
25-
//~ TRANS_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[WeakODR]
19+
//~ TRANS_ITEM fn local_generic::generic[0]<u32> @@ local_generic[Internal]
20+
//~ TRANS_ITEM fn local_generic::generic[0]<u64> @@ local_generic-mod1[Internal]
21+
//~ TRANS_ITEM fn local_generic::generic[0]<char> @@ local_generic-mod1-mod1[Internal]
22+
//~ TRANS_ITEM fn local_generic::generic[0]<&str> @@ local_generic-mod2[Internal]
2623
pub fn generic<T>(x: T) -> T { x }
2724

2825
//~ TRANS_ITEM fn local_generic::user[0] @@ local_generic[External]

src/test/codegen-units/partitioning/methods-are-with-self-type.rs

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// Currently, all generic functions are instantiated in each codegen unit that
12+
// uses them, even those not marked with #[inline], so this test does not make
13+
// much sense at the moment.
14+
// ignore-test
15+
1116
// ignore-tidy-linelength
1217
// We specify -Z incremental here because we want to test the partitioning for
1318
// incremental compilation

0 commit comments

Comments
 (0)