coverage. Add BlockMarkerGen to avoid ownership gymnastics

This commit is contained in:
zhuyunxing 2024-04-30 10:05:50 +08:00
parent 7823bf0412
commit a76e250abd

View File

@ -20,7 +20,7 @@ pub(crate) struct BranchInfoBuilder {
/// Maps condition expressions to their enclosing `!`, for better instrumentation. /// Maps condition expressions to their enclosing `!`, for better instrumentation.
nots: FxHashMap<ExprId, NotInfo>, nots: FxHashMap<ExprId, NotInfo>,
num_block_markers: usize, markers: BlockMarkerGen,
branch_spans: Vec<BranchSpan>, branch_spans: Vec<BranchSpan>,
mcdc_branch_spans: Vec<MCDCBranchSpan>, mcdc_branch_spans: Vec<MCDCBranchSpan>,
@ -38,6 +38,35 @@ struct NotInfo {
is_flipped: bool, is_flipped: bool,
} }
#[derive(Default)]
struct BlockMarkerGen {
num_block_markers: usize,
}
impl BlockMarkerGen {
fn next_block_marker_id(&mut self) -> BlockMarkerId {
let id = BlockMarkerId::from_usize(self.num_block_markers);
self.num_block_markers += 1;
id
}
fn inject_block_marker(
&mut self,
cfg: &mut CFG<'_>,
source_info: SourceInfo,
block: BasicBlock,
) -> BlockMarkerId {
let id = self.next_block_marker_id();
let marker_statement = mir::Statement {
source_info,
kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
};
cfg.push(block, marker_statement);
id
}
}
impl BranchInfoBuilder { impl BranchInfoBuilder {
/// Creates a new branch info builder, but only if branch coverage instrumentation /// Creates a new branch info builder, but only if branch coverage instrumentation
/// is enabled and `def_id` represents a function that is eligible for coverage. /// is enabled and `def_id` represents a function that is eligible for coverage.
@ -45,7 +74,7 @@ pub(crate) fn new_if_enabled(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Self
if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) { if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) {
Some(Self { Some(Self {
nots: FxHashMap::default(), nots: FxHashMap::default(),
num_block_markers: 0, markers: BlockMarkerGen::default(),
branch_spans: vec![], branch_spans: vec![],
mcdc_branch_spans: vec![], mcdc_branch_spans: vec![],
mcdc_decision_spans: vec![], mcdc_decision_spans: vec![],
@ -145,39 +174,16 @@ fn add_two_way_branch<'tcx>(
true_block: BasicBlock, true_block: BasicBlock,
false_block: BasicBlock, false_block: BasicBlock,
) { ) {
let true_marker = self.inject_block_marker(cfg, source_info, true_block); let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
let false_marker = self.inject_block_marker(cfg, source_info, false_block); let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker }); self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
} }
fn next_block_marker_id(&mut self) -> BlockMarkerId {
let id = BlockMarkerId::from_usize(self.num_block_markers);
self.num_block_markers += 1;
id
}
fn inject_block_marker(
&mut self,
cfg: &mut CFG<'_>,
source_info: SourceInfo,
block: BasicBlock,
) -> BlockMarkerId {
let id = self.next_block_marker_id();
let marker_statement = mir::Statement {
source_info,
kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
};
cfg.push(block, marker_statement);
id
}
pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> { pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
let Self { let Self {
nots: _, nots: _,
num_block_markers, markers: BlockMarkerGen { num_block_markers },
branch_spans, branch_spans,
mcdc_branch_spans, mcdc_branch_spans,
mcdc_decision_spans, mcdc_decision_spans,
@ -386,7 +392,7 @@ pub(crate) fn visit_coverage_branch_condition(
// Separate path for handling branches when MC/DC is enabled. // Separate path for handling branches when MC/DC is enabled.
if branch_info.mcdc_state.is_some() { if branch_info.mcdc_state.is_some() {
let mut inject_block_marker = let mut inject_block_marker =
|block| branch_info.inject_block_marker(&mut self.cfg, source_info, block); |block| branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block);
let true_marker = inject_block_marker(then_block); let true_marker = inject_block_marker(then_block);
let false_marker = inject_block_marker(else_block); let false_marker = inject_block_marker(else_block);
let (decision_depth, condition_info) = branch_info let (decision_depth, condition_info) = branch_info