Skip to content

Commit 636f4f1

Browse files
authored
Rollup merge of #137313 - oli-obk:push-ywvuqkxuqyom, r=petrochenkov
Some codegen_llvm cleanups Using some more safe wrappers and thus being able to remove a large unsafe block. As a next step we should probably look into safe extern fns
2 parents 1f6c75e + ce7f58b commit 636f4f1

File tree

5 files changed

+79
-85
lines changed

5 files changed

+79
-85
lines changed

Diff for: compiler/rustc_codegen_llvm/src/back/lto.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ fn fat_lto(
362362
ptr as *const *const libc::c_char,
363363
symbols_below_threshold.len() as libc::size_t,
364364
);
365-
save_temp_bitcode(cgcx, &module, "lto.after-restriction");
366365
}
366+
save_temp_bitcode(cgcx, &module, "lto.after-restriction");
367367
}
368368

369369
Ok(LtoModuleCodegen::Fat(module))

Diff for: compiler/rustc_codegen_llvm/src/callee.rs

+50-56
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
6666
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
6767
// existing logic below to set the Storage Class, but it has an
6868
// exemption for MinGW for backwards compatibility.
69-
unsafe {
70-
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
71-
}
69+
llvm::set_dllimport_storage_class(llfn);
7270
llfn
7371
} else {
7472
cx.declare_fn(sym, fn_abi, Some(instance))
@@ -99,65 +97,61 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
9997
// has been applied to the definition (wherever that definition may be).
10098

10199
llvm::set_linkage(llfn, llvm::Linkage::ExternalLinkage);
102-
unsafe {
103-
let is_generic = instance.args.non_erasable_generics().next().is_some();
104-
105-
let is_hidden = if is_generic {
106-
// This is a monomorphization of a generic function.
107-
if !(cx.tcx.sess.opts.share_generics()
108-
|| tcx.codegen_fn_attrs(instance_def_id).inline
109-
== rustc_attr_parsing::InlineAttr::Never)
110-
{
111-
// When not sharing generics, all instances are in the same
112-
// crate and have hidden visibility.
113-
true
114-
} else {
115-
if let Some(instance_def_id) = instance_def_id.as_local() {
116-
// This is a monomorphization of a generic function
117-
// defined in the current crate. It is hidden if:
118-
// - the definition is unreachable for downstream
119-
// crates, or
120-
// - the current crate does not re-export generics
121-
// (because the crate is a C library or executable)
122-
cx.tcx.is_unreachable_local_definition(instance_def_id)
123-
|| !cx.tcx.local_crate_exports_generics()
124-
} else {
125-
// This is a monomorphization of a generic function
126-
// defined in an upstream crate. It is hidden if:
127-
// - it is instantiated in this crate, and
128-
// - the current crate does not re-export generics
129-
instance.upstream_monomorphization(tcx).is_none()
130-
&& !cx.tcx.local_crate_exports_generics()
131-
}
132-
}
133-
} else {
134-
// This is a non-generic function. It is hidden if:
135-
// - it is instantiated in the local crate, and
136-
// - it is defined an upstream crate (non-local), or
137-
// - it is not reachable
138-
cx.tcx.is_codegened_item(instance_def_id)
139-
&& (!instance_def_id.is_local()
140-
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
141-
};
142-
if is_hidden {
143-
llvm::set_visibility(llfn, llvm::Visibility::Hidden);
144-
}
100+
let is_generic = instance.args.non_erasable_generics().next().is_some();
145101

146-
// MinGW: For backward compatibility we rely on the linker to decide whether it
147-
// should use dllimport for functions.
148-
if cx.use_dll_storage_attrs
149-
&& let Some(library) = tcx.native_library(instance_def_id)
150-
&& library.kind.is_dllimport()
151-
&& !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
102+
let is_hidden = if is_generic {
103+
// This is a monomorphization of a generic function.
104+
if !(cx.tcx.sess.opts.share_generics()
105+
|| tcx.codegen_fn_attrs(instance_def_id).inline
106+
== rustc_attr_parsing::InlineAttr::Never)
152107
{
153-
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
108+
// When not sharing generics, all instances are in the same
109+
// crate and have hidden visibility.
110+
true
111+
} else {
112+
if let Some(instance_def_id) = instance_def_id.as_local() {
113+
// This is a monomorphization of a generic function
114+
// defined in the current crate. It is hidden if:
115+
// - the definition is unreachable for downstream
116+
// crates, or
117+
// - the current crate does not re-export generics
118+
// (because the crate is a C library or executable)
119+
cx.tcx.is_unreachable_local_definition(instance_def_id)
120+
|| !cx.tcx.local_crate_exports_generics()
121+
} else {
122+
// This is a monomorphization of a generic function
123+
// defined in an upstream crate. It is hidden if:
124+
// - it is instantiated in this crate, and
125+
// - the current crate does not re-export generics
126+
instance.upstream_monomorphization(tcx).is_none()
127+
&& !cx.tcx.local_crate_exports_generics()
128+
}
154129
}
130+
} else {
131+
// This is a non-generic function. It is hidden if:
132+
// - it is instantiated in the local crate, and
133+
// - it is defined an upstream crate (non-local), or
134+
// - it is not reachable
135+
cx.tcx.is_codegened_item(instance_def_id)
136+
&& (!instance_def_id.is_local()
137+
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
138+
};
139+
if is_hidden {
140+
llvm::set_visibility(llfn, llvm::Visibility::Hidden);
141+
}
155142

156-
if cx.should_assume_dso_local(llfn, true) {
157-
llvm::LLVMRustSetDSOLocal(llfn, true);
158-
}
143+
// MinGW: For backward compatibility we rely on the linker to decide whether it
144+
// should use dllimport for functions.
145+
if cx.use_dll_storage_attrs
146+
&& let Some(library) = tcx.native_library(instance_def_id)
147+
&& library.kind.is_dllimport()
148+
&& !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
149+
{
150+
llvm::set_dllimport_storage_class(llfn);
159151
}
160152

153+
cx.assume_dso_local(llfn, true);
154+
161155
llfn
162156
};
163157

Diff for: compiler/rustc_codegen_llvm/src/consts.rs

+4-15
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,7 @@ impl<'ll> CodegenCx<'ll, '_> {
336336
llvm::set_thread_local_mode(g, self.tls_model);
337337
}
338338

339-
let dso_local = self.should_assume_dso_local(g, true);
340-
if dso_local {
341-
unsafe {
342-
llvm::LLVMRustSetDSOLocal(g, true);
343-
}
344-
}
339+
let dso_local = self.assume_dso_local(g, true);
345340

346341
if !def_id.is_local() {
347342
let needs_dll_storage_attr = self.use_dll_storage_attrs
@@ -375,9 +370,7 @@ impl<'ll> CodegenCx<'ll, '_> {
375370
// is actually present in the current crate. We can find out via the
376371
// is_codegened_item query.
377372
if !self.tcx.is_codegened_item(def_id) {
378-
unsafe {
379-
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
380-
}
373+
llvm::set_dllimport_storage_class(g);
381374
}
382375
}
383376
}
@@ -387,9 +380,7 @@ impl<'ll> CodegenCx<'ll, '_> {
387380
&& library.kind.is_dllimport()
388381
{
389382
// For foreign (native) libs we know the exact storage type to use.
390-
unsafe {
391-
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
392-
}
383+
llvm::set_dllimport_storage_class(g);
393384
}
394385

395386
self.instances.borrow_mut().insert(instance, g);
@@ -460,9 +451,7 @@ impl<'ll> CodegenCx<'ll, '_> {
460451
set_global_alignment(self, g, alloc.align);
461452
llvm::set_initializer(g, v);
462453

463-
if self.should_assume_dso_local(g, true) {
464-
llvm::LLVMRustSetDSOLocal(g, true);
465-
}
454+
self.assume_dso_local(g, true);
466455

467456
// Forward the allocation's mutability (picked by the const interner) to LLVM.
468457
if alloc.mutability.is_not() {

Diff for: compiler/rustc_codegen_llvm/src/llvm/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,15 @@ pub(crate) fn add_module_flag_str(
403403
);
404404
}
405405
}
406+
407+
pub(crate) fn set_dllimport_storage_class<'ll>(v: &'ll Value) {
408+
unsafe {
409+
LLVMSetDLLStorageClass(v, DLLStorageClass::DllImport);
410+
}
411+
}
412+
413+
pub(crate) fn set_dso_local<'ll>(v: &'ll Value) {
414+
unsafe {
415+
LLVMRustSetDSOLocal(v, true);
416+
}
417+
}

