Skip to content

Commit 05a3c66

Browse files
author
zhuyunxing
committed
coverage. Group MCDC decisions and conditions until instrument mappings
1 parent 2437c67 commit 05a3c66

File tree

21 files changed

+495
-486
lines changed

21 files changed

+495
-486
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,9 +1698,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16981698
&mut self,
16991699
fn_name: &'ll Value,
17001700
hash: &'ll Value,
1701-
bitmap_bytes: &'ll Value,
1701+
bitmap_bits: &'ll Value,
17021702
) {
1703-
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
1703+
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bits);
17041704

17051705
assert!(
17061706
crate::llvm_util::get_version() >= (19, 0, 0),
@@ -1712,7 +1712,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17121712
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
17131713
self.cx.type_void(),
17141714
);
1715-
let args = &[fn_name, hash, bitmap_bytes];
1715+
let args = &[fn_name, hash, bitmap_bits];
17161716
let args = self.check_call("call", llty, llfn, args);
17171717

17181718
unsafe {
@@ -1732,13 +1732,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17321732
&mut self,
17331733
fn_name: &'ll Value,
17341734
hash: &'ll Value,
1735-
bitmap_bytes: &'ll Value,
17361735
bitmap_index: &'ll Value,
17371736
mcdc_temp: &'ll Value,
17381737
) {
17391738
debug!(
1740-
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1741-
fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp
1739+
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?})",
1740+
fn_name, hash, bitmap_index, mcdc_temp
17421741
);
17431742
assert!(
17441743
crate::llvm_util::get_version() >= (19, 0, 0),
@@ -1748,16 +1747,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17481747
let llfn =
17491748
unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
17501749
let llty = self.cx.type_func(
1751-
&[
1752-
self.cx.type_ptr(),
1753-
self.cx.type_i64(),
1754-
self.cx.type_i32(),
1755-
self.cx.type_i32(),
1756-
self.cx.type_ptr(),
1757-
],
1750+
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_ptr()],
17581751
self.cx.type_void(),
17591752
);
1760-
let args = &[fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp];
1753+
let args = &[fn_name, hash, bitmap_index, mcdc_temp];
17611754
let args = self.check_call("call", llty, llfn, args);
17621755
unsafe {
17631756
let _ = llvm::LLVMRustBuildCall(
@@ -1773,45 +1766,15 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17731766
self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi);
17741767
}
17751768

1776-
pub(crate) fn mcdc_condbitmap_update(
1777-
&mut self,
1778-
fn_name: &'ll Value,
1779-
hash: &'ll Value,
1780-
cond_loc: &'ll Value,
1781-
mcdc_temp: &'ll Value,
1782-
bool_value: &'ll Value,
1783-
) {
1784-
debug!(
1785-
"mcdc_condbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1786-
fn_name, hash, cond_loc, mcdc_temp, bool_value
1787-
);
1769+
pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
1770+
debug!("mcdc_condbitmap_update() with args ({:?}, {:?})", cond_index, mcdc_temp);
17881771
assert!(
17891772
crate::llvm_util::get_version() >= (19, 0, 0),
17901773
"MCDC intrinsics require LLVM 19 or later"
17911774
);
1792-
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(self.cx().llmod) };
1793-
let llty = self.cx.type_func(
1794-
&[
1795-
self.cx.type_ptr(),
1796-
self.cx.type_i64(),
1797-
self.cx.type_i32(),
1798-
self.cx.type_ptr(),
1799-
self.cx.type_i1(),
1800-
],
1801-
self.cx.type_void(),
1802-
);
1803-
let args = &[fn_name, hash, cond_loc, mcdc_temp, bool_value];
1804-
self.check_call("call", llty, llfn, args);
1805-
unsafe {
1806-
let _ = llvm::LLVMRustBuildCall(
1807-
self.llbuilder,
1808-
llty,
1809-
llfn,
1810-
args.as_ptr() as *const &llvm::Value,
1811-
args.len() as c_uint,
1812-
[].as_ptr(),
1813-
0 as c_uint,
1814-
);
1815-
}
1775+
let align = self.tcx.data_layout.i32_align.abi;
1776+
let current_tv_index = self.load(self.cx.type_i32(), mcdc_temp, align);
1777+
let new_tv_index = self.add(current_tv_index, cond_index);
1778+
self.store(new_tv_index, mcdc_temp, align);
18161779
}
18171780
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
9898
};
9999

