coverage. Generate Mappings of decisions and conditions for MC/DC

This commit is contained in:
zhuyunxing
2024-04-19 10:53:04 +08:00
parent 68f86381ee
commit cf6b6cb2b4
10 changed files with 779 additions and 41 deletions

View File

@@ -1,7 +1,9 @@
use rustc_data_structures::graph::DirectedGraph;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir;
use rustc_middle::mir::coverage::ConditionInfo;
use rustc_span::{BytePos, Span};
use std::collections::BTreeSet;
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
use crate::coverage::spans::from_mir::SpanFromMir;
@@ -9,12 +11,20 @@ use crate::coverage::ExtractedHirInfo;
mod from_mir;
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
pub(super) enum BcbMappingKind {
/// Associates an ordinary executable code span with its corresponding BCB.
Code(BasicCoverageBlock),
/// Associates a branch span with BCBs for its true and false arms.
Branch { true_bcb: BasicCoverageBlock, false_bcb: BasicCoverageBlock },
/// Associates a mcdc branch span with condition info besides fields for normal branch.
MCDCBranch {
true_bcb: BasicCoverageBlock,
false_bcb: BasicCoverageBlock,
condition_info: ConditionInfo,
},
/// Associates a mcdc decision with its join BCB.
MCDCDecision { end_bcbs: BTreeSet<BasicCoverageBlock>, bitmap_idx: u32, conditions_num: u16 },
}
#[derive(Debug)]
@@ -26,6 +36,7 @@ pub(super) struct BcbMapping {
pub(super) struct CoverageSpans {
bcb_has_mappings: BitSet<BasicCoverageBlock>,
mappings: Vec<BcbMapping>,
test_vector_bitmap_bytes: u32,
}
impl CoverageSpans {
@@ -36,6 +47,10 @@ impl CoverageSpans {
pub(super) fn all_bcb_mappings(&self) -> impl Iterator<Item = &BcbMapping> {
self.mappings.iter()
}
pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
self.test_vector_bitmap_bytes
}
}
/// Extracts coverage-relevant spans from MIR, and associates them with
@@ -85,17 +100,26 @@ pub(super) fn generate_coverage_spans(
let mut insert = |bcb| {
bcb_has_mappings.insert(bcb);
};
for &BcbMapping { kind, span: _ } in &mappings {
match kind {
let mut test_vector_bitmap_bytes = 0;
for BcbMapping { kind, span: _ } in &mappings {
match *kind {
BcbMappingKind::Code(bcb) => insert(bcb),
BcbMappingKind::Branch { true_bcb, false_bcb } => {
BcbMappingKind::Branch { true_bcb, false_bcb }
| BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
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));
}
}
}
Some(CoverageSpans { bcb_has_mappings, mappings })
Some(CoverageSpans { bcb_has_mappings, mappings, test_vector_bitmap_bytes })
}
#[derive(Debug)]