1
Fork 0

coverage: Rename basic_coverage_blocks to just graph

During coverage instrumentation, this variable always holds the coverage graph,
which is a simplified view of the MIR control-flow graph. The new name is
clearer in context, and also shorter.
This commit is contained in:
Zalathar 2024-12-18 13:53:23 +11:00
parent 8700ba1c2c
commit 544809e48a
5 changed files with 60 additions and 92 deletions

View file

@ -80,7 +80,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>, mir_body: &mir::Body<'tcx>,
hir_info: &ExtractedHirInfo, hir_info: &ExtractedHirInfo,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
) -> ExtractedMappings { ) -> ExtractedMappings {
let mut code_mappings = vec![]; let mut code_mappings = vec![];
let mut branch_pairs = vec![]; let mut branch_pairs = vec![];
@ -102,23 +102,23 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
} }
} else { } else {
// Extract coverage spans from MIR statements/terminators as normal. // Extract coverage spans from MIR statements/terminators as normal.
extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings); extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings);
} }
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks)); branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
extract_mcdc_mappings( extract_mcdc_mappings(
mir_body, mir_body,
tcx, tcx,
hir_info.body_span, hir_info.body_span,
basic_coverage_blocks, graph,
&mut mcdc_bitmap_bits, &mut mcdc_bitmap_bits,
&mut mcdc_degraded_branches, &mut mcdc_degraded_branches,
&mut mcdc_mappings, &mut mcdc_mappings,
); );
ExtractedMappings { ExtractedMappings {
num_bcbs: basic_coverage_blocks.num_nodes(), num_bcbs: graph.num_nodes(),
code_mappings, code_mappings,
branch_pairs, branch_pairs,
mcdc_bitmap_bits, mcdc_bitmap_bits,
@ -211,7 +211,7 @@ fn resolve_block_markers(
pub(super) fn extract_branch_pairs( pub(super) fn extract_branch_pairs(
mir_body: &mir::Body<'_>, mir_body: &mir::Body<'_>,
hir_info: &ExtractedHirInfo, hir_info: &ExtractedHirInfo,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
) -> Vec<BranchPair> { ) -> Vec<BranchPair> {
let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] }; let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] };
@ -228,8 +228,7 @@ pub(super) fn extract_branch_pairs(
} }
let span = unexpand_into_body_span(raw_span, hir_info.body_span)?; let span = unexpand_into_body_span(raw_span, hir_info.body_span)?;
let bcb_from_marker = let bcb_from_marker = |marker: BlockMarkerId| graph.bcb_from_bb(block_markers[marker]?);
|marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
let true_bcb = bcb_from_marker(true_marker)?; let true_bcb = bcb_from_marker(true_marker)?;
let false_bcb = bcb_from_marker(false_marker)?; let false_bcb = bcb_from_marker(false_marker)?;
@ -243,7 +242,7 @@ pub(super) fn extract_mcdc_mappings(
mir_body: &mir::Body<'_>, mir_body: &mir::Body<'_>,
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
body_span: Span, body_span: Span,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
mcdc_bitmap_bits: &mut usize, mcdc_bitmap_bits: &mut usize,
mcdc_degraded_branches: &mut impl Extend<MCDCBranch>, mcdc_degraded_branches: &mut impl Extend<MCDCBranch>,
mcdc_mappings: &mut impl Extend<(MCDCDecision, Vec<MCDCBranch>)>, mcdc_mappings: &mut impl Extend<(MCDCDecision, Vec<MCDCBranch>)>,
@ -252,8 +251,7 @@ pub(super) fn extract_mcdc_mappings(
let block_markers = resolve_block_markers(coverage_info_hi, mir_body); let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
let bcb_from_marker = let bcb_from_marker = |marker: BlockMarkerId| graph.bcb_from_bb(block_markers[marker]?);
|marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
let check_branch_bcb = let check_branch_bcb =
|raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| { |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| {

View file

@ -71,16 +71,15 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
let _span = debug_span!("instrument_function_for_coverage", ?def_id).entered(); let _span = debug_span!("instrument_function_for_coverage", ?def_id).entered();
let hir_info = extract_hir_info(tcx, def_id.expect_local()); let hir_info = extract_hir_info(tcx, def_id.expect_local());
let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
// Build the coverage graph, which is a simplified view of the MIR control-flow
// graph that ignores some details not relevant to coverage instrumentation.
let graph = CoverageGraph::from_mir(mir_body);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// Extract coverage spans and other mapping info from MIR. // Extract coverage spans and other mapping info from MIR.
let extracted_mappings = mappings::extract_all_mapping_info_from_mir( let extracted_mappings =
tcx, mappings::extract_all_mapping_info_from_mir(tcx, mir_body, &hir_info, &graph);
mir_body,
&hir_info,
&basic_coverage_blocks,
);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
@ -94,7 +93,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
} }
let coverage_counters = let coverage_counters =
CoverageCounters::make_bcb_counters(&basic_coverage_blocks, &bcbs_with_counter_mappings); CoverageCounters::make_bcb_counters(&graph, &bcbs_with_counter_mappings);
let mappings = create_mappings(&extracted_mappings, &coverage_counters); let mappings = create_mappings(&extracted_mappings, &coverage_counters);
if mappings.is_empty() { if mappings.is_empty() {
@ -103,14 +102,9 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
return; return;
} }
inject_coverage_statements( inject_coverage_statements(mir_body, &graph, &extracted_mappings, &coverage_counters);
mir_body,
&basic_coverage_blocks,
&extracted_mappings,
&coverage_counters,
);
inject_mcdc_statements(mir_body, &basic_coverage_blocks, &extracted_mappings); inject_mcdc_statements(mir_body, &graph, &extracted_mappings);
let mcdc_num_condition_bitmaps = extracted_mappings let mcdc_num_condition_bitmaps = extracted_mappings
.mcdc_mappings .mcdc_mappings
@ -243,7 +237,7 @@ fn create_mappings(
/// inject any necessary coverage statements into MIR. /// inject any necessary coverage statements into MIR.
fn inject_coverage_statements<'tcx>( fn inject_coverage_statements<'tcx>(
mir_body: &mut mir::Body<'tcx>, mir_body: &mut mir::Body<'tcx>,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
extracted_mappings: &ExtractedMappings, extracted_mappings: &ExtractedMappings,
coverage_counters: &CoverageCounters, coverage_counters: &CoverageCounters,
) { ) {
@ -253,12 +247,12 @@ fn inject_coverage_statements<'tcx>(
// For BCB nodes this is just their first block, but for edges we need // For BCB nodes this is just their first block, but for edges we need
// to create a new block between the two BCBs, and inject into that. // to create a new block between the two BCBs, and inject into that.
let target_bb = match site { let target_bb = match site {
Site::Node { bcb } => basic_coverage_blocks[bcb].leader_bb(), Site::Node { bcb } => graph[bcb].leader_bb(),
Site::Edge { from_bcb, to_bcb } => { Site::Edge { from_bcb, to_bcb } => {
// Create a new block between the last block of `from_bcb` and // Create a new block between the last block of `from_bcb` and
// the first block of `to_bcb`. // the first block of `to_bcb`.
let from_bb = basic_coverage_blocks[from_bcb].last_bb(); let from_bb = graph[from_bcb].last_bb();
let to_bb = basic_coverage_blocks[to_bcb].leader_bb(); let to_bb = graph[to_bcb].leader_bb();
let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb); let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb);
debug!( debug!(
@ -291,7 +285,7 @@ fn inject_coverage_statements<'tcx>(
inject_statement( inject_statement(
mir_body, mir_body,
CoverageKind::ExpressionUsed { id: expression_id }, CoverageKind::ExpressionUsed { id: expression_id },
basic_coverage_blocks[bcb].leader_bb(), graph[bcb].leader_bb(),
); );
} }
} }
@ -300,13 +294,13 @@ fn inject_coverage_statements<'tcx>(
/// For each decision inject statements to update test vector bitmap after it has been evaluated. /// For each decision inject statements to update test vector bitmap after it has been evaluated.
fn inject_mcdc_statements<'tcx>( fn inject_mcdc_statements<'tcx>(
mir_body: &mut mir::Body<'tcx>, mir_body: &mut mir::Body<'tcx>,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
extracted_mappings: &ExtractedMappings, extracted_mappings: &ExtractedMappings,
) { ) {
for (decision, conditions) in &extracted_mappings.mcdc_mappings { for (decision, conditions) in &extracted_mappings.mcdc_mappings {
// Inject test vector update first because `inject_statement` always insert new statement at head. // Inject test vector update first because `inject_statement` always insert new statement at head.
for &end in &decision.end_bcbs { for &end in &decision.end_bcbs {
let end_bb = basic_coverage_blocks[end].leader_bb(); let end_bb = graph[end].leader_bb();
inject_statement( inject_statement(
mir_body, mir_body,
CoverageKind::TestVectorBitmapUpdate { CoverageKind::TestVectorBitmapUpdate {
@ -327,7 +321,7 @@ fn inject_mcdc_statements<'tcx>(
} in conditions } in conditions
{ {
for (index, bcb) in [(false_index, false_bcb), (true_index, true_bcb)] { for (index, bcb) in [(false_index, false_bcb), (true_index, true_bcb)] {
let bb = basic_coverage_blocks[bcb].leader_bb(); let bb = graph[bcb].leader_bb();
inject_statement( inject_statement(
mir_body, mir_body,
CoverageKind::CondBitmapUpdate { CoverageKind::CondBitmapUpdate {

View file

@ -17,14 +17,13 @@ mod from_mir;
pub(super) fn extract_refined_covspans( pub(super) fn extract_refined_covspans(
mir_body: &mir::Body<'_>, mir_body: &mir::Body<'_>,
hir_info: &ExtractedHirInfo, hir_info: &ExtractedHirInfo,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
code_mappings: &mut impl Extend<mappings::CodeMapping>, code_mappings: &mut impl Extend<mappings::CodeMapping>,
) { ) {
let ExtractedCovspans { mut covspans } = let ExtractedCovspans { mut covspans } = extract_covspans_from_mir(mir_body, hir_info, graph);
extract_covspans_from_mir(mir_body, hir_info, basic_coverage_blocks);
// First, perform the passes that need macro information. // First, perform the passes that need macro information.
covspans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb)); covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
remove_unwanted_expansion_spans(&mut covspans); remove_unwanted_expansion_spans(&mut covspans);
split_visible_macro_spans(&mut covspans); split_visible_macro_spans(&mut covspans);
@ -34,7 +33,7 @@ pub(super) fn extract_refined_covspans(
let compare_covspans = |a: &Covspan, b: &Covspan| { let compare_covspans = |a: &Covspan, b: &Covspan| {
compare_spans(a.span, b.span) compare_spans(a.span, b.span)
// After deduplication, we want to keep only the most-dominated BCB. // After deduplication, we want to keep only the most-dominated BCB.
.then_with(|| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb).reverse()) .then_with(|| graph.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
}; };
covspans.sort_by(compare_covspans); covspans.sort_by(compare_covspans);

View file

@ -22,13 +22,13 @@ pub(crate) struct ExtractedCovspans {
pub(crate) fn extract_covspans_from_mir( pub(crate) fn extract_covspans_from_mir(
mir_body: &mir::Body<'_>, mir_body: &mir::Body<'_>,
hir_info: &ExtractedHirInfo, hir_info: &ExtractedHirInfo,
basic_coverage_blocks: &CoverageGraph, graph: &CoverageGraph,
) -> ExtractedCovspans { ) -> ExtractedCovspans {
let &ExtractedHirInfo { body_span, .. } = hir_info; let &ExtractedHirInfo { body_span, .. } = hir_info;
let mut covspans = vec![]; let mut covspans = vec![];
for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() { for (bcb, bcb_data) in graph.iter_enumerated() {
bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans); bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans);
} }

View file

@ -223,16 +223,12 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
} }
} }
fn print_coverage_graphviz( fn print_coverage_graphviz(name: &str, mir_body: &Body<'_>, graph: &graph::CoverageGraph) {
name: &str,
mir_body: &Body<'_>,
basic_coverage_blocks: &graph::CoverageGraph,
) {
if PRINT_GRAPHS { if PRINT_GRAPHS {
println!( println!(
"digraph {} {{\n{}\n}}", "digraph {} {{\n{}\n}}",
name, name,
basic_coverage_blocks graph
.iter_enumerated() .iter_enumerated()
.map(|(bcb, bcb_data)| { .map(|(bcb, bcb_data)| {
format!( format!(
@ -240,7 +236,7 @@ fn print_coverage_graphviz(
bcb, bcb,
bcb, bcb,
mir_body[bcb_data.last_bb()].terminator().kind.name(), mir_body[bcb_data.last_bb()].terminator().kind.name(),
basic_coverage_blocks graph
.successors(bcb) .successors(bcb)
.map(|successor| { format!(" {:?} -> {:?};", bcb, successor) }) .map(|successor| { format!(" {:?} -> {:?};", bcb, successor) })
.join("\n") .join("\n")
@ -300,11 +296,11 @@ fn goto_switchint<'a>() -> Body<'a> {
#[track_caller] #[track_caller]
fn assert_successors( fn assert_successors(
basic_coverage_blocks: &graph::CoverageGraph, graph: &graph::CoverageGraph,
bcb: BasicCoverageBlock, bcb: BasicCoverageBlock,
expected_successors: &[BasicCoverageBlock], expected_successors: &[BasicCoverageBlock],
) { ) {
let mut successors = basic_coverage_blocks.successors[bcb].clone(); let mut successors = graph.successors[bcb].clone();
successors.sort_unstable(); successors.sort_unstable();
assert_eq!(successors, expected_successors); assert_eq!(successors, expected_successors);
} }
@ -315,8 +311,8 @@ fn test_covgraph_goto_switchint() {
if false { if false {
eprintln!("basic_blocks = {}", debug_basic_blocks(&mir_body)); eprintln!("basic_blocks = {}", debug_basic_blocks(&mir_body));
} }
let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); let graph = graph::CoverageGraph::from_mir(&mir_body);
print_coverage_graphviz("covgraph_goto_switchint ", &mir_body, &basic_coverage_blocks); print_coverage_graphviz("covgraph_goto_switchint ", &mir_body, &graph);
/* /*
bcb2: Return bcb0: SwitchInt bcb2: Return bcb0: SwitchInt
@ -328,16 +324,11 @@ fn test_covgraph_goto_switchint() {
bcb1: Return bcb1: Return
*/ */
assert_eq!( assert_eq!(graph.num_nodes(), 3, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
basic_coverage_blocks.num_nodes(),
3,
"basic_coverage_blocks: {:?}",
basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
);
assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1), bcb(2)]); assert_successors(&graph, bcb(0), &[bcb(1), bcb(2)]);
assert_successors(&basic_coverage_blocks, bcb(1), &[]); assert_successors(&graph, bcb(1), &[]);
assert_successors(&basic_coverage_blocks, bcb(2), &[]); assert_successors(&graph, bcb(2), &[]);
} }
/// Create a mock `Body` with a loop. /// Create a mock `Body` with a loop.
@ -383,12 +374,8 @@ fn switchint_then_loop_else_return<'a>() -> Body<'a> {
#[test] #[test]
fn test_covgraph_switchint_then_loop_else_return() { fn test_covgraph_switchint_then_loop_else_return() {
let mir_body = switchint_then_loop_else_return(); let mir_body = switchint_then_loop_else_return();
let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); let graph = graph::CoverageGraph::from_mir(&mir_body);
print_coverage_graphviz( print_coverage_graphviz("covgraph_switchint_then_loop_else_return", &mir_body, &graph);
"covgraph_switchint_then_loop_else_return",
&mir_body,
&basic_coverage_blocks,
);
/* /*
bcb0: Call bcb0: Call
@ -408,17 +395,12 @@ fn test_covgraph_switchint_then_loop_else_return() {
*/ */
assert_eq!( assert_eq!(graph.num_nodes(), 4, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
basic_coverage_blocks.num_nodes(),
4,
"basic_coverage_blocks: {:?}",
basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
);
assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1)]); assert_successors(&graph, bcb(0), &[bcb(1)]);
assert_successors(&basic_coverage_blocks, bcb(1), &[bcb(2), bcb(3)]); assert_successors(&graph, bcb(1), &[bcb(2), bcb(3)]);
assert_successors(&basic_coverage_blocks, bcb(2), &[]); assert_successors(&graph, bcb(2), &[]);
assert_successors(&basic_coverage_blocks, bcb(3), &[bcb(1)]); assert_successors(&graph, bcb(3), &[bcb(1)]);
} }
/// Create a mock `Body` with nested loops. /// Create a mock `Body` with nested loops.
@ -494,11 +476,11 @@ fn switchint_loop_then_inner_loop_else_break<'a>() -> Body<'a> {
#[test] #[test]
fn test_covgraph_switchint_loop_then_inner_loop_else_break() { fn test_covgraph_switchint_loop_then_inner_loop_else_break() {
let mir_body = switchint_loop_then_inner_loop_else_break(); let mir_body = switchint_loop_then_inner_loop_else_break();
let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); let graph = graph::CoverageGraph::from_mir(&mir_body);
print_coverage_graphviz( print_coverage_graphviz(
"covgraph_switchint_loop_then_inner_loop_else_break", "covgraph_switchint_loop_then_inner_loop_else_break",
&mir_body, &mir_body,
&basic_coverage_blocks, &graph,
); );
/* /*
@ -531,18 +513,13 @@ fn test_covgraph_switchint_loop_then_inner_loop_else_break() {
*/ */
assert_eq!( assert_eq!(graph.num_nodes(), 7, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
basic_coverage_blocks.num_nodes(),
7,
"basic_coverage_blocks: {:?}",
basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
);
assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1)]); assert_successors(&graph, bcb(0), &[bcb(1)]);
assert_successors(&basic_coverage_blocks, bcb(1), &[bcb(2), bcb(3)]); assert_successors(&graph, bcb(1), &[bcb(2), bcb(3)]);
assert_successors(&basic_coverage_blocks, bcb(2), &[]); assert_successors(&graph, bcb(2), &[]);
assert_successors(&basic_coverage_blocks, bcb(3), &[bcb(4)]); assert_successors(&graph, bcb(3), &[bcb(4)]);
assert_successors(&basic_coverage_blocks, bcb(4), &[bcb(5), bcb(6)]); assert_successors(&graph, bcb(4), &[bcb(5), bcb(6)]);
assert_successors(&basic_coverage_blocks, bcb(5), &[bcb(1)]); assert_successors(&graph, bcb(5), &[bcb(1)]);
assert_successors(&basic_coverage_blocks, bcb(6), &[bcb(4)]); assert_successors(&graph, bcb(6), &[bcb(4)]);
} }