Skip to content

Commit af33fc8

Browse files
committed
coverage: Split out MC/DC decisions from BcbMappingKind
1 parent d2d24e3 commit af33fc8

File tree

2 files changed

+71
-51
lines changed

2 files changed

+71
-51
lines changed

Diff for: compiler/rustc_mir_transform/src/coverage/mappings.rs

+54-36
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use std::collections::BTreeSet;
22

33
use rustc_data_structures::graph::DirectedGraph;
44
use rustc_index::bit_set::BitSet;
5+
use rustc_index::IndexVec;
56
use rustc_middle::mir::coverage::{
6-
BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
7+
BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan,
78
};
89
use rustc_middle::mir::{self, BasicBlock, StatementKind};
910
use rustc_span::Span;
@@ -13,7 +14,6 @@ use crate::coverage::spans::{
1314
extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
1415
};
1516
use crate::coverage::ExtractedHirInfo;
16-
use rustc_index::IndexVec;
1717

1818
#[derive(Clone, Debug)]
1919
pub(super) enum BcbMappingKind {
@@ -32,13 +32,6 @@ pub(super) enum BcbMappingKind {
3232
condition_info: Option<ConditionInfo>,
3333
decision_depth: u16,
3434
},
35-
/// Associates a mcdc decision with its join BCB.
36-
MCDCDecision {
37-
end_bcbs: BTreeSet<BasicCoverageBlock>,
38-
bitmap_idx: u32,
39-
conditions_num: u16,
40-
decision_depth: u16,
41-
},
4235
}
4336

4437
#[derive(Debug)]
@@ -57,11 +50,22 @@ pub(super) struct BcbBranchPair {
5750
pub(super) false_bcb: BasicCoverageBlock,
5851
}
5952

53+
/// Associates an MC/DC decision with its join BCBs.
54+
#[derive(Debug)]
55+
pub(super) struct MCDCDecision {
56+
pub(super) span: Span,
57+
pub(super) end_bcbs: BTreeSet<BasicCoverageBlock>,
58+
pub(super) bitmap_idx: u32,
59+
pub(super) conditions_num: u16,
60+
pub(super) decision_depth: u16,
61+
}
62+
6063
pub(super) struct CoverageSpans {
6164
bcb_has_mappings: BitSet<BasicCoverageBlock>,
6265
pub(super) mappings: Vec<BcbMapping>,
6366
pub(super) branch_pairs: Vec<BcbBranchPair>,
6467
test_vector_bitmap_bytes: u32,
68+
pub(super) mcdc_decisions: Vec<MCDCDecision>,
6569
}
6670

6771
impl CoverageSpans {
@@ -85,6 +89,7 @@ pub(super) fn generate_coverage_spans(
8589
) -> Option<CoverageSpans> {
8690
let mut mappings = vec![];
8791
let mut branch_pairs = vec![];
92+
let mut mcdc_decisions = vec![];
8893

8994
if hir_info.is_async_fn {
9095
// An async function desugars into a function that returns a future,
@@ -99,10 +104,15 @@ pub(super) fn generate_coverage_spans(
99104

100105
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
101106

102-
mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks));
107+
mappings.extend(extract_mcdc_mappings(
108+
mir_body,
109+
hir_info.body_span,
110+
basic_coverage_blocks,
111+
&mut mcdc_decisions,
112+
));
103113
}
104114

105-
if mappings.is_empty() && branch_pairs.is_empty() {
115+
if mappings.is_empty() && branch_pairs.is_empty() && mcdc_decisions.is_empty() {
106116
return None;
107117
}
108118

@@ -111,29 +121,37 @@ pub(super) fn generate_coverage_spans(
111121
let mut insert = |bcb| {
112122
bcb_has_mappings.insert(bcb);
113123
};
114-
let mut test_vector_bitmap_bytes = 0;
124+
115125
for BcbMapping { kind, span: _ } in &mappings {
116126
match *kind {
117127
BcbMappingKind::Code(bcb) => insert(bcb),
118128
BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
119129
insert(true_bcb);
120130
insert(false_bcb);
121131
}
122-
BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
123-
// `bcb_has_mappings` is used for inject coverage counters
124-
// but they are not needed for decision BCBs.
125-
// While the length of test vector bitmap should be calculated here.
126-
test_vector_bitmap_bytes = test_vector_bitmap_bytes
127-
.max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
128-
}
129132
}
130133
}
131134
for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
132135
insert(true_bcb);
133136
insert(false_bcb);
134137
}
135138

136-
Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
139+
// Determine the length of the test vector bitmap.
140+
let test_vector_bitmap_bytes = mcdc_decisions
141+
.iter()
142+
.map(|&MCDCDecision { bitmap_idx, conditions_num, .. }| {
143+
bitmap_idx + (1_u32 << u32::from(conditions_num)).div_ceil(8)
144+
})
145+
.max()
146+
.unwrap_or(0);
147+
148+
Some(CoverageSpans {
149+
bcb_has_mappings,
150+
mappings,
151+
branch_pairs,
152+
test_vector_bitmap_bytes,
153+
mcdc_decisions,
154+
})
137155
}
138156

139157
fn resolve_block_markers(
@@ -199,6 +217,7 @@ pub(super) fn extract_mcdc_mappings(
199217
mir_body: &mir::Body<'_>,
200218
body_span: Span,
201219
basic_coverage_blocks: &CoverageGraph,
220+
mcdc_decisions: &mut impl Extend<MCDCDecision>,
202221
) -> Vec<BcbMapping> {
203222
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
204223
return vec![];
@@ -245,31 +264,30 @@ pub(super) fn extract_mcdc_mappings(
245264

246265
let mut next_bitmap_idx = 0;
247266

248-
let decision_filter_map = |decision: &MCDCDecisionSpan| {
249-
let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
267+
mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map(
268+
|decision: &mir::coverage::MCDCDecisionSpan| {
269+
let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
250270

251-
let end_bcbs = decision
252-
.end_markers
253-
.iter()
254-
.map(|&marker| bcb_from_marker(marker))
255-
.collect::<Option<_>>()?;
271+
let end_bcbs = decision
272+
.end_markers
273+
.iter()
274+
.map(|&marker| bcb_from_marker(marker))
275+
.collect::<Option<_>>()?;
256276

257-
let bitmap_idx = next_bitmap_idx;
258-
next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
277+
let bitmap_idx = next_bitmap_idx;
278+
next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
259279

260-
Some(BcbMapping {
261-
kind: BcbMappingKind::MCDCDecision {
280+
Some(MCDCDecision {
281+
span,
262282
end_bcbs,
263283
bitmap_idx,
264284
conditions_num: decision.conditions_num as u16,
265285
decision_depth: decision.decision_depth,
266-
},
267-
span,
268-
})
269-
};
286+
})
287+
},
288+
));
270289

271290
std::iter::empty()
272291
.chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
273-
.chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
274292
.collect::<Vec<_>>()
275293
}

Diff for: compiler/rustc_mir_transform/src/coverage/mod.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,9 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
103103
inject_mcdc_statements(mir_body, &basic_coverage_blocks, &coverage_spans);
104104

105105
let mcdc_num_condition_bitmaps = coverage_spans
106-
.mappings
106+
.mcdc_decisions
107107
.iter()
108-
.filter_map(|bcb_mapping| match bcb_mapping.kind {
109-
BcbMappingKind::MCDCDecision { decision_depth, .. } => Some(decision_depth),
110-
_ => None,
111-
})
108+
.map(|&mappings::MCDCDecision { decision_depth, .. }| decision_depth)
112109
.max()
113110
.map_or(0, |max| usize::from(max) + 1);
114111

@@ -172,9 +169,6 @@ fn create_mappings<'tcx>(
172169
false_term: term_for_bcb(false_bcb),
173170
mcdc_params,
174171
},
175-
BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
176-
MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num })
177-
}
178172
};
179173
let code_region = make_code_region(source_map, file_name, *span, body_span)?;
180174
Some(Mapping { kind, code_region })
@@ -191,6 +185,14 @@ fn create_mappings<'tcx>(
191185
},
192186
));
193187

188+
mappings.extend(coverage_spans.mcdc_decisions.iter().filter_map(
189+
|&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
190+
let code_region = make_code_region(source_map, file_name, span, body_span)?;
191+
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num });
192+
Some(Mapping { kind, code_region })
193+
},
194+
));
195+
194196
mappings
195197
}
196198

@@ -258,13 +260,13 @@ fn inject_mcdc_statements<'tcx>(
258260
}
259261

260262
// Inject test vector update first because `inject_statement` always insert new statement at head.
261-
for (end_bcbs, bitmap_idx, decision_depth) in
262-
coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind {
263-
BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => {
264-
Some((end_bcbs, *bitmap_idx, *decision_depth))
265-
}
266-
_ => None,
267-
})
263+
for &mappings::MCDCDecision {
264+
span: _,
265+
ref end_bcbs,
266+
bitmap_idx,
267+
conditions_num: _,
268+
decision_depth,
269+
} in &coverage_spans.mcdc_decisions
268270
{
269271
for end in end_bcbs {
270272
let end_bb = basic_coverage_blocks[*end].leader_bb();

0 commit comments

Comments
 (0)