Skip to content

Commit 7facdf4

Browse files
committed
add LinkageInfo to keep track of how we figured out the linkage
1 parent 8291d68 commit 7facdf4

File tree

7 files changed

+77
-29
lines changed

7 files changed

+77
-29
lines changed

compiler/rustc_codegen_cranelift/src/driver/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn predefine_mono_items<'tcx>(
3030
get_function_sig(tcx, module.target_config().default_call_conv, instance);
3131
let linkage = crate::linkage::get_clif_linkage(
3232
mono_item,
33-
data.linkage,
33+
data.linkage_info.into_linkage(),
3434
data.visibility,
3535
is_compiler_builtins,
3636
);

compiler/rustc_codegen_gcc/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ pub fn compile_codegen_unit(
202202

203203
let mono_items = cgu.items_in_deterministic_order(tcx);
204204
for &(mono_item, data) in &mono_items {
205-
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
205+
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage_info, data.visibility);
206206
}
207207

208208
// ... and now that we have everything pre-defined, fill out those definitions.

compiler/rustc_codegen_llvm/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
8383
let cx = CodegenCx::new(tcx, cgu, &llvm_module);
8484
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
8585
for &(mono_item, data) in &mono_items {
86-
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
86+
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage_info, data.visibility);
8787
}
8888

8989
// ... and now that we have everything pre-defined, fill out those definitions.

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ fn exported_symbols_provider_local(
307307
}
308308

309309
if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() {
310-
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
310+
use rustc_middle::mir::mono::{MonoItem, Visibility};
311311
use rustc_middle::ty::InstanceKind;
312312

313313
// Normally, we require that shared monomorphizations are not hidden,
@@ -322,7 +322,7 @@ fn exported_symbols_provider_local(
322322
// The symbols created in this loop are sorted below it
323323
#[allow(rustc::potential_query_instability)]
324324
for (mono_item, data) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
325-
if data.linkage != Linkage::External {
325+
if !data.linkage_info.is_external() {
326326
// We can only re-use things with external linkage, otherwise
327327
// we'll get a linker error
328328
continue;

compiler/rustc_codegen_ssa/src/mono_item.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_hir as hir;
22
use rustc_middle::mir::interpret::ErrorHandled;
3-
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
3+
use rustc_middle::mir::mono::{LinkageInfo, MonoItem, Visibility};
44
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
55
use rustc_middle::ty::Instance;
66
use rustc_middle::{span_bug, ty};
@@ -14,7 +14,7 @@ pub trait MonoItemExt<'a, 'tcx> {
1414
fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
1515
&self,
1616
cx: &'a Bx::CodegenCx,
17-
linkage: Linkage,
17+
linkage_info: LinkageInfo,
1818
visibility: Visibility,
1919
);
2020
fn to_raw_string(&self) -> String;
@@ -116,7 +116,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
116116
fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
117117
&self,
118118
cx: &'a Bx::CodegenCx,
119-
linkage: Linkage,
119+
linkage_info: LinkageInfo,
120120
visibility: Visibility,
121121
) {
122122
debug!(
@@ -132,10 +132,10 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
132132

133133
match *self {
134134
MonoItem::Static(def_id) => {
135-
cx.predefine_static(def_id, linkage, visibility, symbol_name);
135+
cx.predefine_static(def_id, linkage_info.into_linkage(), visibility, symbol_name);
136136
}
137137
MonoItem::Fn(instance) => {
138-
cx.predefine_fn(instance, linkage, visibility, symbol_name);
138+
cx.predefine_fn(instance, linkage_info.into_linkage(), visibility, symbol_name);
139139
}
140140
MonoItem::GlobalAsm(..) => {}
141141
}

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,57 @@ pub struct MonoItemData {
273273
/// `GloballyShared` maps to `false` and `LocalCopy` maps to `true`.
274274
pub inlined: bool,
275275

276-
pub linkage: Linkage,
276+
pub linkage_info: LinkageInfo,
277277
pub visibility: Visibility,
278278

279279
/// A cached copy of the result of `MonoItem::size_estimate`.
280280
pub size_estimate: usize,
281281
}
282282

283+
/// Stores how we know what linkage to use
284+
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
285+
pub enum LinkageInfo {
286+
/// The linkage was specified explicitly (e.g. using #[linkage = "..."])
287+
Explicit(Linkage),
288+
/// Assume the symbol may be used from other CGUs, a safe default
289+
ImplicitExternal,
290+
/// We did not find any uses from other CGUs, so it's fine to make this internal
291+
ImplicitInternal,
292+
}
293+
294+
impl LinkageInfo {
295+
pub const fn is_external(self) -> bool {
296+
matches!(self.into_linkage(), Linkage::External)
297+
}
298+
299+
pub const fn into_linkage(self) -> Linkage {
300+
match self {
301+
Self::Explicit(linkage) => linkage,
302+
Self::ImplicitExternal => Linkage::External,
303+
Self::ImplicitInternal => Linkage::Internal,
304+
}
305+
}
306+
307+
/// Linkage when the MonoItem is a naked function
308+
///
309+
/// Naked functions are generated as a separate declaration (effectively an extern fn) and
310+
/// definition (using global assembly). To link them together, some flavor of external linkage
311+
/// must be used.
312+
pub const fn into_naked_linkage(self) -> Linkage {
313+
match self {
314+
// promote Weak linkage to ExternalWeak
315+
Self::Explicit(Linkage::WeakAny | Linkage::WeakODR) => Linkage::ExternalWeak,
316+
Self::Explicit(linkage) => linkage,
317+
318+
// the "implicit" means that linkage is picked by the partitioning algorithm.
319+
// picking external should always be valid (given that we are in fact linking
320+
// to the global assembly in the same CGU)
321+
Self::ImplicitExternal => Linkage::External,
322+
Self::ImplicitInternal => Linkage::External,
323+
}
324+
}
325+
}
326+
283327
/// Specifies the linkage type for a `MonoItem`.
284328
///
285329
/// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants.

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ use rustc_middle::bug;
109109
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
110110
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
111111
use rustc_middle::mir::mono::{
112-
CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, MonoItemData,
113-
Visibility,
112+
CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, LinkageInfo, MonoItem,
113+
MonoItemData, Visibility,
114114
};
115115
use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
116116
use rustc_middle::ty::visit::TypeVisitableExt;
@@ -244,7 +244,7 @@ where
244244
let cgu = codegen_units.entry(cgu_name).or_insert_with(|| CodegenUnit::new(cgu_name));
245245

246246
let mut can_be_internalized = true;
247-
let (linkage, visibility) = mono_item_linkage_and_visibility(
247+
let (linkage_info, visibility) = mono_item_linkage_info_and_visibility(
248248
cx.tcx,
249249
&mono_item,
250250
&mut can_be_internalized,
@@ -255,8 +255,10 @@ where
255255
}
256256
let size_estimate = mono_item.size_estimate(cx.tcx);
257257

258-
cgu.items_mut()
259-
.insert(mono_item, MonoItemData { inlined: false, linkage, visibility, size_estimate });
258+
cgu.items_mut().insert(
259+
mono_item,
260+
MonoItemData { inlined: false, linkage_info, visibility, size_estimate },
261+
);
260262

261263
// Get all inlined items that are reachable from `mono_item` without
262264
// going via another root item. This includes drop-glue, functions from
@@ -272,7 +274,7 @@ where
272274
// This is a CGU-private copy.
273275
cgu.items_mut().entry(inlined_item).or_insert_with(|| MonoItemData {
274276
inlined: true,
275-
linkage: Linkage::Internal,
277+
linkage_info: LinkageInfo::ImplicitInternal,
276278
visibility: Visibility::Default,
277279
size_estimate: inlined_item.size_estimate(cx.tcx),
278280
});
@@ -585,7 +587,8 @@ fn internalize_symbols<'tcx>(
585587

586588
// If we got here, we did not find any uses from other CGUs, so
587589
// it's fine to make this monomorphization internal.
588-
data.linkage = Linkage::Internal;
590+
debug_assert_eq!(data.linkage_info, LinkageInfo::ImplicitExternal);
591+
data.linkage_info = LinkageInfo::ImplicitInternal;
589592
data.visibility = Visibility::Default;
590593
}
591594
}
@@ -603,7 +606,7 @@ fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>
603606
// function symbols to be included via `-u` or `/include` linker args.
604607
let dead_code_cgu = codegen_units
605608
.iter_mut()
606-
.filter(|cgu| cgu.items().iter().any(|(_, data)| data.linkage == Linkage::External))
609+
.filter(|cgu| cgu.items().iter().any(|(_, data)| data.linkage_info.is_external()))
607610
.min_by_key(|cgu| cgu.size_estimate());
608611

609612
// If there are no CGUs that have externally linked items, then we just
@@ -731,17 +734,18 @@ fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol {
731734
name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
732735
}
733736

734-
fn mono_item_linkage_and_visibility<'tcx>(
737+
fn mono_item_linkage_info_and_visibility<'tcx>(
735738
tcx: TyCtxt<'tcx>,
736739
mono_item: &MonoItem<'tcx>,
737740
can_be_internalized: &mut bool,
738741
export_generics: bool,
739-
) -> (Linkage, Visibility) {
742+
) -> (LinkageInfo, Visibility) {
740743
if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) {
741-
return (explicit_linkage, Visibility::Default);
744+
(LinkageInfo::Explicit(explicit_linkage), Visibility::Default)
745+
} else {
746+
let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics);
747+
(LinkageInfo::ImplicitExternal, vis)
742748
}
743-
let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics);
744-
(Linkage::External, vis)
745749
}
746750

