coverage: Remove intermediate data structures from mapping creation
This commit is contained in:
parent
2c1ac85679
commit
ecce90b3ef
3 changed files with 31 additions and 77 deletions
|
|
@ -1,51 +1,36 @@
|
|||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind};
|
||||
use rustc_middle::mir::coverage::{
|
||||
BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind, Mapping, MappingKind,
|
||||
};
|
||||
use rustc_middle::mir::{self, BasicBlock, StatementKind};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
|
||||
use crate::coverage::graph::CoverageGraph;
|
||||
use crate::coverage::hir_info::ExtractedHirInfo;
|
||||
use crate::coverage::spans::extract_refined_covspans;
|
||||
use crate::coverage::unexpand::unexpand_into_body_span;
|
||||
|
||||
/// Associates an ordinary executable code span with its corresponding BCB.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct CodeMapping {
|
||||
pub(super) span: Span,
|
||||
pub(super) bcb: BasicCoverageBlock,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct BranchPair {
|
||||
pub(super) span: Span,
|
||||
pub(super) true_bcb: BasicCoverageBlock,
|
||||
pub(super) false_bcb: BasicCoverageBlock,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct ExtractedMappings {
|
||||
pub(super) code_mappings: Vec<CodeMapping>,
|
||||
pub(super) branch_pairs: Vec<BranchPair>,
|
||||
pub(crate) struct ExtractedMappings {
|
||||
pub(crate) mappings: Vec<Mapping>,
|
||||
}
|
||||
|
||||
/// Extracts coverage-relevant spans from MIR, and associates them with
|
||||
/// their corresponding BCBs.
|
||||
pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
|
||||
/// Extracts coverage-relevant spans from MIR, and uses them to create
|
||||
/// coverage mapping data for inclusion in MIR.
|
||||
pub(crate) fn extract_mappings_from_mir<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mir_body: &mir::Body<'tcx>,
|
||||
hir_info: &ExtractedHirInfo,
|
||||
graph: &CoverageGraph,
|
||||
) -> ExtractedMappings {
|
||||
let mut code_mappings = vec![];
|
||||
let mut branch_pairs = vec![];
|
||||
let mut mappings = vec![];
|
||||
|
||||
// Extract ordinary code mappings from MIR statement/terminator spans.
|
||||
extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
|
||||
extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut mappings);
|
||||
|
||||
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
|
||||
extract_branch_mappings(mir_body, hir_info, graph, &mut mappings);
|
||||
|
||||
ExtractedMappings { code_mappings, branch_pairs }
|
||||
ExtractedMappings { mappings }
|
||||
}
|
||||
|
||||
fn resolve_block_markers(
|
||||
|
|
@ -69,19 +54,18 @@ fn resolve_block_markers(
|
|||
block_markers
|
||||
}
|
||||
|
||||
pub(super) fn extract_branch_pairs(
|
||||
pub(super) fn extract_branch_mappings(
|
||||
mir_body: &mir::Body<'_>,
|
||||
hir_info: &ExtractedHirInfo,
|
||||
graph: &CoverageGraph,
|
||||
) -> Vec<BranchPair> {
|
||||
let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] };
|
||||
mappings: &mut Vec<Mapping>,
|
||||
) {
|
||||
let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return };
|
||||
|
||||
let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
|
||||
|
||||
coverage_info_hi
|
||||
.branch_spans
|
||||
.iter()
|
||||
.filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
|
||||
mappings.extend(coverage_info_hi.branch_spans.iter().filter_map(
|
||||
|&BranchSpan { span: raw_span, true_marker, false_marker }| try {
|
||||
// For now, ignore any branch span that was introduced by
|
||||
// expansion. This makes things like assert macros less noisy.
|
||||
if !raw_span.ctxt().outer_expn_data().is_root() {
|
||||
|
|
@ -94,7 +78,7 @@ pub(super) fn extract_branch_pairs(
|
|||
let true_bcb = bcb_from_marker(true_marker)?;
|
||||
let false_bcb = bcb_from_marker(false_marker)?;
|
||||
|
||||
Some(BranchPair { span, true_bcb, false_bcb })
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
Mapping { span, kind: MappingKind::Branch { true_bcb, false_bcb } }
|
||||
},
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_middle::mir::coverage::{CoverageKind, FunctionCoverageInfo, Mapping, MappingKind};
|
||||
use rustc_middle::mir::coverage::{CoverageKind, FunctionCoverageInfo};
|
||||
use rustc_middle::mir::{self, BasicBlock, Statement, StatementKind, TerminatorKind};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::{debug, debug_span, trace};
|
||||
|
|
@ -71,10 +71,8 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
// Extract coverage spans and other mapping info from MIR.
|
||||
let extracted_mappings =
|
||||
mappings::extract_all_mapping_info_from_mir(tcx, mir_body, &hir_info, &graph);
|
||||
|
||||
let mappings = create_mappings(&extracted_mappings);
|
||||
let ExtractedMappings { mappings } =
|
||||
mappings::extract_mappings_from_mir(tcx, mir_body, &hir_info, &graph);
|
||||
if mappings.is_empty() {
|
||||
// No spans could be converted into valid mappings, so skip this function.
|
||||
debug!("no spans could be converted into valid mappings; skipping");
|
||||
|
|
@ -100,34 +98,6 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
|||
}));
|
||||
}
|
||||
|
||||
/// For each coverage span extracted from MIR, create a corresponding mapping.
|
||||
///
|
||||
/// FIXME(Zalathar): This used to be where BCBs in the extracted mappings were
|
||||
/// resolved to a `CovTerm`. But that is now handled elsewhere, so this
|
||||
/// function can potentially be simplified even further.
|
||||
fn create_mappings(extracted_mappings: &ExtractedMappings) -> Vec<Mapping> {
|
||||
// Fully destructure the mappings struct to make sure we don't miss any kinds.
|
||||
let ExtractedMappings { code_mappings, branch_pairs } = extracted_mappings;
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
mappings.extend(code_mappings.iter().map(
|
||||
// Ordinary code mappings are the simplest kind.
|
||||
|&mappings::CodeMapping { span, bcb }| {
|
||||
let kind = MappingKind::Code { bcb };
|
||||
Mapping { kind, span }
|
||||
},
|
||||
));
|
||||
|
||||
mappings.extend(branch_pairs.iter().map(
|
||||
|&mappings::BranchPair { span, true_bcb, false_bcb }| {
|
||||
let kind = MappingKind::Branch { true_bcb, false_bcb };
|
||||
Mapping { kind, span }
|
||||
},
|
||||
));
|
||||
|
||||
mappings
|
||||
}
|
||||
|
||||
/// Inject any necessary coverage statements into MIR, so that they influence codegen.
|
||||
fn inject_coverage_statements<'tcx>(mir_body: &mut mir::Body<'tcx>, graph: &CoverageGraph) {
|
||||
for (bcb, data) in graph.iter_enumerated() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::coverage::START_BCB;
|
||||
use rustc_middle::mir::coverage::{Mapping, MappingKind, START_BCB};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span};
|
||||
|
|
@ -9,7 +9,7 @@ use tracing::instrument;
|
|||
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
|
||||
use crate::coverage::hir_info::ExtractedHirInfo;
|
||||
use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir};
|
||||
use crate::coverage::{mappings, unexpand};
|
||||
use crate::coverage::unexpand;
|
||||
|
||||
mod from_mir;
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ pub(super) fn extract_refined_covspans<'tcx>(
|
|||
mir_body: &mir::Body<'tcx>,
|
||||
hir_info: &ExtractedHirInfo,
|
||||
graph: &CoverageGraph,
|
||||
code_mappings: &mut Vec<mappings::CodeMapping>,
|
||||
mappings: &mut Vec<Mapping>,
|
||||
) {
|
||||
if hir_info.is_async_fn {
|
||||
// An async function desugars into a function that returns a future,
|
||||
|
|
@ -26,7 +26,7 @@ pub(super) fn extract_refined_covspans<'tcx>(
|
|||
// outer function will be unhelpful, so just keep the signature span
|
||||
// and ignore all of the spans in the MIR body.
|
||||
if let Some(span) = hir_info.fn_sig_span {
|
||||
code_mappings.push(mappings::CodeMapping { span, bcb: START_BCB });
|
||||
mappings.push(Mapping { span, kind: MappingKind::Code { bcb: START_BCB } })
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -111,9 +111,9 @@ pub(super) fn extract_refined_covspans<'tcx>(
|
|||
// Merge covspans that can be merged.
|
||||
covspans.dedup_by(|b, a| a.merge_if_eligible(b));
|
||||
|
||||
code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
|
||||
mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
|
||||
// Each span produced by the refiner represents an ordinary code region.
|
||||
mappings::CodeMapping { span, bcb }
|
||||
Mapping { span, kind: MappingKind::Code { bcb } }
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue