Rollup merge of #99711 - tmiasko:coverage, r=wesleywiser
Remove reachable coverage without counters Remove reachable coverage without counters to maintain invariant that either there is no coverage at all or there is a live coverage counter left that provides the function source hash. The motivating example would be a following closure: ```rust let f = |x: bool| { debug_assert!(x); }; ``` Which, with span changes from #93967, with disabled debug assertions, after the final CFG simplifications but before removal of dead blocks, gives rise to MIR: ```rust fn main::{closure#0}(_1: &[closure@a.rs:2:13: 2:22], _2: bool) -> () { debug x => _2; let mut _0: (); bb0: { Coverage::Expression(4294967295) = 1 - 2; return; } ... } ``` Which also makes the initial instrumentation quite suspect, although this pull request doesn't attempt to address that aspect directly. Fixes #98833. r? ``@wesleywiser`` ``@richkadel``
This commit is contained in:
commit
3c1eef2e91
3 changed files with 42 additions and 18 deletions
|
@ -315,7 +315,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
/// with `0` executions.
|
||||
///
|
||||
/// If there are no live `Counter` `Coverage` statements remaining, we remove
|
||||
/// dead `Coverage` statements along with the dead blocks. Since at least one
|
||||
/// `Coverage` statements along with the dead blocks. Since at least one
|
||||
/// counter per function is required by LLVM (and necessary, to add the
|
||||
/// `function_hash` to the counter's call to the LLVM intrinsic
|
||||
/// `instrprof.increment()`).
|
||||
|
@ -342,6 +342,16 @@ fn save_unreachable_coverage(
|
|||
}
|
||||
}
|
||||
|
||||
for block in &mut basic_blocks.raw[..first_dead_block] {
|
||||
for statement in &mut block.statements {
|
||||
let StatementKind::Coverage(_) = &statement.kind else { continue };
|
||||
let instance = statement.source_info.scope.inlined_instance(source_scopes);
|
||||
if !live.contains(&instance) {
|
||||
statement.make_nop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if live.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue