coverage: Let each coverage statement hold a vector of code regions
This makes it possible for a `StatementKind::Coverage` to hold more than one code region, but that capability is not yet used.
This commit is contained in:
parent
1355e1fc74
commit
ee9d00f6b8
9 changed files with 96 additions and 90 deletions
|
@ -243,7 +243,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
|
|||
self.mir_body,
|
||||
self.make_mir_coverage_kind(&counter_kind),
|
||||
self.bcb_leader_bb(bcb),
|
||||
Some(code_region),
|
||||
vec![code_region],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
|
|||
self.mir_body,
|
||||
self.make_mir_coverage_kind(&counter_kind),
|
||||
inject_to_bb,
|
||||
None,
|
||||
Vec::new(),
|
||||
);
|
||||
}
|
||||
BcbCounter::Expression { .. } => inject_intermediate_expression(
|
||||
|
@ -367,20 +367,14 @@ fn inject_statement(
|
|||
mir_body: &mut mir::Body<'_>,
|
||||
counter_kind: CoverageKind,
|
||||
bb: BasicBlock,
|
||||
some_code_region: Option<CodeRegion>,
|
||||
code_regions: Vec<CodeRegion>,
|
||||
) {
|
||||
debug!(
|
||||
" injecting statement {:?} for {:?} at code region: {:?}",
|
||||
counter_kind, bb, some_code_region
|
||||
);
|
||||
debug!(" injecting statement {counter_kind:?} for {bb:?} at code regions: {code_regions:?}");
|
||||
let data = &mut mir_body[bb];
|
||||
let source_info = data.terminator().source_info;
|
||||
let statement = Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Coverage(Box::new(Coverage {
|
||||
kind: counter_kind,
|
||||
code_region: some_code_region,
|
||||
})),
|
||||
kind: StatementKind::Coverage(Box::new(Coverage { kind: counter_kind, code_regions })),
|
||||
};
|
||||
data.statements.insert(0, statement);
|
||||
}
|
||||
|
@ -394,7 +388,10 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'_>, expression: Cove
|
|||
let source_info = data.terminator().source_info;
|
||||
let statement = Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Coverage(Box::new(Coverage { kind: expression, code_region: None })),
|
||||
kind: StatementKind::Coverage(Box::new(Coverage {
|
||||
kind: expression,
|
||||
code_regions: Vec::new(),
|
||||
})),
|
||||
};
|
||||
data.statements.push(statement);
|
||||
}
|
||||
|
|
|
@ -93,8 +93,8 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) ->
|
|||
fn covered_code_regions(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<&CodeRegion> {
|
||||
let body = mir_body(tcx, def_id);
|
||||
all_coverage_in_mir_body(body)
|
||||
// Not all coverage statements have an attached code region.
|
||||
.filter_map(|coverage| coverage.code_region.as_ref())
|
||||
// Coverage statements have a list of code regions (possibly empty).
|
||||
.flat_map(|coverage| coverage.code_regions.as_slice())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -441,21 +441,23 @@ fn save_unreachable_coverage(
|
|||
let dead_block = &basic_blocks[dead_block];
|
||||
for statement in &dead_block.statements {
|
||||
let StatementKind::Coverage(coverage) = &statement.kind else { continue };
|
||||
let Some(code_region) = &coverage.code_region else { continue };
|
||||
if coverage.code_regions.is_empty() {
|
||||
continue;
|
||||
};
|
||||
let instance = statement.source_info.scope.inlined_instance(source_scopes);
|
||||
if live.contains(&instance) {
|
||||
retained_coverage.push((statement.source_info, code_region.clone()));
|
||||
retained_coverage.push((statement.source_info, coverage.code_regions.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let start_block = &mut basic_blocks[START_BLOCK];
|
||||
start_block.statements.extend(retained_coverage.into_iter().map(
|
||||
|(source_info, code_region)| Statement {
|
||||
|(source_info, code_regions)| Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Coverage(Box::new(Coverage {
|
||||
kind: CoverageKind::Unreachable,
|
||||
code_region: Some(code_region),
|
||||
code_regions,
|
||||
})),
|
||||
},
|
||||
));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue