Skip to content

Commit 435dc44

Browse files
author
zhuyunxing
committed
coverage. Split structures for mcdc branches and normal branches
1 parent b1a100e commit 435dc44

File tree

8 files changed

+185
-106
lines changed

8 files changed

+185
-106
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,24 @@ impl CounterMappingRegion {
250250
MappingKind::Branch { true_term, false_term } => Self::branch_region(
251251
Counter::from_term(true_term),
252252
Counter::from_term(false_term),
253-
None,
254-
local_file_id,
255-
start_line,
256-
start_col,
257-
end_line,
258-
end_col,
259-
),
260-
MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => Self::branch_region(
261-
Counter::from_term(true_term),
262-
Counter::from_term(false_term),
263-
Some(mcdc_params),
264253
local_file_id,
265254
start_line,
266255
start_col,
267256
end_line,
268257
end_col,
269258
),
259+
MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
260+
Self::mcdc_branch_region(
261+
Counter::from_term(true_term),
262+
Counter::from_term(false_term),
263+
mcdc_params,
264+
local_file_id,
265+
start_line,
266+
start_col,
267+
end_line,
268+
end_col,
269+
)
270+
}
270271
MappingKind::MCDCDecision(decision_info) => Self::decision_region(
271272
decision_info,
272273
local_file_id,
@@ -303,28 +304,47 @@ impl CounterMappingRegion {
303304
pub(crate) fn branch_region(
304305
counter: Counter,
305306
false_counter: Counter,
306-
condition_info: Option<ConditionInfo>,
307307
file_id: u32,
308308
start_line: u32,
309309
start_col: u32,
310310
end_line: u32,
311311
end_col: u32,
312312
) -> Self {
313-
let (kind, mcdc_params) = match condition_info {
314-
Some(info) => (RegionKind::MCDCBranchRegion, mcdc::Parameters::branch(info.into())),
315-
None => (RegionKind::BranchRegion, mcdc::Parameters::none()),
316-
};
317313
Self {
318314
counter,
319315
false_counter,
320-
mcdc_params,
316+
mcdc_params: mcdc::Parameters::none(),
317+
file_id,
318+
expanded_file_id: 0,
319+
start_line,
320+
start_col,
321+
end_line,
322+
end_col,
323+
kind: RegionKind::BranchRegion,
324+
}
325+
}
326+
327+
pub(crate) fn mcdc_branch_region(
328+
counter: Counter,
329+
false_counter: Counter,
330+
condition_info: ConditionInfo,
331+
file_id: u32,
332+
start_line: u32,
333+
start_col: u32,
334+
end_line: u32,
335+
end_col: u32,
336+
) -> Self {
337+
Self {
338+
counter,
339+
false_counter,
340+
mcdc_params: mcdc::Parameters::branch(condition_info.into()),
321341
file_id,
322342
expanded_file_id: 0,
323343
start_line,
324344
start_col,
325345
end_line,
326346
end_col,
327-
kind,
347+
kind: RegionKind::MCDCBranchRegion,
328348
}
329349
}
330350

compiler/rustc_middle/src/mir/coverage.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,14 @@ pub struct BranchInfo {
278278
/// data structures without having to scan the entire body first.
279279
pub num_block_markers: usize,
280280
pub branch_spans: Vec<BranchSpan>,
281-
pub decision_spans: Vec<DecisionSpan>,
281+
pub mcdc_branch_spans: Vec<MCDCBranchSpan>,
282+
pub mcdc_decision_spans: Vec<MCDCDecisionSpan>,
282283
}
283284

284285
#[derive(Clone, Debug)]
285286
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
286287
pub struct BranchSpan {
287288
pub span: Span,
288-
pub condition_info: ConditionInfo,
289289
pub true_marker: BlockMarkerId,
290290
pub false_marker: BlockMarkerId,
291291
}
@@ -308,6 +308,15 @@ impl Default for ConditionInfo {
308308
}
309309
}
310310

311+
#[derive(Clone, Debug)]
312+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
313+
pub struct MCDCBranchSpan {
314+
pub span: Span,
315+
pub condition_info: ConditionInfo,
316+
pub true_marker: BlockMarkerId,
317+
pub false_marker: BlockMarkerId,
318+
}
319+
311320
#[derive(Copy, Clone, Debug)]
312321
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
313322
pub struct DecisionInfo {
@@ -317,8 +326,8 @@ pub struct DecisionInfo {
317326

318327
#[derive(Clone, Debug)]
319328
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
320-
pub struct DecisionSpan {
329+
pub struct MCDCDecisionSpan {
321330
pub span: Span,
322331
pub conditions_num: usize,
323-
pub end_marker: Vec<BlockMarkerId>,
332+
pub end_markers: Vec<BlockMarkerId>,
324333
}

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -475,23 +475,35 @@ 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, .. } = branch_info;
478+
let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
479+
branch_info;
479480

480-
for coverage::BranchSpan { span, true_marker, false_marker, condition_info } in branch_spans {
481-
if condition_info.condition_id == coverage::ConditionId::NONE {
482-
writeln!(
483-
w,
484-
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
485-
)?;
486-
} else {
487-
let id = condition_info.condition_id;
488-
writeln!(
489-
w,
490-
"{INDENT}coverage branch {{ condition_id: {id:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
491-
)?;
492-
}
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+
)?;
493486
}
494-
if !branch_spans.is_empty() {
487+
488+
for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
489+
mcdc_branch_spans
490+
{
491+
writeln!(
492+
w,
493+
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
494+
condition_info.condition_id
495+
)?;
496+
}
497+
498+
for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in mcdc_decision_spans {
499+
writeln!(
500+
w,
501+
"{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}"
502+
)?;
503+
}
504+
505+
if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
506+
{
495507
writeln!(w)?;
496508
}
497509

compiler/rustc_mir_build/src/build/coverageinfo.rs

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use std::collections::VecDeque;
44

55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_middle::mir::coverage::{
7-
BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, DecisionSpan,
7+
BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
8+
MCDCDecisionSpan,
89
};
910
use rustc_middle::mir::{self, BasicBlock, UnOp};
1011
use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir};
@@ -21,7 +22,8 @@ pub(crate) struct BranchInfoBuilder {
2122

2223
num_block_markers: usize,
2324
branch_spans: Vec<BranchSpan>,
24-
decision_spans: Vec<DecisionSpan>,
25+
mcdc_branch_spans: Vec<MCDCBranchSpan>,
26+
mcdc_decision_spans: Vec<MCDCDecisionSpan>,
2527
mcdc_state: Option<MCDCState>,
2628
}
2729

@@ -44,7 +46,8 @@ impl BranchInfoBuilder {
4446
nots: FxHashMap::default(),
4547
num_block_markers: 0,
4648
branch_spans: vec![],
47-
decision_spans: vec![],
49+
mcdc_branch_spans: vec![],
50+
mcdc_decision_spans: vec![],
4851
mcdc_state: MCDCState::new_if_enabled(tcx),
4952
})
5053
} else {
@@ -103,10 +106,8 @@ impl BranchInfoBuilder {
103106
tcx: TyCtxt<'_>,
104107
true_marker: BlockMarkerId,
105108
false_marker: BlockMarkerId,
106-
) -> ConditionInfo {
107-
let Some(mcdc_state) = self.mcdc_state.as_mut() else {
108-
return ConditionInfo::default();
109-
};
109+
) -> Option<ConditionInfo> {
110+
let mcdc_state = self.mcdc_state.as_mut()?;
110111
let (mut condition_info, decision_result) =
111112
mcdc_state.take_condition(true_marker, false_marker);
112113
if let Some(decision) = decision_result {
@@ -115,17 +116,22 @@ impl BranchInfoBuilder {
115116
unreachable!("Decision with no condition is not expected");
116117
}
117118
1..=MAX_CONDITIONS_NUM_IN_DECISION => {
118-
self.decision_spans.push(decision);
119+
self.mcdc_decision_spans.push(decision);
119120
}
120121
_ => {
121122
// Do not generate mcdc mappings and statements for decisions with too many conditions.
122-
for branch in
123-
self.branch_spans.iter_mut().rev().take(decision.conditions_num - 1)
124-
{
125-
branch.condition_info = ConditionInfo::default();
126-
}
123+
let rebase_idx = self.mcdc_branch_spans.len() - decision.conditions_num + 1;
124+
let to_normal_branches = self.mcdc_branch_spans.split_off(rebase_idx);
125+
self.branch_spans.extend(to_normal_branches.into_iter().map(
126+
|MCDCBranchSpan { span, true_marker, false_marker, .. }| BranchSpan {
127+
span,
128+
true_marker,
129+
false_marker,
130+
},
131+
));
132+
127133
// ConditionInfo of this branch shall also be reset.
128-
condition_info = ConditionInfo::default();
134+
condition_info = None;
129135

130136
tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit {
131137
span: decision.span,
@@ -145,7 +151,14 @@ impl BranchInfoBuilder {
145151
}
146152

147153
pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
148-
let Self { nots: _, num_block_markers, branch_spans, decision_spans, .. } = self;
154+
let Self {
155+
nots: _,
156+
num_block_markers,
157+
branch_spans,
158+
mcdc_branch_spans,
159+
mcdc_decision_spans,
160+
..
161+
} = self;
149162

150163
if num_block_markers == 0 {
151164
assert!(branch_spans.is_empty());
@@ -155,7 +168,8 @@ impl BranchInfoBuilder {
155168
Some(Box::new(mir::coverage::BranchInfo {
156169
num_block_markers,
157170
branch_spans,
158-
decision_spans,
171+
mcdc_branch_spans,
172+
mcdc_decision_spans,
159173
}))
160174
}
161175
}
@@ -168,7 +182,7 @@ const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
168182
struct MCDCState {
169183
/// To construct condition evaluation tree.
170184
decision_stack: VecDeque<ConditionInfo>,
171-
processing_decision: Option<DecisionSpan>,
185+
processing_decision: Option<MCDCDecisionSpan>,
172186
}
173187

174188
impl MCDCState {
@@ -224,10 +238,10 @@ impl MCDCState {
224238
decision.span = decision.span.to(span);
225239
decision
226240
}
227-
None => self.processing_decision.insert(DecisionSpan {
241+
None => self.processing_decision.insert(MCDCDecisionSpan {
228242
span,
229243
conditions_num: 0,
230-
end_marker: vec![],
244+
end_markers: vec![],
231245
}),
232246
};
233247

@@ -279,24 +293,24 @@ impl MCDCState {
279293
&mut self,
280294
true_marker: BlockMarkerId,
281295
false_marker: BlockMarkerId,
282-
) -> (ConditionInfo, Option<DecisionSpan>) {
296+
) -> (Option<ConditionInfo>, Option<MCDCDecisionSpan>) {
283297
let Some(condition_info) = self.decision_stack.pop_back() else {
284-
return (ConditionInfo::default(), None);
298+
return (None, None);
285299
};
286300
let Some(decision) = self.processing_decision.as_mut() else {
287301
bug!("Processing decision should have been created before any conditions are taken");
288302
};
289303
if condition_info.true_next_id == ConditionId::NONE {
290-
decision.end_marker.push(true_marker);
304+
decision.end_markers.push(true_marker);
291305
}
292306
if condition_info.false_next_id == ConditionId::NONE {
293-
decision.end_marker.push(false_marker);
307+
decision.end_markers.push(false_marker);
294308
}
295309

296310
if self.decision_stack.is_empty() {
297-
(condition_info, self.processing_decision.take())
311+
(Some(condition_info), self.processing_decision.take())
298312
} else {
299-
(condition_info, None)
313+
(Some(condition_info), None)
300314
}
301315
}
302316
}
@@ -341,14 +355,22 @@ impl Builder<'_, '_> {
341355
let true_marker = inject_branch_marker(then_block);
342356
let false_marker = inject_branch_marker(else_block);
343357

344-
let condition_info = branch_info.fetch_condition_info(self.tcx, true_marker, false_marker);
345-
346-
branch_info.branch_spans.push(BranchSpan {
347-
span: source_info.span,
348-
condition_info,
349-
true_marker,
350-
false_marker,
351-
});
358+
if let Some(condition_info) =
359+
branch_info.fetch_condition_info(self.tcx, true_marker, false_marker)
360+
{
361+
branch_info.mcdc_branch_spans.push(MCDCBranchSpan {
362+
span: source_info.span,
363+
condition_info,
364+
true_marker,
365+
false_marker,
366+
});
367+
} else {
368+
branch_info.branch_spans.push(BranchSpan {
369+
span: source_info.span,
370+
true_marker,
371+
false_marker,
372+
});
373+
}
352374
}
353375

354376
pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {

0 commit comments

Comments
 (0)