diff options
| author | Zalathar <Zalathar@users.noreply.github.com> | 2025-01-25 18:24:02 +1100 | 
|---|---|---|
| committer | Zalathar <Zalathar@users.noreply.github.com> | 2025-02-06 21:44:31 +1100 | 
| commit | bf1f254b13d09aedfd8b44611f39736c32d5d0f6 (patch) | |
| tree | 832b80573a03403ec3ed598f0505e681b07cae20 /compiler/rustc_mir_transform/src | |
| parent | 20d051ec870739c8f263e5f6f581ca24a5dd56fd (diff) | |
| download | rust-bf1f254b13d09aedfd8b44611f39736c32d5d0f6.tar.gz rust-bf1f254b13d09aedfd8b44611f39736c32d5d0f6.zip | |
coverage: Don't create counters for code that was removed by MIR opts
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/counters.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/query.rs | 6 | 
2 files changed, 19 insertions, 13 deletions
| diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index fa4f80f827b..ac0039fd007 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -80,28 +80,30 @@ fn make_node_flow_priority_list( pub(crate) fn transcribe_counters( old: &NodeCounters<BasicCoverageBlock>, bcb_needs_counter: &DenseBitSet<BasicCoverageBlock>, + bcbs_seen: &DenseBitSet<BasicCoverageBlock>, ) -> CoverageCounters { let mut new = CoverageCounters::with_num_bcbs(bcb_needs_counter.domain_size()); for bcb in bcb_needs_counter.iter() { + if !bcbs_seen.contains(bcb) { + // This BCB's code was removed by MIR opts, so its counter is always zero. + new.set_node_counter(bcb, CovTerm::Zero); + continue; + } + // Our counter-creation algorithm doesn't guarantee that a node's list // of terms starts or ends with a positive term, so partition the // counters into "positive" and "negative" lists for easier handling. - let (mut pos, mut neg): (Vec<_>, Vec<_>) = - old.counter_terms[bcb].iter().partition_map(|&CounterTerm { node, op }| match op { + let (mut pos, mut neg): (Vec<_>, Vec<_>) = old.counter_terms[bcb] + .iter() + // Filter out any BCBs that were removed by MIR opts; + // this treats them as having an execution count of 0. + .filter(|term| bcbs_seen.contains(term.node)) + .partition_map(|&CounterTerm { node, op }| match op { Op::Add => Either::Left(node), Op::Subtract => Either::Right(node), }); - if pos.is_empty() { - // If we somehow end up with no positive terms, fall back to - // creating a physical counter. There's no known way for this - // to happen, but we can avoid an ICE if it does. - debug_assert!(false, "{bcb:?} has no positive counter terms"); - pos = vec![bcb]; - neg = vec![]; - } - // These intermediate sorts are not strictly necessary, but were helpful // in reducing churn when switching to the current counter-creation scheme. // They also help to slightly decrease the overall size of the expression @@ -119,7 +121,7 @@ pub(crate) fn transcribe_counters( pos.sort(); neg.sort(); - let pos_counter = new.make_sum(&pos).expect("`pos` should not be empty"); + let pos_counter = new.make_sum(&pos).unwrap_or(CovTerm::Zero); let new_counter = new.make_subtracted_sum(pos_counter, &neg); new.set_node_counter(bcb, new_counter); } diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index f362f4ccfa2..995fa91e0a0 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -127,8 +127,12 @@ fn coverage_ids_info<'tcx>( } } + // FIXME(Zalathar): It should be possible to sort `priority_list[1..]` by + // `!bcbs_seen.contains(bcb)` to simplify the mappings even further, at the + // expense of some churn in the tests. When doing so, also consider removing + // the sorts in `transcribe_counters`. let node_counters = make_node_counters(&fn_cov_info.node_flow_data, &fn_cov_info.priority_list); - let coverage_counters = transcribe_counters(&node_counters, &bcb_needs_counter); + let coverage_counters = transcribe_counters(&node_counters, &bcb_needs_counter, &bcbs_seen); let mut counters_seen = DenseBitSet::new_empty(coverage_counters.node_counters.len()); let mut expressions_seen = DenseBitSet::new_filled(coverage_counters.expressions.len()); | 
