Skip to content

coverage: Consolidate creation of covmap/covfun records #132124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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.
  • Loading branch information
Zalathar committed Oct 25, 2024
commit 0356908cf5e5ead075608709663a38b51c584872
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ffi::{CStr, CString};
use std::ffi::CString;

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

let mut unused_function_names = Vec::new();
let covfun_section_name = coverageinfo::covfun_section_name(cx);

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

generate_covfun_record(
cx,
&covfun_section_name,
mangled_function_name,
source_hash,
filenames_ref,
Expand Down Expand Up @@ -360,7 +358,6 @@ fn generate_covmap_record<'ll>(
/// as a global variable in the `__llvm_covfun` section.
fn generate_covfun_record(
cx: &CodegenCx<'_, '_>,
covfun_section_name: &CStr,
mangled_function_name: &str,
source_hash: u64,
filenames_ref: u64,
Expand Down Expand Up @@ -401,7 +398,7 @@ fn generate_covfun_record(
llvm::set_global_constant(llglobal, true);
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
llvm::set_section(llglobal, covfun_section_name);
llvm::set_section(llglobal, cx.covfun_section_name());
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
llvm::set_alignment(llglobal, Align::EIGHT);
if cx.target_spec().supports_comdat() {
Expand Down
44 changes: 22 additions & 22 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::cell::RefCell;
use std::ffi::CString;
use std::cell::{OnceCell, RefCell};
use std::ffi::{CStr, CString};

use libc::c_uint;
use rustc_codegen_ssa::traits::{
Expand Down Expand Up @@ -29,6 +29,8 @@ pub(crate) struct CrateCoverageContext<'ll, 'tcx> {
RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
pub(crate) pgo_func_name_var_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>,
pub(crate) mcdc_condition_bitmap_map: RefCell<FxHashMap<Instance<'tcx>, Vec<&'ll llvm::Value>>>,

covfun_section_name: OnceCell<CString>,
}

impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
Expand All @@ -37,6 +39,7 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
function_coverage_map: Default::default(),
pgo_func_name_var_map: Default::default(),
mcdc_condition_bitmap_map: Default::default(),
covfun_section_name: Default::default(),
}
}

Expand All @@ -63,13 +66,28 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
}
}

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

/// Returns the section name to use when embedding per-function coverage information
/// in the object file, according to the target's object file format. LLVM's coverage
/// tools use information from this section when producing coverage reports.
///
/// Typical values are:
/// - `__llvm_covfun` on Linux
/// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
/// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
fn covfun_section_name(&self) -> &CStr {
self.coverage_cx().covfun_section_name.get_or_init(|| {
CString::new(llvm::build_byte_buffer(|s| unsafe {
llvm::LLVMRustCoverageWriteFuncSectionNameToString(self.llmod, s);
}))
.expect("covfun section name should not contain NUL")
})
}

/// For LLVM codegen, returns a function-specific `Value` for a global
/// string, to hold the function name passed to LLVM intrinsic
/// `instrprof.increment()`. The `Value` is only created once per instance.
Expand Down Expand Up @@ -278,21 +296,3 @@ pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
pub(crate) fn mapping_version() -> u32 {
unsafe { llvm::LLVMRustCoverageMappingVersion() }
}

/// Returns the section name string to pass through to the linker when embedding
/// per-function coverage information in the object file, according to the target
/// platform's object file format.
///
/// LLVM's coverage tools read coverage mapping details from this section when
/// producing coverage reports.
///
/// Typical values are:
/// - `__llvm_covfun` on Linux
/// - `__LLVM_COV,__llvm_covfun` on macOS (includes `__LLVM_COV,` segment prefix)
/// - `.lcovfun$M` on Windows (includes `$M` sorting suffix)
pub(crate) fn covfun_section_name(cx: &CodegenCx<'_, '_>) -> CString {
CString::new(llvm::build_byte_buffer(|s| unsafe {
llvm::LLVMRustCoverageWriteFuncSectionNameToString(cx.llmod, s);
}))
.expect("covfun section name should not contain NUL")
}
Loading