coverage: Split out MC/DC decisions from BcbMappingKind
This commit is contained in:
parent
d2d24e395a
commit
af33fc85de
2 changed files with 71 additions and 51 deletions
|
@ -2,8 +2,9 @@ use std::collections::BTreeSet;
|
|||
|
||||
use rustc_data_structures::graph::DirectedGraph;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::coverage::{
|
||||
BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
|
||||
BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan,
|
||||
};
|
||||
use rustc_middle::mir::{self, BasicBlock, StatementKind};
|
||||
use rustc_span::Span;
|
||||
|
@ -13,7 +14,6 @@ use crate::coverage::spans::{
|
|||
extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
|
||||
};
|
||||
use crate::coverage::ExtractedHirInfo;
|
||||
use rustc_index::IndexVec;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(super) enum BcbMappingKind {
|
||||
|
@ -32,13 +32,6 @@ pub(super) enum BcbMappingKind {
|
|||
condition_info: Option<ConditionInfo>,
|
||||
decision_depth: u16,
|
||||
},
|
||||
/// Associates a mcdc decision with its join BCB.
|
||||
MCDCDecision {
|
||||
end_bcbs: BTreeSet<BasicCoverageBlock>,
|
||||
bitmap_idx: u32,
|
||||
conditions_num: u16,
|
||||
decision_depth: u16,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -57,11 +50,22 @@ pub(super) struct BcbBranchPair {
|
|||
pub(super) false_bcb: BasicCoverageBlock,
|
||||
}
|
||||
|
||||
/// Associates an MC/DC decision with its join BCBs.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct MCDCDecision {
|
||||
pub(super) span: Span,
|
||||
pub(super) end_bcbs: BTreeSet<BasicCoverageBlock>,
|
||||
pub(super) bitmap_idx: u32,
|
||||
pub(super) conditions_num: u16,
|
||||
pub(super) decision_depth: u16,
|
||||
}
|
||||
|
||||
pub(super) struct CoverageSpans {
|
||||
bcb_has_mappings: BitSet<BasicCoverageBlock>,
|
||||
pub(super) mappings: Vec<BcbMapping>,
|
||||
pub(super) branch_pairs: Vec<BcbBranchPair>,
|
||||
test_vector_bitmap_bytes: u32,
|
||||
pub(super) mcdc_decisions: Vec<MCDCDecision>,
|
||||
}
|
||||
|
||||
impl CoverageSpans {
|
||||
|
@ -85,6 +89,7 @@ pub(super) fn generate_coverage_spans(
|
|||
) -> Option<CoverageSpans> {
|
||||
let mut mappings = vec![];
|
||||
let mut branch_pairs = vec![];
|
||||
let mut mcdc_decisions = vec![];
|
||||
|
||||
if hir_info.is_async_fn {
|
||||
// An async function desugars into a function that returns a future,
|
||||
|
@ -99,10 +104,15 @@ pub(super) fn generate_coverage_spans(
|
|||
|
||||
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
|
||||
|
||||
mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks));
|
||||
mappings.extend(extract_mcdc_mappings(
|
||||
mir_body,
|
||||
hir_info.body_span,
|
||||
basic_coverage_blocks,
|
||||
&mut mcdc_decisions,
|
||||
));
|
||||
}
|
||||
|
||||
if mappings.is_empty() && branch_pairs.is_empty() {
|
||||
if mappings.is_empty() && branch_pairs.is_empty() && mcdc_decisions.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -111,7 +121,7 @@ pub(super) fn generate_coverage_spans(
|
|||
let mut insert = |bcb| {
|
||||
bcb_has_mappings.insert(bcb);
|
||||
};
|
||||
let mut test_vector_bitmap_bytes = 0;
|
||||
|
||||
for BcbMapping { kind, span: _ } in &mappings {
|
||||
match *kind {
|
||||
BcbMappingKind::Code(bcb) => insert(bcb),
|
||||
|
@ -119,13 +129,6 @@ pub(super) fn generate_coverage_spans(
|
|||
insert(true_bcb);
|
||||
insert(false_bcb);
|
||||
}
|
||||
BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
|
||||
// `bcb_has_mappings` is used for inject coverage counters
|
||||
// but they are not needed for decision BCBs.
|
||||
// While the length of test vector bitmap should be calculated here.
|
||||
test_vector_bitmap_bytes = test_vector_bitmap_bytes
|
||||
.max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
|
||||
}
|
||||
}
|
||||
}
|
||||
for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
|
||||
|
@ -133,7 +136,22 @@ pub(super) fn generate_coverage_spans(
|
|||
insert(false_bcb);
|
||||
}
|
||||
|
||||
Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
|
||||
// Determine the length of the test vector bitmap.
|
||||
let test_vector_bitmap_bytes = mcdc_decisions
|
||||
.iter()
|
||||
.map(|&MCDCDecision { bitmap_idx, conditions_num, .. }| {
|
||||
bitmap_idx + (1_u32 << u32::from(conditions_num)).div_ceil(8)
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
Some(CoverageSpans {
|
||||
bcb_has_mappings,
|
||||
mappings,
|
||||
branch_pairs,
|
||||
test_vector_bitmap_bytes,
|
||||
mcdc_decisions,
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_block_markers(
|
||||
|
@ -199,6 +217,7 @@ pub(super) fn extract_mcdc_mappings(
|
|||
mir_body: &mir::Body<'_>,
|
||||
body_span: Span,
|
||||
basic_coverage_blocks: &CoverageGraph,
|
||||
mcdc_decisions: &mut impl Extend<MCDCDecision>,
|
||||
) -> Vec<BcbMapping> {
|
||||
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
|
||||
return vec![];
|
||||
|
@ -245,31 +264,30 @@ pub(super) fn extract_mcdc_mappings(
|
|||
|
||||
let mut next_bitmap_idx = 0;
|
||||
|
||||
let decision_filter_map = |decision: &MCDCDecisionSpan| {
|
||||
let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
|
||||
mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map(
|
||||
|decision: &mir::coverage::MCDCDecisionSpan| {
|
||||
let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
|
||||
|
||||
let end_bcbs = decision
|
||||
.end_markers
|
||||
.iter()
|
||||
.map(|&marker| bcb_from_marker(marker))
|
||||
.collect::<Option<_>>()?;
|
||||
let end_bcbs = decision
|
||||
.end_markers
|
||||
.iter()
|
||||
.map(|&marker| bcb_from_marker(marker))
|
||||
.collect::<Option<_>>()?;
|
||||
|
||||
let bitmap_idx = next_bitmap_idx;
|
||||
next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
|
||||
let bitmap_idx = next_bitmap_idx;
|
||||
next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
|
||||
|
||||
Some(BcbMapping {
|
||||
kind: BcbMappingKind::MCDCDecision {
|
||||
Some(MCDCDecision {
|
||||
span,
|
||||
end_bcbs,
|
||||
bitmap_idx,
|
||||
conditions_num: decision.conditions_num as u16,
|
||||
decision_depth: decision.decision_depth,
|
||||
},
|
||||
span,
|
||||
})
|
||||
};
|
||||
})
|
||||
},
|
||||
));
|
||||
|
||||
std::iter::empty()
|
||||
.chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
|
||||
.chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
|
|
@ -103,12 +103,9 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
|||
inject_mcdc_statements(mir_body, &basic_coverage_blocks, &coverage_spans);
|
||||
|
||||
let mcdc_num_condition_bitmaps = coverage_spans
|
||||
.mappings
|
||||
.mcdc_decisions
|
||||
.iter()
|
||||
.filter_map(|bcb_mapping| match bcb_mapping.kind {
|
||||
BcbMappingKind::MCDCDecision { decision_depth, .. } => Some(decision_depth),
|
||||
_ => None,
|
||||
})
|
||||
.map(|&mappings::MCDCDecision { decision_depth, .. }| decision_depth)
|
||||
.max()
|
||||
.map_or(0, |max| usize::from(max) + 1);
|
||||
|
||||
|
@ -172,9 +169,6 @@ fn create_mappings<'tcx>(
|
|||
false_term: term_for_bcb(false_bcb),
|
||||
mcdc_params,
|
||||
},
|
||||
BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
|
||||
MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num })
|
||||
}
|
||||
};
|
||||
let code_region = make_code_region(source_map, file_name, *span, body_span)?;
|
||||
Some(Mapping { kind, code_region })
|
||||
|
@ -191,6 +185,14 @@ fn create_mappings<'tcx>(
|
|||
},
|
||||
));
|
||||
|
||||
mappings.extend(coverage_spans.mcdc_decisions.iter().filter_map(
|
||||
|&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
|
||||
let code_region = make_code_region(source_map, file_name, span, body_span)?;
|
||||
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num });
|
||||
Some(Mapping { kind, code_region })
|
||||
},
|
||||
));
|
||||
|
||||
mappings
|
||||
}
|
||||
|
||||
|
@ -258,13 +260,13 @@ fn inject_mcdc_statements<'tcx>(
|
|||
}
|
||||
|
||||
// Inject test vector update first because `inject_statement` always insert new statement at head.
|
||||
for (end_bcbs, bitmap_idx, decision_depth) in
|
||||
coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind {
|
||||
BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => {
|
||||
Some((end_bcbs, *bitmap_idx, *decision_depth))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
for &mappings::MCDCDecision {
|
||||
span: _,
|
||||
ref end_bcbs,
|
||||
bitmap_idx,
|
||||
conditions_num: _,
|
||||
decision_depth,
|
||||
} in &coverage_spans.mcdc_decisions
|
||||
{
|
||||
for end in end_bcbs {
|
||||
let end_bb = basic_coverage_blocks[*end].leader_bb();
|
||||
|
|
Loading…
Add table
Reference in a new issue