Skip to content

Commit 8712975

Browse files
author
zhuyunxing
committed
coverage. Introduce MCDCBranchMarker to trace branch blocks of conditions
1 parent c002a8f commit 8712975

File tree

7 files changed

+276
-191
lines changed

7 files changed

+276
-191
lines changed

compiler/rustc_middle/src/mir/coverage.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ pub struct BranchInfo {
291291
/// data structures without having to scan the entire body first.
292292
pub num_block_markers: usize,
293293
pub branch_spans: Vec<BranchSpan>,
294-
pub mcdc_branch_spans: Vec<MCDCBranchSpan>,
295-
pub mcdc_decision_spans: Vec<MCDCDecisionSpan>,
294+
pub mcdc_degraded_spans: Vec<MCDCBranchSpan>,
295+
pub mcdc_spans: Vec<(MCDCDecisionSpan, Vec<MCDCBranchSpan>)>,
296296
}
297297

298298
#[derive(Clone, Debug)]
@@ -325,12 +325,16 @@ impl Default for ConditionInfo {
325325
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
326326
pub struct MCDCBranchSpan {
327327
pub span: Span,
328-
/// If `None`, this actually represents a normal branch span inserted for
329-
/// code that was too complex for MC/DC.
330-
pub condition_info: Option<ConditionInfo>,
331-
pub true_marker: BlockMarkerId,
332-
pub false_marker: BlockMarkerId,
333-
pub decision_depth: u16,
328+
pub condition_info: ConditionInfo,
329+
pub markers: MCDCBranchMarkers,
330+
}
331+
332+
#[derive(Clone, Debug)]
333+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
334+
pub enum MCDCBranchMarkers {
335+
/// The first indicates true branch, the second indicates the false branch.
336+
Boolean(BlockMarkerId, BlockMarkerId),
337+
PatternMatching,
334338
}
335339

336340
#[derive(Copy, Clone, Debug)]
@@ -344,7 +348,6 @@ pub struct DecisionInfo {
344348
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
345349
pub struct MCDCDecisionSpan {
346350
pub span: Span,
347-
pub num_conditions: usize,
348351
pub end_markers: Vec<BlockMarkerId>,
349352
pub decision_depth: u16,
350353
}

compiler/rustc_middle/src/mir/pretty.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,7 @@ fn write_coverage_branch_info(
487487
branch_info: &coverage::BranchInfo,
488488
w: &mut dyn io::Write,
489489
) -> io::Result<()> {
490-
let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
491-
branch_info;
490+
let coverage::BranchInfo { branch_spans, mcdc_degraded_spans, mcdc_spans, .. } = branch_info;
492491

493492
for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
494493
writeln!(
@@ -497,32 +496,30 @@ fn write_coverage_branch_info(
497496
)?;
498497
}
499498

500-
for coverage::MCDCBranchSpan {
501-
span,
502-
condition_info,
503-
true_marker,
504-
false_marker,
505-
decision_depth,
506-
} in mcdc_branch_spans
507-
{
499+
for coverage::MCDCBranchSpan { span, markers, .. } in mcdc_degraded_spans {
508500
writeln!(
509501
w,
510-
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
511-
condition_info.map(|info| info.condition_id)
502+
"{INDENT}coverage mcdc degraded branch {{ markers: {markers:?} }} => {span:?}",
512503
)?;
513504
}
514505

515-
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
516-
mcdc_decision_spans
506+
for (coverage::MCDCDecisionSpan { span, end_markers, decision_depth }, conditions) in mcdc_spans
517507
{
508+
let num_conditions = conditions.len();
518509
writeln!(
519510
w,
520511
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
521512
)?;
513+
for coverage::MCDCBranchSpan { span, condition_info, markers } in conditions {
514+
writeln!(
515+
w,
516+
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, markers: {markers:?} }} => {span:?}",
517+
condition_info.condition_id
518+
)?;
519+
}
522520
}
523521

524-
if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
525-
{
522+
if !branch_spans.is_empty() || !mcdc_degraded_spans.is_empty() || !mcdc_spans.is_empty() {
526523
writeln!(w)?;
527524
}
528525

compiler/rustc_mir_build/src/build/coverageinfo.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,13 @@ impl BranchInfoBuilder {
162162
return None;
163163
}
164164

165-
let (mut mcdc_branch_spans, mcdc_spans) =
165+
let (mcdc_degraded_spans, mcdc_spans) =
166166
mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
167-
let mut mcdc_decision_spans = Vec::with_capacity(mcdc_spans.len());
168-
for (decision, conditions) in mcdc_spans {
169-
mcdc_branch_spans.extend(conditions);
170-
mcdc_decision_spans.push(decision);
171-
}
172167
Some(Box::new(mir::coverage::BranchInfo {
173168
num_block_markers,
174169
branch_spans,
175-
mcdc_branch_spans,
176-
mcdc_decision_spans,
170+
mcdc_degraded_spans,
171+
mcdc_spans,
177172
}))
178173
}
179174
}

compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::collections::VecDeque;
33
use rustc_data_structures::fx::FxIndexMap;
44
use rustc_middle::bug;
55
use rustc_middle::mir::coverage::{
6-
BlockMarkerId, ConditionId, ConditionInfo, DecisionId, MCDCBranchSpan, MCDCDecisionSpan,
6+
BlockMarkerId, ConditionId, ConditionInfo, DecisionId, MCDCBranchMarkers, MCDCBranchSpan,
7+
MCDCDecisionSpan,
78
};
89
use rustc_middle::mir::BasicBlock;
910
use rustc_middle::thir::LogicalOp;
@@ -29,6 +30,7 @@ struct BooleanDecisionCtx {
2930
/// To construct condition evaluation tree.
3031
decision_stack: VecDeque<ConditionInfo>,
3132
conditions: Vec<MCDCBranchSpan>,
33+
condition_id_counter: usize,
3234
}
3335

3436
impl BooleanDecisionCtx {
@@ -37,15 +39,20 @@ impl BooleanDecisionCtx {
3739
id,
3840
decision_info: MCDCDecisionSpan {
3941
span: Span::default(),
40-
num_conditions: 0,
4142
end_markers: vec![],
4243
decision_depth: 0,
4344
},
4445
decision_stack: VecDeque::new(),
4546
conditions: vec![],
47+
condition_id_counter: 0,
4648
}
4749
}
4850

51+
fn next_condition_id(&mut self) -> ConditionId {
52+
self.condition_id_counter += 1;
53+
ConditionId::from_usize(self.condition_id_counter)
54+
}
55+
4956
// At first we assign ConditionIds for each sub expression.
5057
// If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS.
5158
//
@@ -89,14 +96,12 @@ impl BooleanDecisionCtx {
8996
fn record_conditions(&mut self, op: LogicalOp) {
9097
let parent_condition = self.decision_stack.pop_back().unwrap_or_default();
9198
let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
92-
self.decision_info.num_conditions += 1;
93-
ConditionId::from(self.decision_info.num_conditions)
99+
ConditionId::from(self.next_condition_id())
94100
} else {
95101
parent_condition.condition_id
96102
};
97103

98-
self.decision_info.num_conditions += 1;
99-
let rhs_condition_id = ConditionId::from(self.decision_info.num_conditions);
104+
let rhs_condition_id = self.next_condition_id();
100105

101106
let (lhs, rhs) = match op {
102107
LogicalOp::And => {
@@ -147,13 +152,9 @@ impl BooleanDecisionCtx {
147152

148153
self.conditions.push(MCDCBranchSpan {
149154
span,
150-
condition_info: Some(condition_info),
151-
true_marker,
152-
false_marker,
153-
decision_depth: 0,
155+
condition_info,
156+
markers: MCDCBranchMarkers::Boolean(true_marker, false_marker),
154157
});
155-
// In case this decision had only one condition
156-
self.decision_info.num_conditions = self.decision_info.num_conditions.max(1);
157158
}
158159

159160
fn is_finished(&self) -> bool {
@@ -250,7 +251,6 @@ struct MCDCTargetInfo {
250251
impl MCDCTargetInfo {
251252
fn set_depth(&mut self, depth: u16) {
252253
self.decision.decision_depth = depth;
253-
self.conditions.iter_mut().for_each(|branch| branch.decision_depth = depth);
254254
}
255255
}
256256

@@ -298,7 +298,9 @@ impl MCDCInfoBuilder {
298298
}
299299

300300
fn append_normal_branches(&mut self, mut branches: Vec<MCDCBranchSpan>) {
301-
branches.iter_mut().for_each(|branch| branch.condition_info = None);
301+
branches
302+
.iter_mut()
303+
.for_each(|branch| branch.condition_info.condition_id = ConditionId::NONE);
302304
self.normal_branch_spans.extend(branches);
303305
}
304306

compiler/rustc_mir_transform/src/coverage/counters.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ impl CoverageCounters {
101101
BcbCounter::Counter { id }
102102
}
103103

104-
fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter {
104+
pub(super) fn make_expression(
105+
&mut self,
106+
lhs: BcbCounter,
107+
op: Op,
108+
rhs: BcbCounter,
109+
) -> BcbCounter {
105110
let new_expr = BcbExpression { lhs, op, rhs };
106111
*self
107112
.expressions_memo
@@ -159,7 +164,11 @@ impl CoverageCounters {
159164
/// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`].
160165
///
161166
/// This is useful when using [`Iterator::fold`] to build an arbitrary-length sum.
162-
fn make_sum_expression(&mut self, lhs: Option<BcbCounter>, rhs: BcbCounter) -> BcbCounter {
167+
pub(super) fn make_sum_expression(
168+
&mut self,
169+
lhs: Option<BcbCounter>,
170+
rhs: BcbCounter,
171+
) -> BcbCounter {
163172
let Some(lhs) = lhs else { return rhs };
164173
self.make_expression(lhs, Op::Add, rhs)
165174
}

0 commit comments

Comments
 (0)