Skip to content

Commit 4883951

Browse files
committed
Auto merge of rust-lang#124856 - matthiaskrgr:rollup-xqxs21x, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - rust-lang#124223 (coverage: Branch coverage support for let-else and if-let) - rust-lang#124571 (coverage: Clean up `mcdc_bitmap_bytes` and `conditions_num`) - rust-lang#124838 (next_power_of_two: add a doctest to show what happens on 0) r? `@ghost` `@rustbot` modify labels: rollup
2 parents faefc61 + ec9020d commit 4883951

File tree

23 files changed

+391
-74
lines changed

23 files changed

+391
-74
lines changed

Diff for: compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub mod mcdc {
118118
#[derive(Clone, Copy, Debug, Default)]
119119
pub struct DecisionParameters {
120120
bitmap_idx: u32,
121-
conditions_num: u16,
121+
num_conditions: u16,
122122
}
123123

124124
// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
@@ -178,7 +178,7 @@ pub mod mcdc {
178178

179179
impl From<DecisionInfo> for DecisionParameters {
180180
fn from(value: DecisionInfo) -> Self {
181-
Self { bitmap_idx: value.bitmap_idx, conditions_num: value.conditions_num }
181+
Self { bitmap_idx: value.bitmap_idx, num_conditions: value.num_conditions }
182182
}
183183
}
184184
}

Diff for: compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
207207
let cond_bitmap = coverage_context
208208
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
209209
.expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
210-
let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes;
210+
let bitmap_bytes = function_coverage_info.mcdc_bitmap_bytes;
211211
assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range");
212-
assert!(
213-
bitmap_bytes <= function_coverage_info.mcdc_bitmap_bytes,
214-
"bitmap length disagreement: query says {bitmap_bytes} but function info only has {}",
215-
function_coverage_info.mcdc_bitmap_bytes
216-
);
217212

218213
let fn_name = bx.get_pgo_func_name_var(instance);
219214
let hash = bx.const_u64(function_coverage_info.function_source_hash);

Diff for: compiler/rustc_middle/src/mir/coverage.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,11 @@ pub enum CoverageKind {
129129
/// Marks the point in MIR control flow represented by a evaluated condition.
130130
///
131131
/// This is eventually lowered to `llvm.instrprof.mcdc.condbitmap.update` in LLVM IR.
132-
///
133-
/// If this statement does not survive MIR optimizations, the condition would never be
134-
/// taken as evaluated.
135132
CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 },
136133

137134
/// Marks the point in MIR control flow represented by a evaluated decision.
138135
///
139136
/// This is eventually lowered to `llvm.instrprof.mcdc.tvbitmap.update` in LLVM IR.
140-
///
141-
/// If this statement does not survive MIR optimizations, the decision would never be
142-
/// taken as evaluated.
143137
TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 },
144138
}
145139

@@ -335,14 +329,14 @@ pub struct MCDCBranchSpan {
335329
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
336330
pub struct DecisionInfo {
337331
pub bitmap_idx: u32,
338-
pub conditions_num: u16,
332+
pub num_conditions: u16,
339333
}
340334

341335
#[derive(Clone, Debug)]
342336
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
343337
pub struct MCDCDecisionSpan {
344338
pub span: Span,
345-
pub conditions_num: usize,
339+
pub num_conditions: usize,
346340
pub end_markers: Vec<BlockMarkerId>,
347341
pub decision_depth: u16,
348342
}

Diff for: compiler/rustc_middle/src/mir/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,12 @@ fn write_coverage_branch_info(
511511
)?;
512512
}
513513

514-
for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in
514+
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
515515
mcdc_decision_spans
516516
{
517517
writeln!(
518518
w,
519-
"{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
519+
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
520520
)?;
521521
}
522522

Diff for: compiler/rustc_middle/src/mir/query.rs

