1
Fork 0

Declare main as visibility hidden on targets that default to hidden.

On targets with `default_hidden_visibility` set, which is currrently
just WebAssembly, declare the generated `main` function with visibility
hidden. This makes it consistent with clang's WebAssembly target, where
`main` is just a user function that gets the same visibility as any
other user function, which is hidden on WebAssembly unless explicitly
overridden.

This will help simplify use cases which in the future may want to
automatically wasm-export all visibility-"default" symbols. `main` isn't
intended to be wasm-exported, and marking it hidden prevents it from
being wasm-exported in that scenario.
This commit is contained in:
Dan Gohman 2022-09-28 10:42:30 -07:00
parent 09ae7846a2
commit 3c3bf76ce0
5 changed files with 46 additions and 9 deletions

View file

@ -1458,7 +1458,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
} else { } else {
format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width) format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
}; };
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty)); let f = self.declare_cfn(
&name,
llvm::UnnamedAddr::No,
llvm::Visibility::Default,
self.type_func(&[src_ty], dest_ty),
);
self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None) self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None)
} }

View file

@ -528,7 +528,12 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
llfn llfn
} else { } else {
let fty = self.type_variadic_func(&[], self.type_i32()); let fty = self.type_variadic_func(&[], self.type_i32());
let llfn = self.declare_cfn(name, llvm::UnnamedAddr::Global, fty); let llfn = self.declare_cfn(
name,
llvm::UnnamedAddr::Global,
llvm::Visibility::Default,
fty,
);
let target_cpu = attributes::target_cpu_attr(self); let target_cpu = attributes::target_cpu_attr(self);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]);
llfn llfn
@ -585,7 +590,13 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
if self.get_declared_value("main").is_none() { if self.get_declared_value("main").is_none() {
Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type)) let visibility = if self.sess().target.default_hidden_visibility {
llvm::Visibility::Hidden
} else {
llvm::Visibility::Default
};
Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, visibility, fn_type))
} else { } else {
// If the symbol already exists, it is an error: for example, the user wrote // If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..} // #[no_mangle] extern "C" fn main(..) {..}
@ -615,7 +626,7 @@ impl<'ll> CodegenCx<'ll, '_> {
} else { } else {
self.type_variadic_func(&[], ret) self.type_variadic_func(&[], ret)
}; };
let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty); let f = self.declare_cfn(name, llvm::UnnamedAddr::No, llvm::Visibility::Default, fn_ty);
self.intrinsics.borrow_mut().insert(name, (fn_ty, f)); self.intrinsics.borrow_mut().insert(name, (fn_ty, f));
(fn_ty, f) (fn_ty, f)
} }

View file

@ -32,6 +32,7 @@ fn declare_raw_fn<'ll>(
name: &str, name: &str,
callconv: llvm::CallConv, callconv: llvm::CallConv,
unnamed: llvm::UnnamedAddr, unnamed: llvm::UnnamedAddr,
visibility: llvm::Visibility,
ty: &'ll Type, ty: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
@ -41,6 +42,7 @@ fn declare_raw_fn<'ll>(
llvm::SetFunctionCallConv(llfn, callconv); llvm::SetFunctionCallConv(llfn, callconv);
llvm::SetUnnamedAddress(llfn, unnamed); llvm::SetUnnamedAddress(llfn, unnamed);
llvm::SetVisibility(llfn, visibility);
let mut attrs = SmallVec::<[_; 4]>::new(); let mut attrs = SmallVec::<[_; 4]>::new();
@ -76,9 +78,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
&self, &self,
name: &str, name: &str,
unnamed: llvm::UnnamedAddr, unnamed: llvm::UnnamedAddr,
visibility: llvm::Visibility,
fn_type: &'ll Type, fn_type: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
declare_raw_fn(self, name, llvm::CCallConv, unnamed, fn_type) declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
} }
/// Declare a Rust function. /// Declare a Rust function.
@ -95,6 +98,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
name, name,
fn_abi.llvm_cconv(), fn_abi.llvm_cconv(),
llvm::UnnamedAddr::Global, llvm::UnnamedAddr::Global,
llvm::Visibility::Default,
fn_abi.llvm_type(self), fn_abi.llvm_type(self),
); );
fn_abi.apply_attrs_llfn(self, llfn); fn_abi.apply_attrs_llfn(self, llfn);

View file

@ -1216,7 +1216,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
_ => return_error!("unrecognized intrinsic `{}`", name), _ => return_error!("unrecognized intrinsic `{}`", name),
}; };
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, llvm::Visibility::Default, fn_ty);
let c = let c =
bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
Ok(c) Ok(c)
@ -1416,7 +1416,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
&[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty], &[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty],
llvm_elem_vec_ty, llvm_elem_vec_ty,
); );
let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let f = bx.declare_cfn(
&llvm_intrinsic,
llvm::UnnamedAddr::No,
llvm::Visibility::Default,
fn_ty,
);
let v = let v =
bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None);
return Ok(v); return Ok(v);
@ -1542,7 +1547,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str); format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
let fn_ty = let fn_ty =
bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t); bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t);
let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let f = bx.declare_cfn(
&llvm_intrinsic,
llvm::UnnamedAddr::No,
llvm::Visibility::Default,
fn_ty,
);
let v = let v =
bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None);
return Ok(v); return Ok(v);
@ -1991,7 +2001,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64); let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty); let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty);
let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let f =
bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, llvm::Visibility::Default, fn_ty);
let v = bx.call(fn_ty, f, &[lhs, rhs], None); let v = bx.call(fn_ty, f, &[lhs, rhs], None);
return Ok(v); return Ok(v);
} }

View file

@ -172,6 +172,12 @@ pub fn SetUnnamedAddress(global: &Value, unnamed: UnnamedAddr) {
} }
} }
pub fn SetVisibility(global: &Value, visibility: Visibility) {
unsafe {
LLVMRustSetVisibility(global, visibility);
}
}
pub fn set_thread_local_mode(global: &Value, mode: ThreadLocalMode) { pub fn set_thread_local_mode(global: &Value, mode: ThreadLocalMode) {
unsafe { unsafe {
LLVMSetThreadLocalMode(global, mode); LLVMSetThreadLocalMode(global, mode);