Skip to content

Commit bb03d42

Browse files
committed
coverage: Record branch info during MIR building
1 parent e000aa2 commit bb03d42

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

compiler/rustc_mir_build/src/build/coverageinfo.rs

+45-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use rustc_middle::hir;
22
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
3-
use rustc_middle::mir;
4-
use rustc_middle::mir::coverage::BranchSpan;
3+
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
4+
use rustc_middle::mir::{self, BasicBlock, SourceInfo, Statement, StatementKind};
55
use rustc_middle::ty::TyCtxt;
66
use rustc_span::def_id::LocalDefId;
77
use rustc_span::{ExpnKind, Span};
88

9+
use crate::build::Builder;
10+
911
pub(crate) struct HirInfoBuilder {
1012
pub(crate) branch_coverage_enabled: bool,
1113
pub(crate) num_block_markers: usize,
@@ -25,6 +27,12 @@ impl HirInfoBuilder {
2527
}
2628
}
2729

30+
fn next_block_marker_id(&mut self) -> BlockMarkerId {
31+
let id = BlockMarkerId::from_usize(self.num_block_markers);
32+
self.num_block_markers += 1;
33+
id
34+
}
35+
2836
pub(crate) fn finish(self, tcx: TyCtxt<'_>, def_id: LocalDefId) -> Box<mir::coverage::HirInfo> {
2937
Box::new(make_coverage_hir_info(tcx, def_id, self))
3038
}
@@ -138,3 +146,38 @@ fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx
138146
.to_smaller_hash()
139147
.as_u64()
140148
}
149+
150+
impl<'a, 'tcx> Builder<'a, 'tcx> {
151+
pub(crate) fn coverage_add_branch(
152+
&mut self,
153+
cond_source_info: SourceInfo,
154+
then_blk: BasicBlock,
155+
else_blk: BasicBlock,
156+
) {
157+
let hir_info_builder = self.coverage.as_mut().unwrap();
158+
assert!(hir_info_builder.branch_coverage_enabled);
159+
160+
let mut inject_branch_marker = |bb: BasicBlock| {
161+
let id = hir_info_builder.next_block_marker_id();
162+
163+
let statement = Statement {
164+
source_info: cond_source_info,
165+
kind: StatementKind::Coverage(Box::new(mir::Coverage {
166+
kind: CoverageKind::BlockMarker { id },
167+
})),
168+
};
169+
170+
self.cfg.push(bb, statement);
171+
id
172+
};
173+
174+
let true_marker = inject_branch_marker(then_blk);
175+
let false_marker = inject_branch_marker(else_blk);
176+
177+
hir_info_builder.branch_spans.push(BranchSpan {
178+
span: cond_source_info.span,
179+
true_marker,
180+
false_marker,
181+
});
182+
}
183+
}

compiler/rustc_mir_build/src/build/matches/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141141
let term = TerminatorKind::if_(operand, then_block, else_block);
142142

143143
let source_info = this.source_info(expr_span);
144+
145+
if let Some(coverage) = &this.coverage
146+
&& coverage.branch_coverage_enabled
147+
{
148+
this.coverage_add_branch(source_info, then_block, else_block);
149+
}
150+
144151
this.cfg.terminate(block, source_info, term);
145152
this.break_for_else(else_block, break_scope, source_info);
146153

0 commit comments

Comments
 (0)