Skip to content

Commit 6a8c016

Browse files
committed
coverage: Reify CovfunRecord as an intermediate step
1 parent 7c4ac71 commit 6a8c016

File tree

2 files changed

+45
-36
lines changed

2 files changed

+45
-36
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use tracing::debug;
1919
use crate::common::CodegenCx;
2020
use crate::coverageinfo::llvm_cov;
2121
use crate::coverageinfo::map_data::FunctionCoverage;
22+
use crate::coverageinfo::mapgen::covfun::prepare_covfun_record;
2223
use crate::llvm;
2324

2425
mod covfun;
@@ -85,16 +86,17 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
8586

8687
let mut unused_function_names = Vec::new();
8788

88-
// Encode coverage mappings and generate function records
89-
for (instance, function_coverage) in function_coverage_map {
90-
covfun::prepare_and_generate_covfun_record(
91-
cx,
92-
&global_file_table,
93-
filenames_ref,
94-
&mut unused_function_names,
95-
instance,
96-
&function_coverage,
97-
);
89+
let covfun_records = function_coverage_map
90+
.into_iter()
91+
.filter_map(|(instance, function_coverage)| {
92+
prepare_covfun_record(tcx, &global_file_table, instance, &function_coverage)
93+
})
94+
.collect::<Vec<_>>();
95+
96+
for covfun in &covfun_records {
97+
unused_function_names.extend(covfun.mangled_function_name_if_unused());
98+
99+
covfun::generate_covfun_record(cx, filenames_ref, covfun)
98100
}
99101

100102
// For unused functions, we need to take their mangled names and store them

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs

+33-26
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,30 @@ use crate::coverageinfo::mapgen::{GlobalFileTable, VirtualFileMapping, span_file
2222
use crate::coverageinfo::{ffi, llvm_cov};
2323
use crate::llvm;
2424

25-
pub(crate) fn prepare_and_generate_covfun_record<'ll, 'tcx>(
26-
cx: &CodegenCx<'ll, 'tcx>,
25+
/// Intermediate coverage metadata for a single function, used to help build
26+
/// the final record that will be embedded in the `__llvm_covfun` section.
27+
#[derive(Debug)]
28+
pub(crate) struct CovfunRecord<'tcx> {
29+
mangled_function_name: &'tcx str,
30+
source_hash: u64,
31+
is_used: bool,
32+
coverage_mapping_buffer: Vec<u8>,
33+
}
34+
35+
impl<'tcx> CovfunRecord<'tcx> {
36+
/// FIXME(Zalathar): Make this the responsibility of the code that determines
37+
/// which functions are unused.
38+
pub(crate) fn mangled_function_name_if_unused(&self) -> Option<&'tcx str> {
39+
(!self.is_used).then_some(self.mangled_function_name)
40+
}
41+
}
42+
43+
pub(crate) fn prepare_covfun_record<'tcx>(
44+
tcx: TyCtxt<'tcx>,
2745
global_file_table: &GlobalFileTable,
28-
filenames_ref: u64,
29-
unused_function_names: &mut Vec<&'tcx str>,
3046
instance: Instance<'tcx>,
3147
function_coverage: &FunctionCoverage<'tcx>,
32-
) {
33-
let tcx = cx.tcx;
34-
48+
) -> Option<CovfunRecord<'tcx>> {
3549
let mangled_function_name = tcx.symbol_name(instance).name;
3650
let source_hash = function_coverage.source_hash();
3751
let is_used = function_coverage.is_used();
@@ -47,22 +61,11 @@ pub(crate) fn prepare_and_generate_covfun_record<'ll, 'tcx>(
4761
);
4862
} else {
4963
debug!("unused function had no coverage mapping data: {}", mangled_function_name);
50-
return;
64+
return None;
5165
}
5266
}
5367

54-
if !is_used {
55-
unused_function_names.push(mangled_function_name);
56-
}
57-
58-
generate_covfun_record(
59-
cx,
60-
mangled_function_name,
61-
source_hash,
62-
filenames_ref,
63-
coverage_mapping_buffer,
64-
is_used,
65-
);
68+
Some(CovfunRecord { mangled_function_name, source_hash, is_used, coverage_mapping_buffer })
6669
}
6770

6871
/// Using the expressions and counter regions collected for a single function,
@@ -145,14 +148,18 @@ fn encode_mappings_for_function(
145148
/// Generates the contents of the covfun record for this function, which
146149
/// contains the function's coverage mapping data. The record is then stored
147150
/// as a global variable in the `__llvm_covfun` section.
148-
fn generate_covfun_record(
149-
cx: &CodegenCx<'_, '_>,
150-
mangled_function_name: &str,
151-
source_hash: u64,
151+
pub(crate) fn generate_covfun_record<'tcx>(
152+
cx: &CodegenCx<'_, 'tcx>,
152153
filenames_ref: u64,
153-
coverage_mapping_buffer: Vec<u8>,
154-
is_used: bool,
154+
covfun: &CovfunRecord<'tcx>,
155155
) {
156+
let &CovfunRecord {
157+
mangled_function_name,
158+
source_hash,
159+
is_used,
160+
ref coverage_mapping_buffer, // Previously-encoded coverage mappings
161+
} = covfun;
162+
156163
// Concatenate the encoded coverage mappings
157164
let coverage_mapping_size = coverage_mapping_buffer.len();
158165
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);

0 commit comments

Comments
 (0)