Skip to content

Commit 23b6508

Browse files
committed
coverage: Split out MC/DC branches from BcbMappingKind
1 parent af33fc8 commit 23b6508

File tree

2 files changed

+72
-80
lines changed

2 files changed

+72
-80
lines changed

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

+49-52
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::collections::BTreeSet;
33
use rustc_data_structures::graph::DirectedGraph;
44
use rustc_index::bit_set::BitSet;
55
use rustc_index::IndexVec;
6-
use rustc_middle::mir::coverage::{
7-
BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan,
8-
};
6+
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind};
97
use rustc_middle::mir::{self, BasicBlock, StatementKind};
108
use rustc_span::Span;
119

@@ -15,23 +13,13 @@ use crate::coverage::spans::{
1513
};
1614
use crate::coverage::ExtractedHirInfo;
1715

18-
#[derive(Clone, Debug)]
16+
#[derive(Clone, Copy, Debug)]
1917
pub(super) enum BcbMappingKind {
2018
/// Associates an ordinary executable code span with its corresponding BCB.
2119
Code(BasicCoverageBlock),
22-
23-
// Ordinary branch mappings are stored separately, so they don't have a
24-
// variant in this enum.
2520
//
26-
/// Associates a mcdc branch span with condition info besides fields for normal branch.
27-
MCDCBranch {
28-
true_bcb: BasicCoverageBlock,
29-
false_bcb: BasicCoverageBlock,
30-
/// If `None`, this actually represents a normal branch mapping inserted
31-
/// for code that was too complex for MC/DC.
32-
condition_info: Option<ConditionInfo>,
33-
decision_depth: u16,
34-
},
21+
// Branch and MC/DC mappings are more complex, so they are represented
22+
// separately.
3523
}
3624

3725
#[derive(Debug)]
@@ -50,6 +38,18 @@ pub(super) struct BcbBranchPair {
5038
pub(super) false_bcb: BasicCoverageBlock,
5139
}
5240

41+
/// Associates an MC/DC branch span with condition info besides fields for normal branch.
42+
#[derive(Debug)]
43+
pub(super) struct MCDCBranch {
44+
pub(super) span: Span,
45+
pub(super) true_bcb: BasicCoverageBlock,
46+
pub(super) false_bcb: BasicCoverageBlock,
47+
/// If `None`, this actually represents a normal branch mapping inserted
48+
/// for code that was too complex for MC/DC.
49+
pub(super) condition_info: Option<ConditionInfo>,
50+
pub(super) decision_depth: u16,
51+
}
52+
5353
/// Associates an MC/DC decision with its join BCBs.
5454
#[derive(Debug)]
5555
pub(super) struct MCDCDecision {
@@ -65,6 +65,7 @@ pub(super) struct CoverageSpans {
6565
pub(super) mappings: Vec<BcbMapping>,
6666
pub(super) branch_pairs: Vec<BcbBranchPair>,
6767
test_vector_bitmap_bytes: u32,
68+
pub(super) mcdc_branches: Vec<MCDCBranch>,
6869
pub(super) mcdc_decisions: Vec<MCDCDecision>,
6970
}
7071

@@ -89,6 +90,7 @@ pub(super) fn generate_coverage_spans(
8990
) -> Option<CoverageSpans> {
9091
let mut mappings = vec![];
9192
let mut branch_pairs = vec![];
93+
let mut mcdc_branches = vec![];
9294
let mut mcdc_decisions = vec![];
9395

9496
if hir_info.is_async_fn {
@@ -104,15 +106,20 @@ pub(super) fn generate_coverage_spans(
104106

105107
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
106108

107-
mappings.extend(extract_mcdc_mappings(
109+
extract_mcdc_mappings(
108110
mir_body,
109111
hir_info.body_span,
110112
basic_coverage_blocks,
113+
&mut mcdc_branches,
111114
&mut mcdc_decisions,
112-
));
115+
);
113116
}
114117

115-
if mappings.is_empty() && branch_pairs.is_empty() && mcdc_decisions.is_empty() {
118+
if mappings.is_empty()
119+
&& branch_pairs.is_empty()
120+
&& mcdc_branches.is_empty()
121+
&& mcdc_decisions.is_empty()
122+
{
116123
return None;
117124
}
118125

@@ -122,19 +129,19 @@ pub(super) fn generate_coverage_spans(
122129
bcb_has_mappings.insert(bcb);
123130
};
124131

125-
for BcbMapping { kind, span: _ } in &mappings {
126-
match *kind {
132+
for &BcbMapping { kind, span: _ } in &mappings {
133+
match kind {
127134
BcbMappingKind::Code(bcb) => insert(bcb),
128-
BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
129-
insert(true_bcb);
130-
insert(false_bcb);
131-
}
132135
}
133136
}
134137
for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
135138
insert(true_bcb);
136139
insert(false_bcb);
137140
}
141+
for &MCDCBranch { true_bcb, false_bcb, .. } in &mcdc_branches {
142+
insert(true_bcb);
143+
insert(false_bcb);
144+
}
138145

139146
// Determine the length of the test vector bitmap.
140147
let test_vector_bitmap_bytes = mcdc_decisions
@@ -150,6 +157,7 @@ pub(super) fn generate_coverage_spans(
150157
mappings,
151158
branch_pairs,
152159
test_vector_bitmap_bytes,
160+
mcdc_branches,
153161
mcdc_decisions,
154162
})
155163
}
@@ -217,11 +225,10 @@ pub(super) fn extract_mcdc_mappings(
217225
mir_body: &mir::Body<'_>,
218226
body_span: Span,
219227
basic_coverage_blocks: &CoverageGraph,
228+
mcdc_branches: &mut impl Extend<MCDCBranch>,
220229
mcdc_decisions: &mut impl Extend<MCDCDecision>,
221-
) -> Vec<BcbMapping> {
222-
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
223-
return vec![];
224-
};
230+
) {
231+
let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return };
225232

226233
let block_markers = resolve_block_markers(branch_info, mir_body);
227234

@@ -242,25 +249,19 @@ pub(super) fn extract_mcdc_mappings(
242249
Some((span, true_bcb, false_bcb))
243250
};
244251

245-
let mcdc_branch_filter_map = |&MCDCBranchSpan {
246-
span: raw_span,
247-
true_marker,
248-
false_marker,
249-
condition_info,
250-
decision_depth,
251-
}| {
252-
check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| {
253-
BcbMapping {
254-
kind: BcbMappingKind::MCDCBranch {
255-
true_bcb,
256-
false_bcb,
257-
condition_info,
258-
decision_depth,
259-
},
260-
span,
261-
}
262-
})
263-
};
252+
mcdc_branches.extend(branch_info.mcdc_branch_spans.iter().filter_map(
253+
|&mir::coverage::MCDCBranchSpan {
254+
span: raw_span,
255+
condition_info,
256+
true_marker,
257+
false_marker,
258+
decision_depth,
259+
}| {
260+
let (span, true_bcb, false_bcb) =
261+
check_branch_bcb(raw_span, true_marker, false_marker)?;
262+
Some(MCDCBranch { span, true_bcb, false_bcb, condition_info, decision_depth })
263+
},
264+
));
264265

265266
let mut next_bitmap_idx = 0;
266267

@@ -286,8 +287,4 @@ pub(super) fn extract_mcdc_mappings(
286287
})
287288
},
288289
));
289-
290-
std::iter::empty()
291-
.chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
292-
.collect::<Vec<_>>()
293290
}

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

+23-28
Original file line numberDiff line numberDiff line change
@@ -150,27 +150,11 @@ fn create_mappings<'tcx>(
150150
let mut mappings = Vec::new();
151151

152152
mappings.extend(coverage_spans.mappings.iter().filter_map(
153-
|BcbMapping { kind: bcb_mapping_kind, span }| {
154-
let kind = match *bcb_mapping_kind {
153+
|&BcbMapping { kind: bcb_mapping_kind, span }| {
154+
let kind = match bcb_mapping_kind {
155155
BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)),
156-
BcbMappingKind::MCDCBranch {
157-
true_bcb, false_bcb, condition_info: None, ..
158-
} => MappingKind::Branch {
159-
true_term: term_for_bcb(true_bcb),
160-
false_term: term_for_bcb(false_bcb),
161-
},
162-
BcbMappingKind::MCDCBranch {
163-
true_bcb,
164-
false_bcb,
165-
condition_info: Some(mcdc_params),
166-
..
167-
} => MappingKind::MCDCBranch {
168-
true_term: term_for_bcb(true_bcb),
169-
false_term: term_for_bcb(false_bcb),
170-
mcdc_params,
171-
},
172156
};
173-
let code_region = make_code_region(source_map, file_name, *span, body_span)?;
157+
let code_region = make_code_region(source_map, file_name, span, body_span)?;
174158
Some(Mapping { kind, code_region })
175159
},
176160
));
@@ -185,6 +169,19 @@ fn create_mappings<'tcx>(
185169
},
186170
));
187171

172+
mappings.extend(coverage_spans.mcdc_branches.iter().filter_map(
173+
|&mappings::MCDCBranch { span, true_bcb, false_bcb, condition_info, decision_depth: _ }| {
174+
let code_region = make_code_region(source_map, file_name, span, body_span)?;
175+
let true_term = term_for_bcb(true_bcb);
176+
let false_term = term_for_bcb(false_bcb);
177+
let kind = match condition_info {
178+
Some(mcdc_params) => MappingKind::MCDCBranch { true_term, false_term, mcdc_params },
179+
None => MappingKind::Branch { true_term, false_term },
180+
};
181+
Some(Mapping { kind, code_region })
182+
},
183+
));
184+
188185
mappings.extend(coverage_spans.mcdc_decisions.iter().filter_map(
189186
|&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
190187
let code_region = make_code_region(source_map, file_name, span, body_span)?;
@@ -278,24 +275,22 @@ fn inject_mcdc_statements<'tcx>(
278275
}
279276
}
280277

281-
for (true_bcb, false_bcb, condition_id, decision_depth) in
282-
coverage_spans.mappings.iter().filter_map(|mapping| match mapping.kind {
283-
BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info, decision_depth } => {
284-
Some((true_bcb, false_bcb, condition_info?.condition_id, decision_depth))
285-
}
286-
_ => None,
287-
})
278+
for &mappings::MCDCBranch { span: _, true_bcb, false_bcb, condition_info, decision_depth } in
279+
&coverage_spans.mcdc_branches
288280
{
281+
let Some(condition_info) = condition_info else { continue };
282+
let id = condition_info.condition_id;
283+
289284
let true_bb = basic_coverage_blocks[true_bcb].leader_bb();
290285
inject_statement(
291286
mir_body,
292-
CoverageKind::CondBitmapUpdate { id: condition_id, value: true, decision_depth },
287+
CoverageKind::CondBitmapUpdate { id, value: true, decision_depth },
293288
true_bb,
294289
);
295290
let false_bb = basic_coverage_blocks[false_bcb].leader_bb();
296291
inject_statement(
297292
mir_body,
298-
CoverageKind::CondBitmapUpdate { id: condition_id, value: false, decision_depth },
293+
CoverageKind::CondBitmapUpdate { id, value: false, decision_depth },
299294
false_bb,
300295
);
301296
}

0 commit comments

Comments
 (0)