747751
type CguNameCache = UnordMap<(DefId, bool), Symbol>;
@@ -1012,15 +1016,15 @@ fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<
10121016
writeln!(s, " - items: {num_items}, mean size: {mean_size:.1}, sizes: {sizes}",);
10131017

10141018
for (item, data) in cgu.items_in_deterministic_order(tcx) {
1015-
let linkage = data.linkage;
1019+
let linkage_info = data.linkage_info;
10161020
let symbol_name = item.symbol_name(tcx).name;
10171021
let symbol_hash_start = symbol_name.rfind('h');
10181022
let symbol_hash = symbol_hash_start.map_or("<no hash>", |i| &symbol_name[i..]);
10191023
let kind = if !data.inlined { "root" } else { "inlined" };
10201024
let size = data.size_estimate;
10211025
let _ = with_no_trimmed_paths!(writeln!(
10221026
s,
1023-
" - {item} [{linkage:?}] [{symbol_hash}] ({kind}, size: {size})"
1027+
" - {item} [{linkage_info:?}] [{symbol_hash}] ({kind}, size: {size})"
10241028
));
10251029
}
10261030

@@ -1173,7 +1177,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
11731177

11741178
for cgu in codegen_units {
11751179
for (&mono_item, &data) in cgu.items() {
1176-
item_to_cgus.entry(mono_item).or_default().push((cgu.name(), data.linkage));
1180+
item_to_cgus.entry(mono_item).or_default().push((cgu.name(), data.linkage_info));
11771181
}
11781182
}
11791183

@@ -1186,11 +1190,11 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
11861190
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
11871191
cgus.sort_by_key(|(name, _)| *name);
11881192
cgus.dedup();
1189-
for &(ref cgu_name, linkage) in cgus.iter() {
1193+
for &(ref cgu_name, linkage_info) in cgus.iter() {
11901194
output.push(' ');
11911195
output.push_str(cgu_name.as_str());
11921196

1193-
let linkage_abbrev = match linkage {
1197+
let linkage_abbrev = match linkage_info.into_linkage() {
11941198
Linkage::External => "External",
11951199
Linkage::AvailableExternally => "Available",
11961200
Linkage::LinkOnceAny => "OnceAny",

0 commit comments

Comments
 (0)