-4
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,4 @@ pub struct CoverageIdsInfo {
362362
/// InstrumentCoverage MIR pass, if the highest-numbered counter increments
363363
/// were removed by MIR optimizations.
364364
pub max_counter_id: mir::coverage::CounterId,
365-
366-
/// Coverage codegen for mcdc needs to know the size of the global bitmap so that it can
367-
/// set the `bytemap-bytes` argument of the `llvm.instrprof.mcdc.tvbitmap.update` intrinsic.
368-
pub mcdc_bitmap_bytes: u32,
369365
}

Diff for: compiler/rustc_mir_build/messages.ftl

+3-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
9797
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
9898
.label = dereference of raw pointer
9999
100-
mir_build_exceeds_mcdc_condition_num_limit = Conditions number of the decision ({$conditions_num}) exceeds limit ({$max_conditions_num}). MCDC analysis will not count this expression.
100+
mir_build_exceeds_mcdc_condition_limit =
101+
number of conditions in decision ({$num_conditions}) exceeds limit ({$limit})
102+
.note = this decision will not be instrumented for MC/DC coverage
101103
102104
mir_build_extern_static_requires_unsafe =
103105
use of extern static is unsafe and requires unsafe block

Diff for: compiler/rustc_mir_build/src/build/coverageinfo.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
mod mcdc;
21
use std::assert_matches::assert_matches;
32
use std::collections::hash_map::Entry;
43

54
use rustc_data_structures::fx::FxHashMap;
65
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
76
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
8-
use rustc_middle::thir::{ExprId, ExprKind, Thir};
7+
use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
98
use rustc_middle::ty::TyCtxt;
109
use rustc_span::def_id::LocalDefId;
1110

1211
use crate::build::coverageinfo::mcdc::MCDCInfoBuilder;
1312
use crate::build::{Builder, CFG};
1413

14+
mod mcdc;
15+
1516
pub(crate) struct BranchInfoBuilder {
1617
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
1718
nots: FxHashMap<ExprId, NotInfo>,
@@ -155,7 +156,7 @@ impl BranchInfoBuilder {
155156
}
156157
}
157158

158-
impl Builder<'_, '_> {
159+
impl<'tcx> Builder<'_, 'tcx> {
159160
/// If branch coverage is enabled, inject marker statements into `then_block`
160161
/// and `else_block`, and record their IDs in the table of branch spans.
161162
pub(crate) fn visit_coverage_branch_condition(
@@ -195,4 +196,23 @@ impl Builder<'_, '_> {
195196

196197
branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
197198
}
199+
200+
/// If branch coverage is enabled, inject marker statements into `true_block`
201+
/// and `false_block`, and record their IDs in the table of branches.
202+
///
203+
/// Used to instrument let-else and if-let (including let-chains) for branch coverage.
204+
pub(crate) fn visit_coverage_conditional_let(
205+
&mut self,
206+
pattern: &Pat<'tcx>, // Pattern that has been matched when the true path is taken
207+
true_block: BasicBlock,
208+
false_block: BasicBlock,
209+
) {
210+
// Bail out if branch coverage is not enabled for this function.
211+
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
212+
213+
// FIXME(#124144) This may need special handling when MC/DC is enabled.
214+
215+
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
216+
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
217+
}
198218
}

Diff for: compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ use rustc_middle::ty::TyCtxt;
99
use rustc_span::Span;
1010

1111
use crate::build::Builder;
12-
use crate::errors::MCDCExceedsConditionNumLimit;
12+
use crate::errors::MCDCExceedsConditionLimit;
1313

1414
/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen,
15-
/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge.
16-
/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged.
17-
const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
15+
/// So LLVM imposes a limit to prevent the bitmap footprint from growing too large without the user's knowledge.
16+
/// This limit may be relaxed if [upstream change #82448](https://github.com/llvm/llvm-project/pull/82448) is merged.
17+
const MAX_CONDITIONS_IN_DECISION: usize = 6;
1818

1919
#[derive(Default)]
2020
struct MCDCDecisionCtx {
@@ -99,22 +99,22 @@ impl MCDCState {
9999
}
100100
None => decision_ctx.processing_decision.insert(MCDCDecisionSpan {
101101
span,
102-
conditions_num: 0,
102+
num_conditions: 0,
103103
end_markers: vec![],
104104
decision_depth,
105105
}),
106106
};
107107

108108
let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default();
109109
let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
110-
decision.conditions_num += 1;
111-
ConditionId::from(decision.conditions_num)
110+
decision.num_conditions += 1;
111+
ConditionId::from(decision.num_conditions)
112112
} else {
113113
parent_condition.condition_id
114114
};
115115

