Skip to content

Commit

Permalink
Skip MIR pass UnreachablePropagation when coverage is enabled
Browse files Browse the repository at this point in the history
When coverage instrumentation and MIR opts are both enabled, coverage relies on
two assumptions:

- MIR opts that would delete `StatementKind::Coverage` statements instead move
  them into bb0 and change them to `CoverageKind::Unreachable`.

- MIR opts won't delete all `CoverageKind::Counter` statements from an
  instrumented function.

Most MIR opts naturally satisfy the second assumption, because they won't
remove coverage statements from bb0, but `UnreachablePropagation` can do so if
it finds that bb0 is unreachable. If this happens, LLVM thinks the function
isn't instrumented, and it vanishes from coverage reports.

A proper solution won't be possible until after per-function coverage info
lands in rust-lang#116046, but for now we can avoid the problem by turning off this
particular pass when coverage instrumentation is enabled.
  • Loading branch information
Zalathar committed Sep 26, 2023
1 parent d23062b commit 64df5a8
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/rustc_mir_transform/src/unreachable_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ pub struct UnreachablePropagation;
impl MirPass<'_> for UnreachablePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
sess.mir_opt_level() >= 2

// FIXME(#116171) Coverage gets confused by MIR passes that can remove all
// coverage statements from an instrumented function. This pass can be
// re-enabled when coverage codegen is robust against that happening.
sess.mir_opt_level() >= 2 && !sess.instrument_coverage()
}

fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down

0 comments on commit 64df5a8

Please sign in to comment.