coverage: Separately compute the set of BCBs with counter mappings
This commit is contained in:
parent
3170bd9d1b
commit
1a26404f10
2 changed files with 59 additions and 46 deletions
|
@ -53,7 +53,6 @@ pub(super) struct MCDCDecision {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct CoverageSpans {
|
pub(super) struct CoverageSpans {
|
||||||
bcb_has_mappings: BitSet<BasicCoverageBlock>,
|
|
||||||
pub(super) code_mappings: Vec<CodeMapping>,
|
pub(super) code_mappings: Vec<CodeMapping>,
|
||||||
pub(super) branch_pairs: Vec<BranchPair>,
|
pub(super) branch_pairs: Vec<BranchPair>,
|
||||||
test_vector_bitmap_bytes: u32,
|
test_vector_bitmap_bytes: u32,
|
||||||
|
@ -62,10 +61,6 @@ pub(super) struct CoverageSpans {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoverageSpans {
|
impl CoverageSpans {
|
||||||
pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {
|
|
||||||
self.bcb_has_mappings.contains(bcb)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
|
pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
|
||||||
self.test_vector_bitmap_bytes
|
self.test_vector_bitmap_bytes
|
||||||
}
|
}
|
||||||
|
@ -73,13 +68,11 @@ impl CoverageSpans {
|
||||||
|
|
||||||
/// Extracts coverage-relevant spans from MIR, and associates them with
|
/// Extracts coverage-relevant spans from MIR, and associates them with
|
||||||
/// their corresponding BCBs.
|
/// their corresponding BCBs.
|
||||||
///
|
|
||||||
/// Returns `None` if no coverage-relevant spans could be extracted.
|
|
||||||
pub(super) fn generate_coverage_spans(
|
pub(super) fn generate_coverage_spans(
|
||||||
mir_body: &mir::Body<'_>,
|
mir_body: &mir::Body<'_>,
|
||||||
hir_info: &ExtractedHirInfo,
|
hir_info: &ExtractedHirInfo,
|
||||||
basic_coverage_blocks: &CoverageGraph,
|
basic_coverage_blocks: &CoverageGraph,
|
||||||
) -> Option<CoverageSpans> {
|
) -> CoverageSpans {
|
||||||
let mut code_mappings = vec![];
|
let mut code_mappings = vec![];
|
||||||
let mut branch_pairs = vec![];
|
let mut branch_pairs = vec![];
|
||||||
let mut mcdc_branches = vec![];
|
let mut mcdc_branches = vec![];
|
||||||
|
@ -107,32 +100,6 @@ pub(super) fn generate_coverage_spans(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if code_mappings.is_empty()
|
|
||||||
&& branch_pairs.is_empty()
|
|
||||||
&& mcdc_branches.is_empty()
|
|
||||||
&& mcdc_decisions.is_empty()
|
|
||||||
{
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Identify which BCBs have one or more mappings.
|
|
||||||
let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
|
|
||||||
let mut insert = |bcb| {
|
|
||||||
bcb_has_mappings.insert(bcb);
|
|
||||||
};
|
|
||||||
|
|
||||||
for &CodeMapping { span: _, bcb } in &code_mappings {
|
|
||||||
insert(bcb);
|
|
||||||
}
|
|
||||||
for &BranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
|
|
||||||
insert(true_bcb);
|
|
||||||
insert(false_bcb);
|
|
||||||
}
|
|
||||||
for &MCDCBranch { true_bcb, false_bcb, .. } in &mcdc_branches {
|
|
||||||
insert(true_bcb);
|
|
||||||
insert(false_bcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the length of the test vector bitmap.
|
// Determine the length of the test vector bitmap.
|
||||||
let test_vector_bitmap_bytes = mcdc_decisions
|
let test_vector_bitmap_bytes = mcdc_decisions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -142,14 +109,57 @@ pub(super) fn generate_coverage_spans(
|
||||||
.max()
|
.max()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
Some(CoverageSpans {
|
CoverageSpans {
|
||||||
bcb_has_mappings,
|
|
||||||
code_mappings,
|
code_mappings,
|
||||||
branch_pairs,
|
branch_pairs,
|
||||||
test_vector_bitmap_bytes,
|
test_vector_bitmap_bytes,
|
||||||
mcdc_branches,
|
mcdc_branches,
|
||||||
mcdc_decisions,
|
mcdc_decisions,
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoverageSpans {
|
||||||
|
pub(super) fn all_bcbs_with_counter_mappings(
|
||||||
|
&self,
|
||||||
|
basic_coverage_blocks: &CoverageGraph, // Only used for allocating a correctly-sized set
|
||||||
|
) -> BitSet<BasicCoverageBlock> {
|
||||||
|
// Fully destructure self to make sure we don't miss any fields that have mappings.
|
||||||
|
let Self {
|
||||||
|
code_mappings,
|
||||||
|
branch_pairs,
|
||||||
|
test_vector_bitmap_bytes: _,
|
||||||
|
mcdc_branches,
|
||||||
|
mcdc_decisions,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
// Identify which BCBs have one or more mappings.
|
||||||
|
let mut bcbs_with_counter_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
|
||||||
|
let mut insert = |bcb| {
|
||||||
|
bcbs_with_counter_mappings.insert(bcb);
|
||||||
|
};
|
||||||
|
|
||||||
|
for &CodeMapping { span: _, bcb } in code_mappings {
|
||||||
|
insert(bcb);
|
||||||
|
}
|
||||||
|
for &BranchPair { true_bcb, false_bcb, .. } in branch_pairs {
|
||||||
|
insert(true_bcb);
|
||||||
|
insert(false_bcb);
|
||||||
|
}
|
||||||
|
for &MCDCBranch { true_bcb, false_bcb, .. } in mcdc_branches {
|
||||||
|
insert(true_bcb);
|
||||||
|
insert(false_bcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MC/DC decisions refer to BCBs, but don't require those BCBs to have counters.
|
||||||
|
if bcbs_with_counter_mappings.is_empty() {
|
||||||
|
debug_assert!(
|
||||||
|
mcdc_decisions.is_empty(),
|
||||||
|
"A function with no counter mappings shouldn't have any decisions: {mcdc_decisions:?}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bcbs_with_counter_mappings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_block_markers(
|
fn resolve_block_markers(
|
||||||
|
|
|
@ -70,21 +70,24 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
// Compute coverage spans from the `CoverageGraph`.
|
// Compute coverage spans from the `CoverageGraph`.
|
||||||
let Some(coverage_spans) =
|
let coverage_spans =
|
||||||
mappings::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks)
|
mappings::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks);
|
||||||
else {
|
|
||||||
// No relevant spans were found in MIR, so skip instrumenting this function.
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
|
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
|
||||||
// every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
|
// every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
|
||||||
// and all `Expression` dependencies (operands) are also generated, for any other
|
// and all `Expression` dependencies (operands) are also generated, for any other
|
||||||
// `BasicCoverageBlock`s not already associated with a coverage span.
|
// `BasicCoverageBlock`s not already associated with a coverage span.
|
||||||
let bcb_has_coverage_spans = |bcb| coverage_spans.bcb_has_coverage_spans(bcb);
|
let bcbs_with_counter_mappings =
|
||||||
|
coverage_spans.all_bcbs_with_counter_mappings(&basic_coverage_blocks);
|
||||||
|
if bcbs_with_counter_mappings.is_empty() {
|
||||||
|
// No relevant spans were found in MIR, so skip instrumenting this function.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bcb_has_counter_mappings = |bcb| bcbs_with_counter_mappings.contains(bcb);
|
||||||
let coverage_counters =
|
let coverage_counters =
|
||||||
CoverageCounters::make_bcb_counters(&basic_coverage_blocks, bcb_has_coverage_spans);
|
CoverageCounters::make_bcb_counters(&basic_coverage_blocks, bcb_has_counter_mappings);
|
||||||
|
|
||||||
let mappings = create_mappings(tcx, &hir_info, &coverage_spans, &coverage_counters);
|
let mappings = create_mappings(tcx, &hir_info, &coverage_spans, &coverage_counters);
|
||||||
if mappings.is_empty() {
|
if mappings.is_empty() {
|
||||||
|
@ -96,7 +99,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
||||||
inject_coverage_statements(
|
inject_coverage_statements(
|
||||||
mir_body,
|
mir_body,
|
||||||
&basic_coverage_blocks,
|
&basic_coverage_blocks,
|
||||||
bcb_has_coverage_spans,
|
bcb_has_counter_mappings,
|
||||||
&coverage_counters,
|
&coverage_counters,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue