Skip to content

Commit b3632b2

Browse files
committed
coverage: Represent branches as a list of arms during MIR building, too
1 parent ce5bdb9 commit b3632b2

File tree

6 files changed

+52
-37
lines changed

6 files changed

+52
-37
lines changed

compiler/rustc_middle/src/mir/coverage.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -279,17 +279,16 @@ pub struct BranchInfo {
279279
/// injected into the MIR body. This makes it possible to allocate per-ID
280280
/// data structures without having to scan the entire body first.
281281
pub num_block_markers: usize,
282-
pub branch_spans: Vec<BranchSpan>,
282+
pub branch_arm_lists: Vec<Vec<BranchArm>>,
283283
pub mcdc_branch_spans: Vec<MCDCBranchSpan>,
284284
pub mcdc_decision_spans: Vec<MCDCDecisionSpan>,
285285
}
286286

287287
#[derive(Clone, Debug)]
288288
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
289-
pub struct BranchSpan {
289+
pub struct BranchArm {
290290
pub span: Span,
291-
pub true_marker: BlockMarkerId,
292-
pub false_marker: BlockMarkerId,
291+
pub marker: BlockMarkerId,
293292
}
294293

295294
#[derive(Copy, Clone, Debug)]

compiler/rustc_middle/src/mir/pretty.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,18 @@ fn write_coverage_branch_info(
475475
branch_info: &coverage::BranchInfo,
476476
w: &mut dyn io::Write,
477477
) -> io::Result<()> {
478-
let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
478+
let coverage::BranchInfo { branch_arm_lists, mcdc_branch_spans, mcdc_decision_spans, .. } =
479479
branch_info;
480480

481-
for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
482-
writeln!(
483-
w,
484-
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
485-
)?;
481+
for arms in branch_arm_lists {
482+
writeln!(w, "{INDENT}coverage branches {{")?;
483+
for coverage::BranchArm { span, marker } in arms {
484+
writeln!(w, "{INDENT}{INDENT}{marker:?} => {span:?}")?;
485+
}
486+
writeln!(w, "{INDENT}}}")?;
487+
}
488+
if !branch_arm_lists.is_empty() {
489+
writeln!(w)?;
486490
}
487491

488492
for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
@@ -502,8 +506,7 @@ fn write_coverage_branch_info(
502506
)?;
503507
}
504508

505-
if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
506-
{
509+
if !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty() {
507510
writeln!(w)?;
508511
}
509512

compiler/rustc_mir_build/src/build/coverageinfo.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::collections::VecDeque;
44

55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_middle::mir::coverage::{
7-
BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
7+
BlockMarkerId, BranchArm, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
88
MCDCDecisionSpan,
99
};
1010
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
@@ -21,7 +21,7 @@ pub(crate) struct BranchInfoBuilder {
2121
nots: FxHashMap<ExprId, NotInfo>,
2222

2323
num_block_markers: usize,
24-
branch_spans: Vec<BranchSpan>,
24+
branch_arm_lists: Vec<Vec<BranchArm>>,
2525

2626
mcdc_branch_spans: Vec<MCDCBranchSpan>,
2727
mcdc_decision_spans: Vec<MCDCDecisionSpan>,
@@ -46,7 +46,7 @@ impl BranchInfoBuilder {
4646
Some(Self {
4747
nots: FxHashMap::default(),
4848
num_block_markers: 0,
49-
branch_spans: vec![],
49+
branch_arm_lists: vec![],
5050
mcdc_branch_spans: vec![],
5151
mcdc_decision_spans: vec![],
5252
mcdc_state: MCDCState::new_if_enabled(tcx),
@@ -144,7 +144,10 @@ impl BranchInfoBuilder {
144144
let true_marker = self.inject_block_marker(cfg, source_info, true_block);
145145
let false_marker = self.inject_block_marker(cfg, source_info, false_block);
146146

147-
self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
147+
self.branch_arm_lists.push(vec![
148+
BranchArm { span: source_info.span, marker: true_marker },
149+
BranchArm { span: source_info.span, marker: false_marker },
150+
]);
148151
}
149152

150153
fn next_block_marker_id(&mut self) -> BlockMarkerId {
@@ -174,20 +177,20 @@ impl BranchInfoBuilder {
174177
let Self {
175178
nots: _,
176179
num_block_markers,
177-
branch_spans,
180+
branch_arm_lists,
178181
mcdc_branch_spans,
179182
mcdc_decision_spans,
180183
mcdc_state: _,
181184
} = self;
182185

183186
if num_block_markers == 0 {
184-
assert!(branch_spans.is_empty());
187+
assert!(branch_arm_lists.is_empty());
185188
return None;
186189
}
187190

188191
Some(Box::new(mir::coverage::BranchInfo {
189192
num_block_markers,
190-
branch_spans,
193+
branch_arm_lists,
191194
mcdc_branch_spans,
192195
mcdc_decision_spans,
193196
}))
@@ -337,7 +340,7 @@ impl MCDCState {
337340

338341
impl Builder<'_, '_> {
339342
/// If branch coverage is enabled, inject marker statements into `then_block`
340-
/// and `else_block`, and record their IDs in the table of branch spans.
343+
/// and `else_block`, and record their IDs in the table of branches.
341344
pub(crate) fn visit_coverage_branch_condition(
342345
&mut self,
343346
mut expr_id: ExprId,

compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_data_structures::captures::Captures;
22
use rustc_data_structures::fx::FxHashSet;
33
use rustc_index::IndexVec;
44
use rustc_middle::mir::coverage::{
5-
BlockMarkerId, BranchSpan, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
5+
BlockMarkerId, BranchArm, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
66
};
77
use rustc_middle::mir::{
88
self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
@@ -403,24 +403,26 @@ pub(super) fn extract_branch_arm_lists(
403403
let block_markers = resolve_block_markers(branch_info, mir_body);
404404

405405
branch_info
406-
.branch_spans
406+
.branch_arm_lists
407407
.iter()
408-
.filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
409-
// For now, ignore any branch span that was introduced by
410-
// expansion. This makes things like assert macros less noisy.
411-
if !raw_span.ctxt().outer_expn_data().is_root() {
412-
return None;
413-
}
414-
let (span, _) =
415-
unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?;
408+
.filter_map(|arms| {
409+
let mut bcb_arms = vec![];
410+
for &BranchArm { span: raw_span, marker } in arms {
411+
// For now, ignore any branch span that was introduced by
412+
// expansion. This makes things like assert macros less noisy.
413+
if !raw_span.ctxt().outer_expn_data().is_root() {
414+
return None;
415+
}
416416

417-
let bcb_from_marker =
418-
|marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
417+
let (span, _) =
418+
unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?;
419419

420-
let true_bcb = bcb_from_marker(true_marker)?;
421-
let false_bcb = bcb_from_marker(false_marker)?;
420+
let bcb = basic_coverage_blocks.bcb_from_bb(block_markers[marker]?)?;
421+
422+
bcb_arms.push(BcbBranchArm { span, bcb });
423+
}
422424

423-
Some(vec![BcbBranchArm { span, bcb: true_bcb }, BcbBranchArm { span, bcb: false_bcb }])
425+
(bcb_arms.len() >= 2).then_some(bcb_arms)
424426
})
425427
.collect::<Vec<_>>()
426428
}

tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
let mut _0: ();
66
let mut _1: bool;
77

8-
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
8+
coverage branches {
9+
BlockMarkerId(0) => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
10+
BlockMarkerId(1) => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
11+
}
912

1013
coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
1114
coverage ExpressionId(1) => Expression { lhs: Counter(1), op: Add, rhs: Expression(0) };
15+
coverage ExpressionId(2) => Expression { lhs: Expression(0), op: Add, rhs: Counter(1) };
1216
coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1 - 14:36;
1317
coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37 - 14:39;
1418
coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39 - 14:40;

tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
let mut _0: ();
66
let mut _1: bool;
77

8-
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
8+
coverage branches {
9+
BlockMarkerId(0) => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
10+
BlockMarkerId(1) => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
11+
}
912

1013
+ coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
1114
+ coverage ExpressionId(1) => Expression { lhs: Counter(1), op: Add, rhs: Expression(0) };
15+
+ coverage ExpressionId(2) => Expression { lhs: Expression(0), op: Add, rhs: Counter(1) };
1216
+ coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1 - 14:36;
1317
+ coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37 - 14:39;
1418
+ coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39 - 14:40;

0 commit comments

Comments
 (0)