Skip to content

Commit d4f1f92

Browse files
committed
coverage: Restrict ExpressionUsed simplification to Code mappings
In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node. We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.
1 parent 741ed01 commit d4f1f92

File tree

4 files changed

+27
-19
lines changed

4 files changed

+27
-19
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,15 @@ impl<'tcx> FunctionCoverageCollector<'tcx> {
6666
// For each expression ID that is directly used by one or more mappings,
6767
// mark it as not-yet-seen. This indicates that we expect to see a
6868
// corresponding `ExpressionUsed` statement during MIR traversal.
69-
for term in function_coverage_info.mappings.iter().flat_map(|m| m.kind.terms()) {
70-
if let CovTerm::Expression(id) = term {
69+
for mapping in function_coverage_info.mappings.iter() {
70+
// Currently we only worry about ordinary code mappings.
71+
// For branch and MC/DC mappings, expressions might not correspond
72+
// to any particular point in the control-flow graph.
73+
// (Keep this in sync with the injection of `ExpressionUsed`
74+
// statements in the `InstrumentCoverage` MIR pass.)
75+
if let MappingKind::Code(term) = mapping.kind
76+
&& let CovTerm::Expression(id) = term
77+
{
7178
expressions_seen.remove(id);
7279
}
7380
}

compiler/rustc_middle/src/mir/coverage.rs

-13
Original file line numberDiff line numberDiff line change
@@ -220,19 +220,6 @@ pub enum MappingKind {
220220
}
221221

222222
impl MappingKind {
223-
/// Iterator over all coverage terms in this mapping kind.
224-
pub fn terms(&self) -> impl Iterator<Item = CovTerm> {
225-
let zero = || None.into_iter().chain(None);
226-
let one = |a| Some(a).into_iter().chain(None);
227-
let two = |a, b| Some(a).into_iter().chain(Some(b));
228-
match *self {
229-
Self::Code(term) => one(term),
230-
Self::Branch { true_term, false_term } => two(true_term, false_term),
231-
Self::MCDCBranch { true_term, false_term, .. } => two(true_term, false_term),
232-
Self::MCDCDecision(_) => zero(),
233-
}
234-
}
235-
236223
/// Returns a copy of this mapping kind, in which all coverage terms have
237224
/// been replaced with ones returned by the given function.
238225
pub fn map_terms(&self, map_fn: impl Fn(CovTerm) -> CovTerm) -> Self {

compiler/rustc_mir_transform/src/coverage/mappings.rs

+9
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ impl ExtractedMappings {
159159

160160
bcbs_with_counter_mappings
161161
}
162+
163+
/// Returns the set of BCBs that have one or more `Code` mappings.
164+
pub(super) fn bcbs_with_ordinary_code_mappings(&self) -> BitSet<BasicCoverageBlock> {
165+
let mut bcbs = BitSet::new_empty(self.num_bcbs);
166+
for &CodeMapping { span: _, bcb } in &self.code_mappings {
167+
bcbs.insert(bcb);
168+
}
169+
bcbs
170+
}
162171
}
163172

164173
fn resolve_block_markers(

compiler/rustc_mir_transform/src/coverage/mod.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_span::source_map::SourceMap;
2525
use rustc_span::{BytePos, Pos, RelativeBytePos, Span, Symbol};
2626

2727
use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
28-
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
28+
use crate::coverage::graph::CoverageGraph;
2929
use crate::coverage::mappings::ExtractedMappings;
3030
use crate::MirPass;
3131

@@ -108,7 +108,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
108108
inject_coverage_statements(
109109
mir_body,
110110
&basic_coverage_blocks,
111-
bcb_has_counter_mappings,
111+
&extracted_mappings,
112112
&coverage_counters,
113113
);
114114

@@ -219,7 +219,7 @@ fn create_mappings<'tcx>(
219219
fn inject_coverage_statements<'tcx>(
220220
mir_body: &mut mir::Body<'tcx>,
221221
basic_coverage_blocks: &CoverageGraph,
222-
bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
222+
extracted_mappings: &ExtractedMappings,
223223
coverage_counters: &CoverageCounters,
224224
) {
225225
// Inject counter-increment statements into MIR.
@@ -252,11 +252,16 @@ fn inject_coverage_statements<'tcx>(
252252
// can check whether the injected statement survived MIR optimization.
253253
// (BCB edges can't have spans, so we only need to process BCB nodes here.)
254254
//
255+
// We only do this for ordinary `Code` mappings, because branch and MC/DC
256+
// mappings might have expressions that don't correspond to any single
257+
// point in the control-flow graph.
258+
//
255259
// See the code in `rustc_codegen_llvm::coverageinfo::map_data` that deals
256260
// with "expressions seen" and "zero terms".
261+
let eligible_bcbs = extracted_mappings.bcbs_with_ordinary_code_mappings();
257262
for (bcb, expression_id) in coverage_counters
258263
.bcb_nodes_with_coverage_expressions()
259-
.filter(|&(bcb, _)| bcb_has_coverage_spans(bcb))
264+
.filter(|&(bcb, _)| eligible_bcbs.contains(bcb))
260265
{
261266
inject_statement(
262267
mir_body,

0 commit comments

Comments
 (0)