Skip to content

Commit c593218

Browse files
committed
coverage: Store extracted spans as a flat list of mappings
This is less elegant in some ways, since we no longer visit a BCB's spans as a batch, but will make it much easier to add support for other kinds of coverage mapping regions (e.g. branch regions or gap regions).
1 parent 8f98b54 commit c593218

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

compiler/rustc_mir_transform/src/coverage/mod.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod tests;
99

1010
use self::counters::{BcbCounter, CoverageCounters};
1111
use self::graph::{BasicCoverageBlock, CoverageGraph};
12-
use self::spans::CoverageSpans;
12+
use self::spans::{BcbMapping, CoverageSpans};
1313

1414
use crate::MirPass;
1515

@@ -149,16 +149,9 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
149149
};
150150

151151
coverage_spans
152-
.bcbs_with_coverage_spans()
153-
// For each BCB with spans, get a coverage term for its counter.
154-
.map(|(bcb, spans)| {
152+
.all_bcb_mappings()
153+
.filter_map(|&BcbMapping { bcb, span }| {
155154
let term = term_for_bcb(bcb);
156-
(term, spans)
157-
})
158-
// Flatten the spans into individual term/span pairs.
159-
.flat_map(|(term, spans)| spans.iter().map(move |&span| (term, span)))
160-
// Convert each span to a code region, and create the final mapping.
161-
.filter_map(|(term, span)| {
162155
let code_region = make_code_region(source_map, file_name, span, body_span)?;
163156
Some(Mapping { term, code_region })
164157
})

compiler/rustc_mir_transform/src/coverage/spans.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_data_structures::graph::WithNumNodes;
2-
use rustc_index::IndexVec;
2+
use rustc_index::bit_set::BitSet;
33
use rustc_middle::mir;
44
use rustc_span::{BytePos, Span, DUMMY_SP};
55

@@ -8,9 +8,15 @@ use crate::coverage::ExtractedHirInfo;
88

99
mod from_mir;
1010

11+
#[derive(Debug)]
12+
pub(super) struct BcbMapping {
13+
pub(super) bcb: BasicCoverageBlock,
14+
pub(super) span: Span,
15+
}
16+
1117
pub(super) struct CoverageSpans {
12-
/// Map from BCBs to their list of coverage spans.
13-
bcb_to_spans: IndexVec<BasicCoverageBlock, Vec<Span>>,
18+
bcb_has_mappings: BitSet<BasicCoverageBlock>,
19+
mappings: Vec<BcbMapping>,
1420
}
1521

1622
impl CoverageSpans {
@@ -23,36 +29,37 @@ impl CoverageSpans {
2329
hir_info: &ExtractedHirInfo,
2430
basic_coverage_blocks: &CoverageGraph,
2531
) -> Option<Self> {
32+
let mut mappings = vec![];
33+
2634
let coverage_spans = CoverageSpansGenerator::generate_coverage_spans(
2735
mir_body,
2836
hir_info,
2937
basic_coverage_blocks,
3038
);
39+
mappings.extend(coverage_spans.into_iter().map(|CoverageSpan { bcb, span, .. }| {
40+
// Each span produced by the generator represents an ordinary code region.
41+
BcbMapping { bcb, span }
42+
}));
3143

32-
if coverage_spans.is_empty() {
44+
if mappings.is_empty() {
3345
return None;
3446
}
3547

36-
// Group the coverage spans by BCB, with the BCBs in sorted order.
37-
let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes());
38-
for CoverageSpan { bcb, span, .. } in coverage_spans {
39-
bcb_to_spans[bcb].push(span);
48+
// Identify which BCBs have one or more mappings.
49+
let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
50+
for &BcbMapping { bcb, span: _ } in &mappings {
51+
bcb_has_mappings.insert(bcb);
4052
}
4153

42-
Some(Self { bcb_to_spans })
54+
Some(Self { bcb_has_mappings, mappings })
4355
}
4456

4557
pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {
46-
!self.bcb_to_spans[bcb].is_empty()
58+
self.bcb_has_mappings.contains(bcb)
4759
}
4860

49-
pub(super) fn bcbs_with_coverage_spans(
50-
&self,
51-
) -> impl Iterator<Item = (BasicCoverageBlock, &[Span])> {
52-
self.bcb_to_spans.iter_enumerated().filter_map(|(bcb, spans)| {
53-
// Only yield BCBs that have at least one coverage span.
54-
(!spans.is_empty()).then_some((bcb, spans.as_slice()))
55-
})
61+
pub(super) fn all_bcb_mappings(&self) -> impl Iterator<Item = &BcbMapping> {
62+
self.mappings.iter()
5663
}
5764
}
5865

0 commit comments

Comments
 (0)