100100
// If there are no MC/DC bitmaps to set up, return immediately.
101-
if function_coverage_info.mcdc_bitmap_bytes == 0 {
101+
if function_coverage_info.mcdc_bitmap_bits == 0 {
102102
return;
103103
}
104104

105105
let fn_name = self.get_pgo_func_name_var(instance);
106106
let hash = self.const_u64(function_coverage_info.function_source_hash);
107-
let bitmap_bytes = self.const_u32(function_coverage_info.mcdc_bitmap_bytes);
108-
self.mcdc_parameters(fn_name, hash, bitmap_bytes);
107+
let bitmap_bits = self.const_u32(function_coverage_info.mcdc_bitmap_bits as u32);
108+
self.mcdc_parameters(fn_name, hash, bitmap_bits);
109109

110110
// Create pointers named `mcdc.addr.{i}` to stack-allocated condition bitmaps.
111111
let mut cond_bitmaps = vec![];
@@ -185,35 +185,28 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
185185
CoverageKind::ExpressionUsed { id } => {
186186
func_coverage.mark_expression_id_seen(id);
187187
}
188-
CoverageKind::CondBitmapUpdate { id, value, decision_depth } => {
188+
CoverageKind::CondBitmapUpdate { index, decision_depth } => {
189189
drop(coverage_map);
190-
assert_ne!(
191-
id.as_u32(),
192-
0,
193-
"ConditionId of evaluated conditions should never be zero"
194-
);
195190
let cond_bitmap = coverage_context
196191
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
197192
.expect("mcdc cond bitmap should have been allocated for updating");
198-
let cond_loc = bx.const_i32(id.as_u32() as i32 - 1);
199-
let bool_value = bx.const_bool(value);
200-
let fn_name = bx.get_pgo_func_name_var(instance);
201-
let hash = bx.const_u64(function_coverage_info.function_source_hash);
202-
bx.mcdc_condbitmap_update(fn_name, hash, cond_loc, cond_bitmap, bool_value);
193+
let cond_index = bx.const_i32(index as i32);
194+
bx.mcdc_condbitmap_update(cond_index, cond_bitmap);
203195
}
204196
CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
205197
drop(coverage_map);
206198
let cond_bitmap = coverage_context
207199
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
208200
.expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
209-
let bitmap_bytes = function_coverage_info.mcdc_bitmap_bytes;
210-
assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range");
201+
assert!(
202+
bitmap_idx as usize <= function_coverage_info.mcdc_bitmap_bits,
203+
"bitmap index of the decision out of range"
204+
);
211205

212206
let fn_name = bx.get_pgo_func_name_var(instance);
213207
let hash = bx.const_u64(function_coverage_info.function_source_hash);
214-
let bitmap_bytes = bx.const_u32(bitmap_bytes);
215208
let bitmap_index = bx.const_u32(bitmap_idx);
216-
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_bytes, bitmap_index, cond_bitmap);
209+
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);
217210
}
218211
}
219212
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,6 @@ unsafe extern "C" {
16131613
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
16141614
pub fn LLVMRustGetInstrProfMCDCParametersIntrinsic(M: &Module) -> &Value;
16151615
pub fn LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(M: &Module) -> &Value;
1616-
pub fn LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(M: &Module) -> &Value;
16171616

16181617
pub fn LLVMRustBuildCall<'a>(
16191618
B: &Builder<'a>,

compiler/rustc_middle/src/mir/coverage.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ pub enum CoverageKind {
128128

129129
/// Marks the point in MIR control flow represented by a evaluated condition.
130130
///
131-
/// This is eventually lowered to `llvm.instrprof.mcdc.condbitmap.update` in LLVM IR.
132-
CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 },
131+
/// This is eventually lowered to instruments updating mcdc temp variables.
132+
CondBitmapUpdate { index: u32, decision_depth: u16 },
133133

134134
/// Marks the point in MIR control flow represented by a evaluated decision.
135135
///
@@ -145,14 +145,8 @@ impl Debug for CoverageKind {
145145
BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()),
146146
CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()),
147147
ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()),
148-
CondBitmapUpdate { id, value, decision_depth } => {
149-
write!(
150-
fmt,
151-
"CondBitmapUpdate({:?}, {:?}, depth={:?})",
152-
id.index(),
153-
value,
154-
decision_depth
155-
)
148+
CondBitmapUpdate { index, decision_depth } => {
149+
write!(fmt, "CondBitmapUpdate(index={:?}, depth={:?})", index, decision_depth)
156150
}
157151
TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
158152
write!(fmt, "TestVectorUpdate({:?}, depth={:?})", bitmap_idx, decision_depth)
@@ -253,7 +247,7 @@ pub struct Mapping {
253247
pub struct FunctionCoverageInfo {
254248
pub function_source_hash: u64,
255249
pub num_counters: usize,
256-
pub mcdc_bitmap_bytes: u32,
250+
pub mcdc_bitmap_bits: usize,
257251
pub expressions: IndexVec<ExpressionId, Expression>,
258252
pub mappings: Vec<Mapping>,
259253
/// The depth of the deepest decision is used to know how many
@@ -275,8 +269,10 @@ pub struct CoverageInfoHi {
275269
/// data structures without having to scan the entire body first.
276270
pub num_block_markers: usize,
277271
pub branch_spans: Vec<BranchSpan>,
278-
pub mcdc_branch_spans: Vec<MCDCBranchSpan>,
279-
pub mcdc_decision_spans: Vec<MCDCDecisionSpan>,
272+
/// Branch spans generated by mcdc. Because of some limits mcdc builder give up generating
273+
/// decisions including them so that they are handled as normal branch spans.
274+
pub mcdc_degraded_branch_spans: Vec<MCDCBranchSpan>,
275+
pub mcdc_spans: Vec<(MCDCDecisionSpan, Vec<MCDCBranchSpan>)>,
280276
}
281277

282278
#[derive(Clone, Debug)]
@@ -299,12 +295,9 @@ pub struct ConditionInfo {
299295
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
300296
pub struct MCDCBranchSpan {
301297
pub span: Span,
302-
/// If `None`, this actually represents a normal branch span inserted for
303-
/// code that was too complex for MC/DC.
304-
pub condition_info: Option<ConditionInfo>,
298+
pub condition_info: ConditionInfo,
305299
pub true_marker: BlockMarkerId,
306300
pub false_marker: BlockMarkerId,
307-
pub decision_depth: u16,
308301
}
309302

310303
#[derive(Copy, Clone, Debug)]
@@ -318,7 +311,7 @@ pub struct DecisionInfo {
318311
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
319312
pub struct MCDCDecisionSpan {
320313
pub span: Span,
321-
pub num_conditions: usize,
322314
pub end_markers: Vec<BlockMarkerId>,
323315
pub decision_depth: u16,
316+
pub num_conditions: usize,
324317
}

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ fn write_coverage_info_hi(
538538
let coverage::CoverageInfoHi {
539539
num_block_markers: _,
540540
branch_spans,
541-
mcdc_branch_spans,
542-
mcdc_decision_spans,
541+
mcdc_degraded_branch_spans,
542+
mcdc_spans,
543543
} = coverage_info_hi;
544544

545545
// Only add an extra trailing newline if we printed at least one thing.
@@ -553,29 +553,35 @@ fn write_coverage_info_hi(
553553
did_print = true;
554554
}
555555

556-
for coverage::MCDCBranchSpan {
557-
span,
558-
condition_info,
559-
true_marker,
560-
false_marker,
561-
decision_depth,
562-
} in mcdc_branch_spans
556+
for coverage::MCDCBranchSpan { span, true_marker, false_marker, .. } in
557+
mcdc_degraded_branch_spans
563558
{
564559
writeln!(
565560
w,
566-
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
567-
condition_info.map(|info| info.condition_id)
561+
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
568562
)?;
569563
did_print = true;
570564
}
571565

572-
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
573-
mcdc_decision_spans
566+
for (
567+
coverage::MCDCDecisionSpan { span, end_markers, decision_depth, num_conditions: _ },
568+
conditions,
569+
) in mcdc_spans
574570
{
571+
let num_conditions = conditions.len();
575572
writeln!(
576573
w,
577574
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
578575
)?;
576+
for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
577+
conditions
578+
{
579+
writeln!(
580+
w,
581+
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
582+
condition_info.condition_id
583+
)?;
584+
}
579585
did_print = true;
580586
}
581587

compiler/rustc_mir_build/src/build/coverageinfo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,16 @@ impl CoverageInfoBuilder {
175175
let branch_spans =
176176
branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default();
177177

178-
let (mcdc_decision_spans, mcdc_branch_spans) =
178+
let (mcdc_spans, mcdc_degraded_branch_spans) =
179179
mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
180180

181181
// For simplicity, always return an info struct (without Option), even
182182
// if there's nothing interesting in it.
183183
Box::new(CoverageInfoHi {
184184
num_block_markers,
185185
branch_spans,
186-
mcdc_branch_spans,
187-
mcdc_decision_spans,
186+
mcdc_degraded_branch_spans,
187+
mcdc_spans,
188188
})
189189
}
190190
}

0 commit comments

Comments
 (0)