116-
decision.conditions_num += 1;
117-
let rhs_condition_id = ConditionId::from(decision.conditions_num);
116+
decision.num_conditions += 1;
117+
let rhs_condition_id = ConditionId::from(decision.num_conditions);
118118

119119
let (lhs, rhs) = match op {
120120
LogicalOp::And => {
@@ -207,27 +207,27 @@ impl MCDCInfoBuilder {
207207
// is empty, i.e. when all the conditions of the decision were instrumented,
208208
// and the decision is "complete".
209209
if let Some(decision) = decision_result {
210-
match decision.conditions_num {
210+
match decision.num_conditions {
211211
0 => {
212212
unreachable!("Decision with no condition is not expected");
213213
}
214-
1..=MAX_CONDITIONS_NUM_IN_DECISION => {
214+
1..=MAX_CONDITIONS_IN_DECISION => {
215215
self.decision_spans.push(decision);
216216
}
217217
_ => {
218218
// Do not generate mcdc mappings and statements for decisions with too many conditions.
219-
let rebase_idx = self.branch_spans.len() - decision.conditions_num + 1;
219+
let rebase_idx = self.branch_spans.len() - decision.num_conditions + 1;
220220
for branch in &mut self.branch_spans[rebase_idx..] {
221221
branch.condition_info = None;
222222
}
223223

224224
// ConditionInfo of this branch shall also be reset.
225225
condition_info = None;
226226

227-
tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit {
227+
tcx.dcx().emit_warn(MCDCExceedsConditionLimit {
228228
span: decision.span,
229-
conditions_num: decision.conditions_num,
230-
max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION,
229+
num_conditions: decision.num_conditions,
230+
limit: MAX_CONDITIONS_IN_DECISION,
231231
});
232232
}
233233
}

Diff for: compiler/rustc_mir_build/src/build/matches/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20002000
false,
20012001
);
20022002

2003+
// If branch coverage is enabled, record this branch.
2004+
self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_post_guard_block);
2005+
20032006
post_guard_block.unit()
20042007
}
20052008

@@ -2492,6 +2495,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24922495
None,
24932496
true,
24942497
);
2498+
2499+
// If branch coverage is enabled, record this branch.
2500+
this.visit_coverage_conditional_let(pattern, matching, failure);
2501+
24952502
this.break_for_else(failure, this.source_info(initializer_span));
24962503
matching.unit()
24972504
});

Diff for: compiler/rustc_mir_build/src/errors.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -819,12 +819,13 @@ pub struct NontrivialStructuralMatch<'tcx> {
819819
}
820820

