coverage: Reify CovfunRecord
as an intermediate step
This commit is contained in:
parent
7c4ac71ad1
commit
6a8c016266
2 changed files with 45 additions and 36 deletions
|
@ -19,6 +19,7 @@ use tracing::debug;
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::coverageinfo::llvm_cov;
|
use crate::coverageinfo::llvm_cov;
|
||||||
use crate::coverageinfo::map_data::FunctionCoverage;
|
use crate::coverageinfo::map_data::FunctionCoverage;
|
||||||
|
use crate::coverageinfo::mapgen::covfun::prepare_covfun_record;
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
|
|
||||||
mod covfun;
|
mod covfun;
|
||||||
|
@ -85,16 +86,17 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
|
||||||
|
|
||||||
let mut unused_function_names = Vec::new();
|
let mut unused_function_names = Vec::new();
|
||||||
|
|
||||||
// Encode coverage mappings and generate function records
|
let covfun_records = function_coverage_map
|
||||||
for (instance, function_coverage) in function_coverage_map {
|
.into_iter()
|
||||||
covfun::prepare_and_generate_covfun_record(
|
.filter_map(|(instance, function_coverage)| {
|
||||||
cx,
|
prepare_covfun_record(tcx, &global_file_table, instance, &function_coverage)
|
||||||
&global_file_table,
|
})
|
||||||
filenames_ref,
|
.collect::<Vec<_>>();
|
||||||
&mut unused_function_names,
|
|
||||||
instance,
|
for covfun in &covfun_records {
|
||||||
&function_coverage,
|
unused_function_names.extend(covfun.mangled_function_name_if_unused());
|
||||||
);
|
|
||||||
|
covfun::generate_covfun_record(cx, filenames_ref, covfun)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For unused functions, we need to take their mangled names and store them
|
// For unused functions, we need to take their mangled names and store them
|
||||||
|
|
|
@ -22,16 +22,30 @@ use crate::coverageinfo::mapgen::{GlobalFileTable, VirtualFileMapping, span_file
|
||||||
use crate::coverageinfo::{ffi, llvm_cov};
|
use crate::coverageinfo::{ffi, llvm_cov};
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
|
|
||||||
pub(crate) fn prepare_and_generate_covfun_record<'ll, 'tcx>(
|
/// Intermediate coverage metadata for a single function, used to help build
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
/// the final record that will be embedded in the `__llvm_covfun` section.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct CovfunRecord<'tcx> {
|
||||||
|
mangled_function_name: &'tcx str,
|
||||||
|
source_hash: u64,
|
||||||
|
is_used: bool,
|
||||||
|
coverage_mapping_buffer: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> CovfunRecord<'tcx> {
|
||||||
|
/// FIXME(Zalathar): Make this the responsibility of the code that determines
|
||||||
|
/// which functions are unused.
|
||||||
|
pub(crate) fn mangled_function_name_if_unused(&self) -> Option<&'tcx str> {
|
||||||
|
(!self.is_used).then_some(self.mangled_function_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn prepare_covfun_record<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
global_file_table: &GlobalFileTable,
|
global_file_table: &GlobalFileTable,
|
||||||
filenames_ref: u64,
|
|
||||||
unused_function_names: &mut Vec<&'tcx str>,
|
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
function_coverage: &FunctionCoverage<'tcx>,
|
function_coverage: &FunctionCoverage<'tcx>,
|
||||||
) {
|
) -> Option<CovfunRecord<'tcx>> {
|
||||||
let tcx = cx.tcx;
|
|
||||||
|
|
||||||
let mangled_function_name = tcx.symbol_name(instance).name;
|
let mangled_function_name = tcx.symbol_name(instance).name;
|
||||||
let source_hash = function_coverage.source_hash();
|
let source_hash = function_coverage.source_hash();
|
||||||
let is_used = function_coverage.is_used();
|
let is_used = function_coverage.is_used();
|
||||||
|
@ -47,22 +61,11 @@ pub(crate) fn prepare_and_generate_covfun_record<'ll, 'tcx>(
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
debug!("unused function had no coverage mapping data: {}", mangled_function_name);
|
debug!("unused function had no coverage mapping data: {}", mangled_function_name);
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_used {
|
Some(CovfunRecord { mangled_function_name, source_hash, is_used, coverage_mapping_buffer })
|
||||||
unused_function_names.push(mangled_function_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_covfun_record(
|
|
||||||
cx,
|
|
||||||
mangled_function_name,
|
|
||||||
source_hash,
|
|
||||||
filenames_ref,
|
|
||||||
coverage_mapping_buffer,
|
|
||||||
is_used,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Using the expressions and counter regions collected for a single function,
|
/// Using the expressions and counter regions collected for a single function,
|
||||||
|
@ -145,14 +148,18 @@ fn encode_mappings_for_function(
|
||||||
/// Generates the contents of the covfun record for this function, which
|
/// Generates the contents of the covfun record for this function, which
|
||||||
/// contains the function's coverage mapping data. The record is then stored
|
/// contains the function's coverage mapping data. The record is then stored
|
||||||
/// as a global variable in the `__llvm_covfun` section.
|
/// as a global variable in the `__llvm_covfun` section.
|
||||||
fn generate_covfun_record(
|
pub(crate) fn generate_covfun_record<'tcx>(
|
||||||
cx: &CodegenCx<'_, '_>,
|
cx: &CodegenCx<'_, 'tcx>,
|
||||||
mangled_function_name: &str,
|
|
||||||
source_hash: u64,
|
|
||||||
filenames_ref: u64,
|
filenames_ref: u64,
|
||||||
coverage_mapping_buffer: Vec<u8>,
|
covfun: &CovfunRecord<'tcx>,
|
||||||
is_used: bool,
|
|
||||||
) {
|
) {
|
||||||
|
let &CovfunRecord {
|
||||||
|
mangled_function_name,
|
||||||
|
source_hash,
|
||||||
|
is_used,
|
||||||
|
ref coverage_mapping_buffer, // Previously-encoded coverage mappings
|
||||||
|
} = covfun;
|
||||||
|
|
||||||
// Concatenate the encoded coverage mappings
|
// Concatenate the encoded coverage mappings
|
||||||
let coverage_mapping_size = coverage_mapping_buffer.len();
|
let coverage_mapping_size = coverage_mapping_buffer.len();
|
||||||
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);
|
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue