1
Fork 0

coverage: Attach an optional FunctionCoverageInfo to mir::Body

This allows coverage information to be attached to the function as a whole when
appropriate, instead of being smuggled through coverage statements in the
function's basic blocks.

As an example, this patch moves the `function_source_hash` value out of
individual `CoverageKind::Counter` statements and into the per-function info.

When synthesizing unused functions for coverage purposes, the absence of this
info is taken to indicate that a function was not eligible for coverage and
should not be synthesized.
This commit is contained in:
Zalathar 2023-09-10 16:35:37 +10:00
parent 6d7160ce97
commit c479bc7f3b
7 changed files with 74 additions and 54 deletions

View file

@ -60,7 +60,6 @@ impl Debug for Operand {
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum CoverageKind {
Counter {
function_source_hash: u64,
/// ID of this counter within its enclosing function.
/// Expressions in the same function can refer to it as an operand.
id: CounterId,
@ -80,7 +79,7 @@ impl Debug for CoverageKind {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
use CoverageKind::*;
match self {
Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
Counter { id } => write!(fmt, "Counter({:?})", id.index()),
Expression { id, lhs, op, rhs } => write!(
fmt,
"Expression({:?}) = {:?} {} {:?}",
@ -133,3 +132,12 @@ impl Op {
matches!(self, Self::Subtract)
}
}
/// Stores per-function coverage information attached to a `mir::Body`,
/// to be used in conjunction with the individual coverage statements injected
/// into the function's basic blocks.
#[derive(Clone, Debug)]
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct FunctionCoverageInfo {
pub function_source_hash: u64,
}

View file

@ -345,6 +345,14 @@ pub struct Body<'tcx> {
pub injection_phase: Option<MirPhase>,
pub tainted_by_errors: Option<ErrorGuaranteed>,
/// Per-function coverage information added by the `InstrumentCoverage`
/// pass, to be used in conjunction with the coverage statements injected
/// into this body's blocks.
///
/// If `-Cinstrument-coverage` is not active, or if an individual function
/// is not eligible for coverage, then this should always be `None`.
pub function_coverage_info: Option<Box<coverage::FunctionCoverageInfo>>,
}
impl<'tcx> Body<'tcx> {
@ -392,6 +400,7 @@ impl<'tcx> Body<'tcx> {
is_polymorphic: false,
injection_phase: None,
tainted_by_errors,
function_coverage_info: None,
};
body.is_polymorphic = body.has_non_region_param();
body
@ -420,6 +429,7 @@ impl<'tcx> Body<'tcx> {
is_polymorphic: false,
injection_phase: None,
tainted_by_errors: None,
function_coverage_info: None,
};
body.is_polymorphic = body.has_non_region_param();
body