821821
#[derive(Diagnostic)]
822-
#[diag(mir_build_exceeds_mcdc_condition_num_limit)]
823-
pub(crate) struct MCDCExceedsConditionNumLimit {
822+
#[diag(mir_build_exceeds_mcdc_condition_limit)]
823+
#[note]
824+
pub(crate) struct MCDCExceedsConditionLimit {
824825
#[primary_span]
825826
pub span: Span,
826-
pub conditions_num: usize,
827-
pub max_conditions_num: usize,
827+
pub num_conditions: usize,
828+
pub limit: usize,
828829
}
829830

830831
#[derive(Diagnostic)]

Diff for: compiler/rustc_mir_transform/src/coverage/mappings.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub(super) struct MCDCDecision {
4848
pub(super) span: Span,
4949
pub(super) end_bcbs: BTreeSet<BasicCoverageBlock>,
5050
pub(super) bitmap_idx: u32,
51-
pub(super) conditions_num: u16,
51+
pub(super) num_conditions: u16,
5252
pub(super) decision_depth: u16,
5353
}
5454

@@ -136,8 +136,8 @@ pub(super) fn generate_coverage_spans(
136136
// Determine the length of the test vector bitmap.
137137
let test_vector_bitmap_bytes = mcdc_decisions
138138
.iter()
139-
.map(|&MCDCDecision { bitmap_idx, conditions_num, .. }| {
140-
bitmap_idx + (1_u32 << u32::from(conditions_num)).div_ceil(8)
139+
.map(|&MCDCDecision { bitmap_idx, num_conditions, .. }| {
140+
bitmap_idx + (1_u32 << u32::from(num_conditions)).div_ceil(8)
141141
})
142142
.max()
143143
.unwrap_or(0);
@@ -266,13 +266,13 @@ pub(super) fn extract_mcdc_mappings(
266266
.collect::<Option<_>>()?;
267267

268268
let bitmap_idx = next_bitmap_idx;
269-
next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
269+
next_bitmap_idx += (1_u32 << decision.num_conditions).div_ceil(8);
270270

271271
Some(MCDCDecision {
272272
span,
273273
end_bcbs,
274274
bitmap_idx,
275-
conditions_num: decision.conditions_num as u16,
275+
num_conditions: decision.num_conditions as u16,
276276
decision_depth: decision.decision_depth,
277277
})
278278
},

Diff for: compiler/rustc_mir_transform/src/coverage/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ fn create_mappings<'tcx>(
182182
));
183183

184184
mappings.extend(coverage_spans.mcdc_decisions.iter().filter_map(
185-
|&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
185+
|&mappings::MCDCDecision { span, bitmap_idx, num_conditions, .. }| {
186186
let code_region = region_for_span(span)?;
187-
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num });
187+
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, num_conditions });
188188
Some(Mapping { kind, code_region })
189189
},
190190
));
@@ -260,7 +260,7 @@ fn inject_mcdc_statements<'tcx>(
260260
span: _,
261261
ref end_bcbs,
262262
bitmap_idx,
263-
conditions_num: _,
263+
num_conditions: _,
264264
decision_depth,
265265
} in &coverage_spans.mcdc_decisions
266266
{

Diff for: compiler/rustc_mir_transform/src/coverage/query.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,7 @@ fn coverage_ids_info<'tcx>(
6161
.max()
6262
.unwrap_or(CounterId::ZERO);
6363

64-
let mcdc_bitmap_bytes = mir_body
65-
.coverage_branch_info
66-
.as_deref()
67-
.map(|info| {
68-
info.mcdc_decision_spans
69-
.iter()
70-
.fold(0, |acc, decision| acc + (1_u32 << decision.conditions_num).div_ceil(8))
71-
})
72-
.unwrap_or_default();
73-
74-
CoverageIdsInfo { max_counter_id, mcdc_bitmap_bytes }
64+
CoverageIdsInfo { max_counter_id }
7565
}
7666

7767
fn all_coverage_in_mir_body<'a, 'tcx>(

Diff for: library/core/src/num/uint_macros.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2764,6 +2764,7 @@ macro_rules! uint_impl {
27642764
/// ```
27652765
#[doc = concat!("assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);")]
27662766
#[doc = concat!("assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);")]
2767+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".next_power_of_two(), 1);")]
27672768
/// ```
27682769
#[stable(feature = "rust1", since = "1.0.0")]
27692770
#[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]

0 commit comments

Comments
 (0)