Skip to content

Commit 8aa9f01

Browse files
committed
coverage: Clean up marker statements that aren't needed later
Some of the marker statements used by coverage are added during MIR building for use by the InstrumentCoverage pass (during analysis), and are not needed afterwards.
1 parent cdb683f commit 8aa9f01

File tree

6 files changed

+148
-13
lines changed

6 files changed

+148
-13
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
8585

8686
let bx = self;
8787

88-
match coverage.kind {
89-
// Marker statements have no effect during codegen,
90-
// so return early and don't create `func_coverage`.
91-
CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => return,
92-
// Match exhaustively to ensure that newly-added kinds are classified correctly.
93-
CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. } => {}
94-
}
95-
9688
let Some(function_coverage_info) =
9789
bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
9890
else {
@@ -109,7 +101,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
109101
let Coverage { kind } = coverage;
110102
match *kind {
111103
CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => unreachable!(
112-
"unexpected marker statement {kind:?} should have caused an early return"
104+
"marker statement {kind:?} should have been removed by CleanupPostBorrowck"
113105
),
114106
CoverageKind::CounterIncrement { id } => {
115107
func_coverage.mark_counter_id_seen(id);

compiler/rustc_middle/src/mir/coverage.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,13 @@ pub enum CoverageKind {
8888
/// Marks a span that might otherwise not be represented in MIR, so that
8989
/// coverage instrumentation can associate it with its enclosing block/BCB.
9090
///
91-
/// Only used by the `InstrumentCoverage` pass, and has no effect during
92-
/// codegen.
91+
/// Should be erased before codegen (at some point after `InstrumentCoverage`).
9392
SpanMarker,
9493

9594
/// Marks its enclosing basic block with an ID that can be referred to by
9695
/// side data in [`BranchInfo`].
9796
///
98-
/// Has no effect during codegen.
97+
/// Should be erased before codegen (at some point after `InstrumentCoverage`).
9998
BlockMarker { id: BlockMarkerId },
10099

101100
/// Marks the point in MIR control flow represented by a coverage counter.

compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
//! - [`AscribeUserType`]
66
//! - [`FakeRead`]
77
//! - [`Assign`] statements with a [`Fake`] borrow
8+
//! - [`Coverage`] statements of kind [`BlockMarker`] or [`SpanMarker`]
89
//!
910
//! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
1011
//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
1112
//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
1213
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
1314
//! [`Fake`]: rustc_middle::mir::BorrowKind::Fake
15+
//! [`Coverage`]: rustc_middle::mir::StatementKind::Coverage
16+
//! [`BlockMarker`]: rustc_middle::mir::coverage::CoverageKind::BlockMarker
17+
//! [`SpanMarker`]: rustc_middle::mir::coverage::CoverageKind::SpanMarker
1418
1519
use crate::MirPass;
16-
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
20+
use rustc_middle::mir::coverage::CoverageKind;
21+
use rustc_middle::mir::{Body, BorrowKind, Coverage, Rvalue, StatementKind, TerminatorKind};
1722
use rustc_middle::ty::TyCtxt;
1823

1924
pub struct CleanupPostBorrowck;
@@ -25,6 +30,12 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
2530
match statement.kind {
2631
StatementKind::AscribeUserType(..)
2732
| StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Fake, _)))
33+
| StatementKind::Coverage(box Coverage {
34+
// These kinds of coverage statements are markers inserted during
35+
// MIR building, and are not needed after InstrumentCoverage.
36+
kind: CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
37+
..
38+
})
2839
| StatementKind::FakeRead(..) => statement.make_nop(),
2940
_ => (),
3041
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
- // MIR for `main` before CleanupPostBorrowck
2+
+ // MIR for `main` after CleanupPostBorrowck
3+
4+
fn main() -> () {
5+
let mut _0: ();
6+
let mut _1: bool;
7+
8+
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => /the/src/instrument_coverage_cleanup.rs:17:8: 17:36 (#0)
9+
10+
coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
11+
coverage ExpressionId(1) => Expression { lhs: Counter(1), op: Add, rhs: Expression(0) };
12+
coverage Code(Counter(0)) => /the/src/instrument_coverage_cleanup.rs:16:1 - 17:36;
13+
coverage Code(Expression(0)) => /the/src/instrument_coverage_cleanup.rs:17:37 - 17:39;
14+
coverage Code(Counter(1)) => /the/src/instrument_coverage_cleanup.rs:17:39 - 17:40;
15+
coverage Code(Expression(1)) => /the/src/instrument_coverage_cleanup.rs:18:1 - 18:2;
16+
coverage Branch { true_term: Expression(0), false_term: Counter(1) } => /the/src/instrument_coverage_cleanup.rs:17:8 - 17:36;
17+
18+
bb0: {
19+
Coverage::CounterIncrement(0);
20+
- Coverage::SpanMarker;
21+
+ nop;
22+
StorageLive(_1);
23+
_1 = std::hint::black_box::<bool>(const true) -> [return: bb1, unwind: bb5];
24+
}
25+
26+
bb1: {
27+
switchInt(move _1) -> [0: bb3, otherwise: bb2];
28+
}
29+
30+
bb2: {
31+
Coverage::CounterIncrement(1);
32+
- Coverage::BlockMarker(1);
33+
+ nop;
34+
_0 = const ();
35+
goto -> bb4;
36+
}
37+
38+
bb3: {
39+
Coverage::ExpressionUsed(0);
40+
- Coverage::BlockMarker(0);
41+
+ nop;
42+
_0 = const ();
43+
goto -> bb4;
44+
}
45+
46+
bb4: {
47+
Coverage::ExpressionUsed(1);
48+
StorageDead(_1);
49+
return;
50+
}
51+
52+
bb5 (cleanup): {
53+
resume;
54+
}
55+
}
56+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
- // MIR for `main` before InstrumentCoverage
2+
+ // MIR for `main` after InstrumentCoverage
3+
4+
fn main() -> () {
5+
let mut _0: ();
6+
let mut _1: bool;
7+
8+
coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => /the/src/instrument_coverage_cleanup.rs:17:8: 17:36 (#0)
9+
10+
+ coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
11+
+ coverage ExpressionId(1) => Expression { lhs: Counter(1), op: Add, rhs: Expression(0) };
12+
+ coverage Code(Counter(0)) => /the/src/instrument_coverage_cleanup.rs:16:1 - 17:36;
13+
+ coverage Code(Expression(0)) => /the/src/instrument_coverage_cleanup.rs:17:37 - 17:39;
14+
+ coverage Code(Counter(1)) => /the/src/instrument_coverage_cleanup.rs:17:39 - 17:40;
15+
+ coverage Code(Expression(1)) => /the/src/instrument_coverage_cleanup.rs:18:1 - 18:2;
16+
+ coverage Branch { true_term: Expression(0), false_term: Counter(1) } => /the/src/instrument_coverage_cleanup.rs:17:8 - 17:36;
17+
+
18+
bb0: {
19+
+ Coverage::CounterIncrement(0);
20+
Coverage::SpanMarker;
21+
StorageLive(_1);
22+
_1 = std::hint::black_box::<bool>(const true) -> [return: bb1, unwind: bb5];
23+
}
24+
25+
bb1: {
26+
switchInt(move _1) -> [0: bb3, otherwise: bb2];
27+
}
28+
29+
bb2: {
30+
+ Coverage::CounterIncrement(1);
31+
Coverage::BlockMarker(1);
32+
_0 = const ();
33+
goto -> bb4;
34+
}
35+
36+
bb3: {
37+
+ Coverage::ExpressionUsed(0);
38+
Coverage::BlockMarker(0);
39+
_0 = const ();
40+
goto -> bb4;
41+
}
42+
43+
bb4: {
44+
+ Coverage::ExpressionUsed(1);
45+
StorageDead(_1);
46+
return;
47+
}
48+
49+
bb5 (cleanup): {
50+
resume;
51+
}
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Test that CleanupPostBorrowck cleans up the marker statements that are
2+
// inserted during MIR building (after InstrumentCoverage is done with them),
3+
// but leaves the statements that were added by InstrumentCoverage.
4+
//
5+
// Removed statement kinds: BlockMarker, SpanMarker
6+
// Retained statement kinds: CounterIncrement, ExpressionUsed
7+
8+
//@ unit-test: InstrumentCoverage
9+
//@ needs-profiler-support
10+
//@ ignore-windows (see ./instrument_coverage.rs)
11+
//@ compile-flags: -Cinstrument-coverage -Zcoverage-options=branch
12+
//@ compile-flags: --remap-path-prefix={{src-base}}=/the/src
13+
14+
// EMIT_MIR instrument_coverage_cleanup.main.InstrumentCoverage.diff
15+
// EMIT_MIR instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
16+
fn main() {
17+
if !core::hint::black_box(true) {}
18+
}
19+
20+
// CHECK-NOT: Coverage::BlockMarker
21+
// CHECK-NOT: Coverage::SpanMarker
22+
// CHECK: Coverage::CounterIncrement
23+
// CHECK-NOT: Coverage::BlockMarker
24+
// CHECK-NOT: Coverage::SpanMarker

0 commit comments

Comments
 (0)