Diff for: compiler/rustc_codegen_llvm/src/mono_item.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
3838

3939
llvm::set_linkage(g, base::linkage_to_llvm(linkage));
4040
llvm::set_visibility(g, base::visibility_to_llvm(visibility));
41-
unsafe {
42-
if self.should_assume_dso_local(g, false) {
43-
llvm::LLVMRustSetDSOLocal(g, true);
44-
}
45-
}
41+
self.assume_dso_local(g, false);
4642

4743
self.instances.borrow_mut().insert(instance, g);
4844
}
@@ -79,9 +75,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
7975

8076
debug!("predefine_fn: instance = {:?}", instance);
8177

82-
if self.should_assume_dso_local(lldecl, false) {
83-
unsafe { llvm::LLVMRustSetDSOLocal(lldecl, true) };
84-
}
78+
self.assume_dso_local(lldecl, false);
8579

8680
self.instances.borrow_mut().insert(instance, lldecl);
8781
}
@@ -90,11 +84,16 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
9084
impl CodegenCx<'_, '_> {
9185
/// Whether a definition or declaration can be assumed to be local to a group of
9286
/// libraries that form a single DSO or executable.
93-
pub(crate) fn should_assume_dso_local(
94-
&self,
95-
llval: &llvm::Value,
96-
is_declaration: bool,
97-
) -> bool {
87+
/// Marks the local as DSO if so.
88+
pub(crate) fn assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool {
89+
let assume = self.should_assume_dso_local(llval, is_declaration);
90+
if assume {
91+
llvm::set_dso_local(llval);
92+
}
93+
assume
94+
}
95+
96+
fn should_assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool {
9897
let linkage = llvm::get_linkage(llval);
9998
let visibility = llvm::get_visibility(llval);
10099

0 commit comments

Comments
 (0)