Skip to content

Commit 0356908

Browse files
committed
coverage: Store covfun_section_name in the codegen context
Adding an extra `OnceCell` to `CrateCoverageContext` is much nicer than trying to thread this string through multiple layers of function calls that already have access to the context.
1 parent 0a96176 commit 0356908

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::ffi::{CStr, CString};
1+
use std::ffi::CString;
22

33
use itertools::Itertools as _;
44
use rustc_abi::Align;
@@ -81,7 +81,6 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
8181
generate_covmap_record(cx, covmap_version, filenames_size, filenames_val);
8282

8383
let mut unused_function_names = Vec::new();
84-
let covfun_section_name = coverageinfo::covfun_section_name(cx);
8584

8685
// Encode coverage mappings and generate function records
8786
for (instance, function_coverage) in function_coverage_entries {
@@ -112,7 +111,6 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
112111

113112
generate_covfun_record(
114113
cx,
115-
&covfun_section_name,
116114
mangled_function_name,
117115
source_hash,
118116
filenames_ref,
@@ -360,7 +358,6 @@ fn generate_covmap_record<'ll>(
360358
/// as a global variable in the `__llvm_covfun` section.
361359
fn generate_covfun_record(
362360
cx: &CodegenCx<'_, '_>,
363-
covfun_section_name: &CStr,
364361
mangled_function_name: &str,
365362
source_hash: u64,
366363
filenames_ref: u64,
@@ -401,7 +398,7 @@ fn generate_covfun_record(
401398
llvm::set_global_constant(llglobal, true);
402399
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
403400
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
404-
llvm::set_section(llglobal, covfun_section_name);
401+
llvm::set_section(llglobal, cx.covfun_section_name());
405402
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
406403
llvm::set_alignment(llglobal, Align::EIGHT);
407404
if cx.target_spec().supports_comdat() {

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::cell::RefCell;
2-
use std::ffi::CString;
1+
use std::cell::{OnceCell, RefCell};
2+
use std::ffi::{CStr, CString};
33

44
use libc::c_uint;
55
use rustc_codegen_ssa::traits::{
@@ -29,6 +29,8 @@ pub(crate) struct CrateCoverageContext<'ll, 'tcx> {
2929
RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
3030
pub(crate) pgo_func_name_var_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>,
3131
pub(crate) mcdc_condition_bitmap_map: RefCell<FxHashMap<Instance<'tcx>, Vec<&'ll llvm::Value>>>,
32+
33+
covfun_section_name: OnceCell<CString>,
3234
}
3335

3436
impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
@@ -37,6 +39,7 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
3739
function_coverage_map: Default::default(),
3840
pgo_func_name_var_map: Default::default(),
3941
mcdc_condition_bitmap_map: Default::default(),
42+
covfun_section_name: Default::default(),
4043
}
4144
}
4245

@@ -63,13 +66,28 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
6366
}
6467
}
6568

66-
// These methods used to be part of trait `CoverageInfoMethods`, which no longer
67-
// exists after most coverage code was moved out of SSA.
6869
impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
6970
pub(crate) fn coverageinfo_finalize(&self) {
7071
mapgen::finalize(self)
7172
}
7273

74+
/// Returns the section name to use when embedding per-function coverage information
75+
/// in the object file, according to the target's object file format. LLVM's coverage
76+
/// tools use information from this section when producing coverage reports.
77+
///
78+
/// Typical values are:
79+
/// - `__llvm_covfun` on Linux
80+
/// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
81+
/// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
82+
fn covfun_section_name(&self) -> &CStr {
83+
self.coverage_cx().covfun_section_name.get_or_init(|| {
84+
CString::new(llvm::build_byte_buffer(|s| unsafe {
85+
llvm::LLVMRustCoverageWriteFuncSectionNameToString(self.llmod, s);
86+
}))
87+
.expect("covfun section name should not contain NUL")
88+
})
89+
}
90+
7391
/// For LLVM codegen, returns a function-specific `Value` for a global
7492
/// string, to hold the function name passed to LLVM intrinsic
7593
/// `instrprof.increment()`. The `Value` is only created once per instance.
@@ -278,21 +296,3 @@ pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
278296
pub(crate) fn mapping_version() -> u32 {
279297
unsafe { llvm::LLVMRustCoverageMappingVersion() }
280298
}
281-
282-
/// Returns the section name string to pass through to the linker when embedding
283-
/// per-function coverage information in the object file, according to the target
284-
/// platform's object file format.
285-
///
286-
/// LLVM's coverage tools read coverage mapping details from this section when
287-
/// producing coverage reports.
288-
///
289-
/// Typical values are:
290-
/// - `__llvm_covfun` on Linux
291-
/// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
292-
/// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
293-
pub(crate) fn covfun_section_name(cx: &CodegenCx<'_, '_>) -> CString {
294-
CString::new(llvm::build_byte_buffer(|s| unsafe {
295-
llvm::LLVMRustCoverageWriteFuncSectionNameToString(cx.llmod, s);
296-
}))
297-
.expect("covfun section name should not contain NUL")
298-
}

0 commit comments

Comments
 (0)