Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use std::sync::Arc;
use rustc_abi::Align;
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods as _, ConstCodegenMethods};
use rustc_middle::mir::coverage::{
BasicCoverageBlock, CounterId, CovTerm, CoverageIdsInfo, Expression, ExpressionId,
FunctionCoverageInfo, Mapping, MappingKind, Op,
BasicCoverageBlock, CounterId, CovTerm, CoverageCodegenInfo, CoverageMirInfo, Expression,
ExpressionId, Mapping, MappingKind, Op,
};
use rustc_middle::ty::{Instance, TyCtxt};
use rustc_span::{SourceFile, Span};
Expand Down Expand Up @@ -52,22 +52,22 @@ pub(crate) fn prepare_covfun_record<'tcx>(
instance: Instance<'tcx>,
is_used: bool,
) -> Option<CovfunRecord<'tcx>> {
let fn_cov_info = tcx.instance_mir(instance.def).function_coverage_info.as_deref()?;
let ids_info = tcx.coverage_ids_info(instance.def)?;
let mir_info = tcx.instance_mir(instance.def).coverage_mir_info.as_deref()?;
let cg_info = tcx.coverage_codegen_info(instance.def)?;

let expressions = prepare_expressions(ids_info);
let expressions = prepare_expressions(cg_info);

let mut covfun = CovfunRecord {
_instance: instance,
mangled_function_name: tcx.symbol_name(instance).name,
source_hash: if is_used { fn_cov_info.function_source_hash } else { 0 },
source_hash: if is_used { mir_info.function_source_hash } else { 0 },
is_used,
virtual_file_mapping: VirtualFileMapping::default(),
expressions,
regions: llvm_cov::Regions::default(),
};

fill_region_tables(tcx, fn_cov_info, ids_info, &mut covfun);
fill_region_tables(tcx, mir_info, cg_info, &mut covfun);

if covfun.regions.has_no_regions() {
debug!(?covfun, "function has no mappings to embed; skipping");
Expand All @@ -91,12 +91,12 @@ pub(crate) fn counter_for_term(term: CovTerm) -> ffi::Counter {
}

/// Convert the function's coverage-counter expressions into a form suitable for FFI.
fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec<ffi::CounterExpression> {
fn prepare_expressions(cg_info: &CoverageCodegenInfo) -> Vec<ffi::CounterExpression> {
// We know that LLVM will optimize out any unused expressions before
// producing the final coverage map, so there's no need to do the same
// thing on the Rust side unless we're confident we can do much better.
// (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)
ids_info
cg_info
.expressions
.iter()
.map(move |&Expression { lhs, op, rhs }| ffi::CounterExpression {
Expand All @@ -113,14 +113,14 @@ fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec<ffi::CounterExpression
/// Populates the mapping region tables in the current function's covfun record.
fn fill_region_tables<'tcx>(
tcx: TyCtxt<'tcx>,
fn_cov_info: &'tcx FunctionCoverageInfo,
ids_info: &'tcx CoverageIdsInfo,
mir_info: &'tcx CoverageMirInfo,
cg_info: &'tcx CoverageCodegenInfo,
covfun: &mut CovfunRecord<'tcx>,
) {
// If this function is unused, replace all counters with zero.
let counter_for_bcb = |bcb: BasicCoverageBlock| -> ffi::Counter {
let term = if covfun.is_used {
ids_info.term_for_bcb[bcb].expect("every BCB in a mapping was given a term")
cg_info.term_for_bcb[bcb].expect("every BCB in a mapping was given a term")
} else {
CovTerm::Zero
};
Expand All @@ -130,7 +130,7 @@ fn fill_region_tables<'tcx>(
// Currently a function's mappings must all be in the same file, so use the
// first mapping's span to determine the file.
let source_map = tcx.sess.source_map();
let Some(first_span) = (try { fn_cov_info.mappings.first()?.span }) else {
let Some(first_span) = (try { mir_info.mappings.first()?.span }) else {
debug_assert!(false, "function has no mappings: {covfun:?}");
return;
};
Expand All @@ -155,7 +155,7 @@ fn fill_region_tables<'tcx>(

// For each counter/region pair in this function+file, convert it to a
// form suitable for FFI.
for &Mapping { ref kind, span } in &fn_cov_info.mappings {
for &Mapping { ref kind, span } in &mir_info.mappings {
let Some(coords) = make_coords(span) else { continue };
let cov_span = coords.make_coverage_span(local_file_id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
}
}

if !saw_own_coverage && body.function_coverage_info.is_some() {
if !saw_own_coverage && body.coverage_mir_info.is_some() {
missing_own_coverage.insert(def_id);
}
}
Expand Down
14 changes: 6 additions & 8 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,12 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
// FIXME(Zalathar): Find a better solution for mixed-coverage builds.
let Some(_coverage_cx) = &bx.cx.coverage_cx else { return };

let Some(function_coverage_info) =
bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
else {
let Some(mir_info) = bx.tcx.instance_mir(instance.def).coverage_mir_info.as_deref() else {
debug!("function has a coverage statement but no coverage info");
return;
};
let Some(ids_info) = bx.tcx.coverage_ids_info(instance.def) else {
debug!("function has a coverage statement but no IDs info");
let Some(cg_info) = bx.tcx.coverage_codegen_info(instance.def) else {
debug!("function has a coverage statement but no codegen info");
return;
};

Expand All @@ -117,11 +115,11 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
"marker statement {kind:?} should have been removed by CleanupPostBorrowck"
),
CoverageKind::VirtualCounter { bcb }
if let Some(&id) = ids_info.phys_counter_for_node.get(&bcb) =>
if let Some(&id) = cg_info.phys_counter_for_node.get(&bcb) =>
{
let fn_name = bx.ensure_pgo_func_name_var(instance);
let hash = bx.const_u64(function_coverage_info.function_source_hash);
let num_counters = bx.const_u32(ids_info.num_counters);
let hash = bx.const_u64(mir_info.function_source_hash);
let num_counters = bx.const_u32(cg_info.num_counters);
let index = bx.const_u32(id.as_u32());
debug!(
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
Expand Down
27 changes: 14 additions & 13 deletions compiler/rustc_middle/src/mir/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub enum CoverageKind {
SpanMarker,

/// Marks its enclosing basic block with an ID that can be referred to by
/// side data in [`CoverageInfoHi`].
/// side data in [`CoverageEarlyInfo`].
///
/// Should be erased before codegen (at some point after `InstrumentCoverage`).
BlockMarker { id: BlockMarkerId },
Expand Down Expand Up @@ -144,12 +144,11 @@ pub struct Mapping {
pub span: Span,
}

/// 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.
/// Coverage information for a function, collected during the `InstrumentCoverage`
/// MIR pass and stored in the `mir::Body` for later use by coverage codegen.
#[derive(Clone, Debug)]
#[derive(TyEncodable, TyDecodable, Hash, StableHash)]
pub struct FunctionCoverageInfo {
pub struct CoverageMirInfo {
pub function_source_hash: u64,

/// Used in conjunction with `priority_list` to create physical counters
Expand All @@ -160,15 +159,17 @@ pub struct FunctionCoverageInfo {
pub mappings: Vec<Mapping>,
}

/// Coverage information for a function, recorded during MIR building and
/// attached to the corresponding `mir::Body`. Used by the `InstrumentCoverage`
/// MIR pass.
/// Coverage information for a function, collected in advance at the THIR/MIR
/// boundary during MIR building, and attached to the corresponding `mir::Body`.
///
/// ("Hi" indicates that this is "high-level" information collected at the
/// THIR/MIR boundary, before the MIR-based coverage instrumentation pass.)
/// This side-data is "early" in that it must be collected prior to the main
/// instrumentation step, in contrast to the main [`CoverageMirInfo`] produced
/// by instrumentation itself.
///
/// Used by the `InstrumentCoverage` MIR pass.
#[derive(Clone, Debug)]
#[derive(TyEncodable, TyDecodable, Hash, StableHash)]
pub struct CoverageInfoHi {
pub struct CoverageEarlyInfo {
/// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was
/// injected into the MIR body. This makes it possible to allocate per-ID
/// data structures without having to scan the entire body first.
Expand All @@ -187,9 +188,9 @@ pub struct BranchSpan {
/// Contains information needed during codegen, obtained by inspecting the
/// function's MIR after MIR optimizations.
///
/// Returned by the `coverage_ids_info` query.
/// Returned by the [`coverage_codegen_info`](crate::ty::TyCtxt::coverage_codegen_info) query.
#[derive(Clone, TyEncodable, TyDecodable, Debug, StableHash)]
pub struct CoverageIdsInfo {
pub struct CoverageCodegenInfo {
pub num_counters: u32,
pub phys_counter_for_node: FxIndexMap<BasicCoverageBlock, CounterId>,
pub term_for_bcb: IndexVec<BasicCoverageBlock, Option<CovTerm>>,
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,14 @@ pub struct Body<'tcx> {

pub tainted_by_errors: Option<ErrorGuaranteed>,

/// Coverage information collected from THIR/MIR during MIR building,
/// to be used by the `InstrumentCoverage` pass.
/// Coverage information collected at the THIR/MIR boundary during MIR
/// building, to be used by the `InstrumentCoverage` pass.
///
/// Only present if coverage is enabled and this function is eligible.
/// Boxed to limit space overhead in non-coverage builds.
#[type_foldable(identity)]
#[type_visitable(ignore)]
pub coverage_info_hi: Option<Box<coverage::CoverageInfoHi>>,
pub coverage_early_info: Option<Box<coverage::CoverageEarlyInfo>>,

/// Per-function coverage information added by the `InstrumentCoverage`
/// pass, to be used in conjunction with the coverage statements injected
Expand All @@ -327,7 +327,7 @@ pub struct Body<'tcx> {
/// is not eligible for coverage, then this should always be `None`.
#[type_foldable(identity)]
#[type_visitable(ignore)]
pub function_coverage_info: Option<Box<coverage::FunctionCoverageInfo>>,
pub coverage_mir_info: Option<Box<coverage::CoverageMirInfo>>,
}

impl<'tcx> Body<'tcx> {
Expand Down Expand Up @@ -369,8 +369,8 @@ impl<'tcx> Body<'tcx> {
is_polymorphic: false,
injection_phase: None,
tainted_by_errors,
coverage_info_hi: None,
function_coverage_info: None,
coverage_early_info: None,
coverage_mir_info: None,
};
body.is_polymorphic = body.has_non_region_param();
body
Expand Down Expand Up @@ -400,8 +400,8 @@ impl<'tcx> Body<'tcx> {
is_polymorphic: false,
injection_phase: None,
tainted_by_errors: None,
coverage_info_hi: None,
function_coverage_info: None,
coverage_early_info: None,
coverage_mir_info: None,
};
body.is_polymorphic = body.has_non_region_param();
body
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,21 +630,21 @@ fn write_mir_intro<'tcx>(
// Add an empty line before the first block is printed.
writeln!(w)?;

if let Some(coverage_info_hi) = &body.coverage_info_hi {
write_coverage_info_hi(coverage_info_hi, w)?;
if let Some(early_info) = &body.coverage_early_info {
write_coverage_early_info(early_info, w)?;
}
if let Some(function_coverage_info) = &body.function_coverage_info {
write_function_coverage_info(function_coverage_info, w)?;
if let Some(mir_info) = &body.coverage_mir_info {
write_coverage_mir_info(mir_info, w)?;
}

Ok(())
}

fn write_coverage_info_hi(
coverage_info_hi: &coverage::CoverageInfoHi,
fn write_coverage_early_info(
early_info: &coverage::CoverageEarlyInfo,
w: &mut dyn io::Write,
) -> io::Result<()> {
let coverage::CoverageInfoHi { num_block_markers: _, branch_spans } = coverage_info_hi;
let coverage::CoverageEarlyInfo { num_block_markers: _, branch_spans } = early_info;

// Only add an extra trailing newline if we printed at least one thing.
let mut did_print = false;
Expand All @@ -664,11 +664,11 @@ fn write_coverage_info_hi(
Ok(())
}

fn write_function_coverage_info(
function_coverage_info: &coverage::FunctionCoverageInfo,
fn write_coverage_mir_info(
mir_info: &coverage::CoverageMirInfo,
w: &mut dyn io::Write,
) -> io::Result<()> {
let coverage::FunctionCoverageInfo { mappings, .. } = function_coverage_info;
let coverage::CoverageMirInfo { mappings, .. } = mir_info;

for coverage::Mapping { kind, span } in mappings {
writeln!(w, "{INDENT}coverage {kind:?} => {span:?};")?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ pub enum StatementKind<'tcx> {
///
/// Coverage statements are used in conjunction with the coverage mappings and other
/// information stored in the function's
/// [`mir::Body::function_coverage_info`](crate::mir::Body::function_coverage_info).
/// [`mir::Body::coverage_mir_info`](crate::mir::Body::coverage_mir_info).
/// (For inlined MIR, take care to look up the *original function's* coverage info.)
///
/// Interpreters and codegen backends that don't support coverage instrumentation
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,13 +747,11 @@ rustc_queries! {
/// intrinsics, and the expression tables to be embedded in the function's
/// coverage metadata.
///
/// FIXME(Zalathar): This query's purpose has drifted a bit and should
/// probably be renamed, but that can wait until after the potential
/// follow-ups to #136053 have settled down.
///
/// Returns `None` for functions that were not instrumented.
query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> {
desc { "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
query coverage_codegen_info(key: ty::InstanceKind<'tcx>)
-> Option<&'tcx mir::coverage::CoverageCodegenInfo>
{
desc { "retrieving coverage codegen info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
arena_cache
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_mir_build/src/builder/coverageinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::assert_matches;
use std::collections::hash_map::Entry;

use rustc_data_structures::fx::FxHashMap;
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind};
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageEarlyInfo, CoverageKind};
use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
use rustc_middle::ty::TyCtxt;
Expand All @@ -11,7 +11,7 @@ use rustc_span::def_id::LocalDefId;
use crate::builder::{Builder, CFG};

/// Collects coverage-related information during MIR building, to eventually be
/// turned into a function's [`CoverageInfoHi`] when MIR building is complete.
/// turned into a function's [`CoverageEarlyInfo`] when MIR building is complete.
pub(crate) struct CoverageInfoBuilder {
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
nots: FxHashMap<ExprId, NotInfo>,
Expand Down Expand Up @@ -147,18 +147,18 @@ impl CoverageInfoBuilder {
});
}

pub(crate) fn into_done(self) -> Box<CoverageInfoHi> {
pub(crate) fn into_done(self) -> Box<CoverageEarlyInfo> {
let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info } = self;

let branch_spans =
branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default();

// For simplicity, always return an info struct (without Option), even
// if there's nothing interesting in it.
Box::new(CoverageInfoHi { num_block_markers, branch_spans })
Box::new(CoverageEarlyInfo { num_block_markers, branch_spans })
}

pub(crate) fn as_done(&self) -> Box<CoverageInfoHi> {
pub(crate) fn as_done(&self) -> Box<CoverageEarlyInfo> {
let &Self { nots: _, markers: BlockMarkerGen { num_block_markers }, ref branch_info } =
self;

Expand All @@ -170,7 +170,7 @@ impl CoverageInfoBuilder {

// For simplicity, always return an info struct (without Option), even
// if there's nothing interesting in it.
Box::new(CoverageInfoHi { num_block_markers, branch_spans })
Box::new(CoverageEarlyInfo { num_block_markers, branch_spans })
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/builder/custom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ pub(super) fn build_custom_mir<'tcx>(
tainted_by_errors: None,
injection_phase: None,
pass_count: 0,
coverage_info_hi: None,
function_coverage_info: None,
coverage_early_info: None,
coverage_mir_info: None,
};

body.local_decls.push(LocalDecl::new(return_ty, return_ty_span));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.coroutine.clone(),
None,
);
body.coverage_info_hi = self.coverage_info.as_ref().map(|b| b.as_done());
body.coverage_early_info = self.coverage_info.as_ref().map(|b| b.as_done());

let writer = pretty::MirWriter::new(self.tcx);
writer.write_mir_fn(&body, &mut std::io::stdout()).unwrap();
Expand All @@ -858,7 +858,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.coroutine,
None,
);
body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
body.coverage_early_info = self.coverage_info.map(|b| b.into_done());

let writer = pretty::MirWriter::new(self.tcx);
for (index, block) in body.basic_blocks.iter().enumerate() {
Expand Down
Loading
Loading