diff options
Diffstat (limited to 'compiler/rustc_middle/src/mir/coverage.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/coverage.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index b7410ca5f18..962176290df 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -3,6 +3,7 @@ use std::fmt::{self, Debug, Formatter}; use rustc_index::IndexVec; +use rustc_index::bit_set::BitSet; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; @@ -310,3 +311,41 @@ pub struct MCDCDecisionSpan { pub decision_depth: u16, pub num_conditions: usize, } + +/// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass +/// (for compiler option `-Cinstrument-coverage`), after MIR optimizations +/// have had a chance to potentially remove some of them. +/// +/// Used by the `coverage_ids_info` query. +#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)] +pub struct CoverageIdsInfo { + pub counters_seen: BitSet<CounterId>, + pub zero_expressions: BitSet<ExpressionId>, +} + +impl CoverageIdsInfo { + /// Coverage codegen needs to know how many coverage counters are ever + /// incremented within a function, so that it can set the `num-counters` + /// argument of the `llvm.instrprof.increment` intrinsic. + /// + /// This may be less than the highest counter ID emitted by the + /// InstrumentCoverage MIR pass, if the highest-numbered counter increments + /// were removed by MIR optimizations. + pub fn num_counters_after_mir_opts(&self) -> u32 { + // FIXME(Zalathar): Currently this treats an unused counter as "used" + // if its ID is less than that of the highest counter that really is + // used. Fixing this would require adding a renumbering step somewhere. + self.counters_seen.last_set_in(..).map_or(0, |max| max.as_u32() + 1) + } + + /// Returns `true` if the given term is known to have a value of zero, taking + /// into account knowledge of which counters are unused and which expressions + /// are always zero. + pub fn is_zero_term(&self, term: CovTerm) -> bool { + match term { + CovTerm::Zero => true, + CovTerm::Counter(id) => !self.counters_seen.contains(id), + CovTerm::Expression(id) => self.zero_expressions.contains(id), + } + } +} |
