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 #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 a6dce3b commit ddbb0f7
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 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,9 @@ 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
// Coverage gets confused by MIR passes that can remove all coverage statements
// from an instrumented function.
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 ddbb0f7

Please sign in to comment.