Streamline hidden visibility setting.

In `get_fn` there is a complicated set of if/elses to determine if
`hidden` visibility should be applied. There are five calls to
`LLVMRustSetVisibility` and some repetition in the comments.

This commit streamlines it a bit:
- Computes `hidden` and then uses it to determine if a single call to
  `LLVMRustSetVisibility` occurs.
- Converts some of the if/elses into boolean expressions.
- Removes the repetitive comments.

Overall this makes it quite a bit shorter, and I find it easier to read.
This commit is contained in:
Nicholas Nethercote 2024-09-18 07:05:03 +10:00
parent eb575506f2
commit fda530d729

View File

@ -101,63 +101,43 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
let is_generic = let is_generic =
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some(); instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
if is_generic { let is_hidden = if is_generic {
// This is a monomorphization. Its expected visibility depends // This is a monomorphization of a generic function.
// on whether we are in share-generics mode. if !cx.tcx.sess.opts.share_generics() {
// When not sharing generics, all instances are in the same
if cx.tcx.sess.opts.share_generics() { // crate and have hidden visibility.
// We are in share_generics mode. true
} else {
if let Some(instance_def_id) = instance_def_id.as_local() { if let Some(instance_def_id) = instance_def_id.as_local() {
// This is a definition from the current crate. If the // This is a monomorphization of a generic function
// definition is unreachable for downstream crates or // defined in the current crate. It is hidden if:
// the current crate does not re-export generics, the // - the definition is unreachable for downstream
// definition of the instance will have been declared // crates, or
// as `hidden`. // - the current crate does not re-export generics
if cx.tcx.is_unreachable_local_definition(instance_def_id) // (because the crate is a C library or executable)
cx.tcx.is_unreachable_local_definition(instance_def_id)
|| !cx.tcx.local_crate_exports_generics() || !cx.tcx.local_crate_exports_generics()
{
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} else { } else {
// This is a monomorphization of a generic function // This is a monomorphization of a generic function
// defined in an upstream crate. // defined in an upstream crate. It is hidden if:
if instance.upstream_monomorphization(tcx).is_some() { // - it is instantiated in this crate, and
// This is instantiated in another crate. It cannot // - the current crate does not re-export generics
// be `hidden`. instance.upstream_monomorphization(tcx).is_none()
} else { && !cx.tcx.local_crate_exports_generics()
// This is a local instantiation of an upstream definition.
// If the current crate does not re-export it
// (because it is a C library or an executable), it
// will have been declared `hidden`.
if !cx.tcx.local_crate_exports_generics() {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} }
} }
} else { } else {
// When not sharing generics, all instances are in the same // This is a non-generic function. It is hidden if:
// crate and have hidden visibility // - it is instantiated in the local crate, and
// - it is defined an upstream crate (non-local), or
// - it is not reachable
cx.tcx.is_codegened_item(instance_def_id)
&& (!instance_def_id.is_local()
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
};
if is_hidden {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
} }
} else {
// This is a non-generic function
if cx.tcx.is_codegened_item(instance_def_id) {
// This is a function that is instantiated in the local crate
if instance_def_id.is_local() {
// This is function that is defined in the local crate.
// If it is not reachable, it is hidden.
if !cx.tcx.is_reachable_non_generic(instance_def_id) {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} else {
// This is a function from an upstream crate that has
// been instantiated here. These are always hidden.
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
}
}
// MinGW: For backward compatibility we rely on the linker to decide whether it // MinGW: For backward compatibility we rely on the linker to decide whether it
// should use dllimport for functions. // should use dllimport for functions.