From 3c3bf76ce0cc9e569e04a242dfdc447131e21db9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Sep 2022 10:42:30 -0700 Subject: [PATCH 1/4] 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. --- compiler/rustc_codegen_llvm/src/builder.rs | 7 ++++++- compiler/rustc_codegen_llvm/src/context.rs | 17 ++++++++++++++--- compiler/rustc_codegen_llvm/src/declare.rs | 6 +++++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 19 +++++++++++++++---- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 6 ++++++ 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 59b1c7fb5dbd0..a6cd1059dc723 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1458,7 +1458,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } else { 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) } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 67ffc7cb9511f..6aeb56eb5ade0 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -528,7 +528,12 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { llfn } else { 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); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]); llfn @@ -585,7 +590,13 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn declare_c_main(&self, fn_type: Self::Type) -> Option { 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 { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} @@ -615,7 +626,7 @@ impl<'ll> CodegenCx<'ll, '_> { } else { 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)); (fn_ty, f) } diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 0f663a26732bb..21c466ddc244f 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -32,6 +32,7 @@ fn declare_raw_fn<'ll>( name: &str, callconv: llvm::CallConv, unnamed: llvm::UnnamedAddr, + visibility: llvm::Visibility, ty: &'ll Type, ) -> &'ll Value { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); @@ -41,6 +42,7 @@ fn declare_raw_fn<'ll>( llvm::SetFunctionCallConv(llfn, callconv); llvm::SetUnnamedAddress(llfn, unnamed); + llvm::SetVisibility(llfn, visibility); let mut attrs = SmallVec::<[_; 4]>::new(); @@ -76,9 +78,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { &self, name: &str, unnamed: llvm::UnnamedAddr, + visibility: llvm::Visibility, fn_type: &'ll Type, ) -> &'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. @@ -95,6 +98,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { name, fn_abi.llvm_cconv(), llvm::UnnamedAddr::Global, + llvm::Visibility::Default, fn_abi.llvm_type(self), ); fn_abi.apply_attrs_llfn(self, llfn); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index a640de42a6a86..4e1e6371ad481 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1216,7 +1216,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => return_error!("unrecognized intrinsic `{}`", name), }; 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 = bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::>(), None); 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_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 = bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); 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); let fn_ty = 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 = bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); 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 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); return Ok(v); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 6602a4ab8636c..942e7e0427c11 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -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) { unsafe { LLVMSetThreadLocalMode(global, mode); From bc5443a603efd83c0eacaac0bf5383280c81a6eb Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Sep 2022 14:43:58 -0700 Subject: [PATCH 2/4] Use the existing `set_visibility` function. --- compiler/rustc_codegen_llvm/src/declare.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 21c466ddc244f..3fbc803d5c32f 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -42,7 +42,7 @@ fn declare_raw_fn<'ll>( llvm::SetFunctionCallConv(llfn, callconv); llvm::SetUnnamedAddress(llfn, unnamed); - llvm::SetVisibility(llfn, visibility); + llvm::set_visibility(llfn, visibility); let mut attrs = SmallVec::<[_; 4]>::new(); diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 942e7e0427c11..6602a4ab8636c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -172,12 +172,6 @@ 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) { unsafe { LLVMSetThreadLocalMode(global, mode); From 297c908fee73206bc00276df80326582dad0168f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Sep 2022 14:50:58 -0700 Subject: [PATCH 3/4] Change `declare_cfn` to use the C visibility for all C ABI functions. --- compiler/rustc_codegen_llvm/src/builder.rs | 7 +------ compiler/rustc_codegen_llvm/src/context.rs | 17 +++-------------- compiler/rustc_codegen_llvm/src/declare.rs | 8 +++++++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 19 ++++--------------- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index a6cd1059dc723..59b1c7fb5dbd0 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1458,12 +1458,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } else { format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width) }; - let f = self.declare_cfn( - &name, - llvm::UnnamedAddr::No, - llvm::Visibility::Default, - self.type_func(&[src_ty], dest_ty), - ); + let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty)); self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None) } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6aeb56eb5ade0..67ffc7cb9511f 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -528,12 +528,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { llfn } else { let fty = self.type_variadic_func(&[], self.type_i32()); - let llfn = self.declare_cfn( - name, - llvm::UnnamedAddr::Global, - llvm::Visibility::Default, - fty, - ); + let llfn = self.declare_cfn(name, llvm::UnnamedAddr::Global, fty); let target_cpu = attributes::target_cpu_attr(self); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]); llfn @@ -590,13 +585,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn declare_c_main(&self, fn_type: Self::Type) -> Option { if self.get_declared_value("main").is_none() { - 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)) + Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type)) } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} @@ -626,7 +615,7 @@ impl<'ll> CodegenCx<'ll, '_> { } else { self.type_variadic_func(&[], ret) }; - let f = self.declare_cfn(name, llvm::UnnamedAddr::No, llvm::Visibility::Default, fn_ty); + let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty); self.intrinsics.borrow_mut().insert(name, (fn_ty, f)); (fn_ty, f) } diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 3fbc803d5c32f..f79ef11720df9 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -78,9 +78,15 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { &self, name: &str, unnamed: llvm::UnnamedAddr, - visibility: llvm::Visibility, fn_type: &'ll Type, ) -> &'ll Value { + // Declare C ABI functions with the visibility used by C by default. + let visibility = if self.tcx.sess.target.default_hidden_visibility { + llvm::Visibility::Hidden + } else { + llvm::Visibility::Default + }; + declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 4e1e6371ad481..a640de42a6a86 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1216,7 +1216,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => return_error!("unrecognized intrinsic `{}`", name), }; 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, llvm::Visibility::Default, fn_ty); + let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); let c = bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::>(), None); Ok(c) @@ -1416,12 +1416,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( &[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty], llvm_elem_vec_ty, ); - let f = bx.declare_cfn( - &llvm_intrinsic, - llvm::UnnamedAddr::No, - llvm::Visibility::Default, - fn_ty, - ); + let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let v = bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); return Ok(v); @@ -1547,12 +1542,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str); let fn_ty = 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, - llvm::Visibility::Default, - fn_ty, - ); + let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let v = bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); return Ok(v); @@ -2001,8 +1991,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, 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 f = - bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, llvm::Visibility::Default, fn_ty); + let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); let v = bx.call(fn_ty, f, &[lhs, rhs], None); return Ok(v); } From 72f15572ee5592c93bf307bfe94240d0e1f03601 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 30 Sep 2022 14:55:26 -0700 Subject: [PATCH 4/4] Allow `hidden` in src/test/codegen/abi-main-signature-32bit-c-int.rs --- src/test/codegen/abi-main-signature-32bit-c-int.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/codegen/abi-main-signature-32bit-c-int.rs b/src/test/codegen/abi-main-signature-32bit-c-int.rs index 31b19a54276e7..7f22ddcfc12ff 100644 --- a/src/test/codegen/abi-main-signature-32bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-32bit-c-int.rs @@ -7,4 +7,4 @@ fn main() { } -// CHECK: define i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) +// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}})