coverage. Adapt to mcdc mapping formats introduced by llvm 19
This commit is contained in:
parent
99bd601df5
commit
6e3e19f714
22 changed files with 490 additions and 485 deletions
|
@ -114,16 +114,16 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
|
|||
inject_mcdc_statements(mir_body, &basic_coverage_blocks, &extracted_mappings);
|
||||
|
||||
let mcdc_num_condition_bitmaps = extracted_mappings
|
||||
.mcdc_decisions
|
||||
.mcdc_mappings
|
||||
.iter()
|
||||
.map(|&mappings::MCDCDecision { decision_depth, .. }| decision_depth)
|
||||
.map(|&(mappings::MCDCDecision { decision_depth, .. }, _)| decision_depth)
|
||||
.max()
|
||||
.map_or(0, |max| usize::from(max) + 1);
|
||||
|
||||
mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo {
|
||||
function_source_hash: hir_info.function_source_hash,
|
||||
num_counters: coverage_counters.num_counters(),
|
||||
mcdc_bitmap_bytes: extracted_mappings.mcdc_bitmap_bytes,
|
||||
mcdc_bitmap_bits: extracted_mappings.mcdc_bitmap_bits,
|
||||
expressions: coverage_counters.into_expressions(),
|
||||
mappings,
|
||||
mcdc_num_condition_bitmaps,
|
||||
|
@ -161,9 +161,9 @@ fn create_mappings<'tcx>(
|
|||
num_bcbs: _,
|
||||
code_mappings,
|
||||
branch_pairs,
|
||||
mcdc_bitmap_bytes: _,
|
||||
mcdc_branches,
|
||||
mcdc_decisions,
|
||||
mcdc_bitmap_bits: _,
|
||||
mcdc_degraded_branches,
|
||||
mcdc_mappings,
|
||||
} = extracted_mappings;
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
|
@ -186,26 +186,79 @@ fn create_mappings<'tcx>(
|
|||
},
|
||||
));
|
||||
|
||||
mappings.extend(mcdc_branches.iter().filter_map(
|
||||
|&mappings::MCDCBranch { span, true_bcb, false_bcb, condition_info, decision_depth: _ }| {
|
||||
let term_for_bcb =
|
||||
|bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
|
||||
|
||||
// MCDC branch mappings are appended with their decisions in case decisions were ignored.
|
||||
mappings.extend(mcdc_degraded_branches.iter().filter_map(
|
||||
|&mappings::MCDCBranch {
|
||||
span,
|
||||
true_bcb,
|
||||
false_bcb,
|
||||
condition_info: _,
|
||||
true_index: _,
|
||||
false_index: _,
|
||||
}| {
|
||||
let source_region = region_for_span(span)?;
|
||||
let true_term = term_for_bcb(true_bcb);
|
||||
let false_term = term_for_bcb(false_bcb);
|
||||
let kind = match condition_info {
|
||||
Some(mcdc_params) => MappingKind::MCDCBranch { true_term, false_term, mcdc_params },
|
||||
None => MappingKind::Branch { true_term, false_term },
|
||||
};
|
||||
Some(Mapping { kind, source_region })
|
||||
Some(Mapping { kind: MappingKind::Branch { true_term, false_term }, source_region })
|
||||
},
|
||||
));
|
||||
|
||||
mappings.extend(mcdc_decisions.iter().filter_map(
|
||||
|&mappings::MCDCDecision { span, bitmap_idx, num_conditions, .. }| {
|
||||
let source_region = region_for_span(span)?;
|
||||
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, num_conditions });
|
||||
Some(Mapping { kind, source_region })
|
||||
},
|
||||
));
|
||||
for (decision, branches) in mcdc_mappings {
|
||||
let num_conditions = branches.len() as u16;
|
||||
let conditions = branches
|
||||
.into_iter()
|
||||
.filter_map(
|
||||
|&mappings::MCDCBranch {
|
||||
span,
|
||||
true_bcb,
|
||||
false_bcb,
|
||||
condition_info,
|
||||
true_index: _,
|
||||
false_index: _,
|
||||
}| {
|
||||
let source_region = region_for_span(span)?;
|
||||
let true_term = term_for_bcb(true_bcb);
|
||||
let false_term = term_for_bcb(false_bcb);
|
||||
Some(Mapping {
|
||||
kind: MappingKind::MCDCBranch {
|
||||
true_term,
|
||||
false_term,
|
||||
mcdc_params: condition_info,
|
||||
},
|
||||
source_region,
|
||||
})
|
||||
},
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if conditions.len() == num_conditions as usize
|
||||
&& let Some(source_region) = region_for_span(decision.span)
|
||||
{
|
||||
// LLVM requires end index for counter mapping regions.
|
||||
let kind = MappingKind::MCDCDecision(DecisionInfo {
|
||||
bitmap_idx: (decision.bitmap_idx + decision.num_test_vectors) as u32,
|
||||
num_conditions,
|
||||
});
|
||||
mappings.extend(
|
||||
std::iter::once(Mapping { kind, source_region }).chain(conditions.into_iter()),
|
||||
);
|
||||
} else {
|
||||
mappings.extend(conditions.into_iter().map(|mapping| {
|
||||
let MappingKind::MCDCBranch { true_term, false_term, mcdc_params: _ } =
|
||||
mapping.kind
|
||||
else {
|
||||
unreachable!("all mappings here are MCDCBranch as shown above");
|
||||
};
|
||||
Mapping {
|
||||
kind: MappingKind::Branch { true_term, false_term },
|
||||
source_region: mapping.source_region,
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
mappings
|
||||
}
|
||||
|
@ -274,44 +327,41 @@ fn inject_mcdc_statements<'tcx>(
|
|||
basic_coverage_blocks: &CoverageGraph,
|
||||
extracted_mappings: &ExtractedMappings,
|
||||
) {
|
||||
// Inject test vector update first because `inject_statement` always insert new statement at
|
||||
// head.
|
||||
for &mappings::MCDCDecision {
|
||||
span: _,
|
||||
ref end_bcbs,
|
||||
bitmap_idx,
|
||||
num_conditions: _,
|
||||
decision_depth,
|
||||
} in &extracted_mappings.mcdc_decisions
|
||||
{
|
||||
for end in end_bcbs {
|
||||
let end_bb = basic_coverage_blocks[*end].leader_bb();
|
||||
for (decision, conditions) in &extracted_mappings.mcdc_mappings {
|
||||
// Inject test vector update first because `inject_statement` always insert new statement at head.
|
||||
for &end in &decision.end_bcbs {
|
||||
let end_bb = basic_coverage_blocks[end].leader_bb();
|
||||
inject_statement(
|
||||
mir_body,
|
||||
CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth },
|
||||
CoverageKind::TestVectorBitmapUpdate {
|
||||
bitmap_idx: decision.bitmap_idx as u32,
|
||||
decision_depth: decision.decision_depth,
|
||||
},
|
||||
end_bb,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for &mappings::MCDCBranch { span: _, true_bcb, false_bcb, condition_info, decision_depth } in
|
||||
&extracted_mappings.mcdc_branches
|
||||
{
|
||||
let Some(condition_info) = condition_info else { continue };
|
||||
let id = condition_info.condition_id;
|
||||
|
||||
let true_bb = basic_coverage_blocks[true_bcb].leader_bb();
|
||||
inject_statement(
|
||||
mir_body,
|
||||
CoverageKind::CondBitmapUpdate { id, value: true, decision_depth },
|
||||
true_bb,
|
||||
);
|
||||
let false_bb = basic_coverage_blocks[false_bcb].leader_bb();
|
||||
inject_statement(
|
||||
mir_body,
|
||||
CoverageKind::CondBitmapUpdate { id, value: false, decision_depth },
|
||||
false_bb,
|
||||
);
|
||||
for &mappings::MCDCBranch {
|
||||
span: _,
|
||||
true_bcb,
|
||||
false_bcb,
|
||||
condition_info: _,
|
||||
true_index,
|
||||
false_index,
|
||||
} in conditions
|
||||
{
|
||||
for (index, bcb) in [(false_index, false_bcb), (true_index, true_bcb)] {
|
||||
let bb = basic_coverage_blocks[bcb].leader_bb();
|
||||
inject_statement(
|
||||
mir_body,
|
||||
CoverageKind::CondBitmapUpdate {
|
||||
index: index as u32,
|
||||
decision_depth: decision.decision_depth,
|
||||
},
|
||||
bb,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue