Skip to content

Commit 20fcc4f

Browse files
cg_llvm: Reuse LLVM-C Comdat support
Migrate `llvm::set_comdat` and `llvm::SetUniqueComdat` to LLVM-C FFI. Note, now we can call `llvm::set_comdat` only when the target actually supports adding comdat. As this has no convenient LLVM-C API, we implement this as `TargetOptions::supports_comdat`. Co-authored-by: Stuart Cook <[email protected]>
1 parent 888efe7 commit 20fcc4f

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::mir::coverage::CoverageKind;
1313
use rustc_middle::ty::Instance;
1414
use rustc_middle::ty::layout::HasTyCtxt;
1515
use rustc_target::abi::{Align, Size};
16+
use rustc_target::spec::HasTargetSpec;
1617
use tracing::{debug, instrument};
1718

1819
use crate::builder::Builder;
@@ -336,7 +337,9 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
336337
llvm::set_section(llglobal, covfun_section_name);
337338
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
338339
llvm::set_alignment(llglobal, Align::EIGHT);
339-
llvm::set_comdat(cx.llmod, llglobal, func_record_var_name.to_str().unwrap());
340+
if cx.target_spec().supports_comdat() {
341+
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
342+
}
340343
cx.add_used_global(llglobal);
341344
}
342345

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ unsafe extern "C" {
646646
pub type Attribute;
647647
pub type Metadata;
648648
pub type BasicBlock;
649+
pub type Comdat;
649650
}
650651
#[repr(C)]
651652
pub struct Builder<'a>(InvariantOpaque<'a>);
@@ -1490,6 +1491,9 @@ unsafe extern "C" {
14901491
pub fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr);
14911492

14921493
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
1494+
1495+
pub fn LLVMGetOrInsertComdat(M: &Module, Name: *const c_char) -> &Comdat;
1496+
pub fn LLVMSetComdat(V: &Value, C: &Comdat);
14931497
}
14941498

14951499
#[link(name = "llvm-wrapper", kind = "static")]
@@ -2320,7 +2324,6 @@ unsafe extern "C" {
23202324

23212325
pub fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
23222326

2323-
pub fn LLVMRustSetComdat<'a>(M: &'a Module, V: &'a Value, Name: *const c_char, NameLen: size_t);
23242327
pub fn LLVMRustSetModulePICLevel(M: &Module);
23252328
pub fn LLVMRustSetModulePIELevel(M: &Module);
23262329
pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel);

compiler/rustc_codegen_llvm/src/llvm/mod.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ pub fn SetFunctionCallConv(fn_: &Value, cc: CallConv) {
178178
// function.
179179
// For more details on COMDAT sections see e.g., https://www.airs.com/blog/archives/52
180180
pub fn SetUniqueComdat(llmod: &Module, val: &Value) {
181-
unsafe {
182-
let name = get_value_name(val);
183-
LLVMRustSetComdat(llmod, val, name.as_ptr().cast(), name.len());
184-
}
181+
let name_buf = get_value_name(val).to_vec();
182+
let name =
183+
CString::from_vec_with_nul(name_buf).or_else(|buf| CString::new(buf.into_bytes())).unwrap();
184+
set_comdat(llmod, val, &name);
185185
}
186186

187187
pub fn SetUnnamedAddress(global: &Value, unnamed: UnnamedAddr) {
@@ -251,9 +251,14 @@ pub fn set_alignment(llglobal: &Value, align: Align) {
251251
}
252252
}
253253

254-
pub fn set_comdat(llmod: &Module, llglobal: &Value, name: &str) {
254+
/// Get the `name`d comdat from `llmod` and set it in llglobal.
255+
///
256+
/// Inserts the comdat into `llmod` if it does not exist.
257+
/// It is an error to call this if the target does not support comdat.
258+
pub fn set_comdat(llmod: &Module, llglobal: &Value, name: &CStr) {
255259
unsafe {
256-
LLVMRustSetComdat(llmod, llglobal, name.as_ptr().cast(), name.len());
260+
let comdat = LLVMGetOrInsertComdat(llmod, name.as_ptr());
261+
LLVMSetComdat(llglobal, comdat);
257262
}
258263
}
259264

compiler/rustc_target/src/spec/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2514,6 +2514,13 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
25142514
add_link_args_iter(link_args, flavor, args.iter().copied().map(Cow::Borrowed))
25152515
}
25162516

2517+
impl TargetOptions {
2518+
pub fn supports_comdat(&self) -> bool {
2519+
// XCOFF and MachO don't support COMDAT.
2520+
!self.is_like_aix && !self.is_like_osx
2521+
}
2522+
}
2523+
25172524
impl TargetOptions {
25182525
fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
25192526
let mut link_args = LinkArgs::new();

0 commit comments

Comments
 (0)