coverage: Make obtaining the codegen coverage context infallible
In all the situations where this context is needed, it should always be available.
This commit is contained in:
parent
9f8a6be221
commit
0a96176533
3 changed files with 16 additions and 33 deletions
|
@ -80,6 +80,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
|
||||||
|
|
||||||
pub isize_ty: &'ll Type,
|
pub isize_ty: &'ll Type,
|
||||||
|
|
||||||
|
/// Extra codegen state needed when coverage instrumentation is enabled.
|
||||||
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
|
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
|
||||||
pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,
|
pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,
|
||||||
|
|
||||||
|
@ -592,11 +593,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
&self.statics_to_rauw
|
&self.statics_to_rauw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extra state that is only available when coverage instrumentation is enabled.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn coverage_context(
|
pub(crate) fn coverage_cx(&self) -> &coverageinfo::CrateCoverageContext<'ll, 'tcx> {
|
||||||
&self,
|
self.coverage_cx.as_ref().expect("only called when coverage instrumentation is enabled")
|
||||||
) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
|
|
||||||
self.coverage_cx.as_ref()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
|
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
|
||||||
|
|
|
@ -54,11 +54,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
|
||||||
add_unused_functions(cx);
|
add_unused_functions(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let function_coverage_map = match cx.coverage_context() {
|
let function_coverage_map = cx.coverage_cx().take_function_coverage_map();
|
||||||
Some(ctx) => ctx.take_function_coverage_map(),
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
if function_coverage_map.is_empty() {
|
if function_coverage_map.is_empty() {
|
||||||
// This module has no functions with coverage instrumentation
|
// This module has no functions with coverage instrumentation
|
||||||
return;
|
return;
|
||||||
|
@ -543,9 +539,5 @@ fn add_unused_function_coverage<'tcx>(
|
||||||
// zero, because none of its counters/expressions are marked as seen.
|
// zero, because none of its counters/expressions are marked as seen.
|
||||||
let function_coverage = FunctionCoverageCollector::unused(instance, function_coverage_info);
|
let function_coverage = FunctionCoverageCollector::unused(instance, function_coverage_info);
|
||||||
|
|
||||||
if let Some(coverage_context) = cx.coverage_context() {
|
cx.coverage_cx().function_coverage_map.borrow_mut().insert(instance, function_coverage);
|
||||||
coverage_context.function_coverage_map.borrow_mut().insert(instance, function_coverage);
|
|
||||||
} else {
|
|
||||||
bug!("Could not get the `coverage_context`");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_codegen_ssa::traits::{
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||||
use rustc_llvm::RustString;
|
use rustc_llvm::RustString;
|
||||||
use rustc_middle::bug;
|
|
||||||
use rustc_middle::mir::coverage::CoverageKind;
|
use rustc_middle::mir::coverage::CoverageKind;
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
use rustc_middle::ty::layout::HasTyCtxt;
|
use rustc_middle::ty::layout::HasTyCtxt;
|
||||||
|
@ -76,15 +75,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
/// `instrprof.increment()`. The `Value` is only created once per instance.
|
/// `instrprof.increment()`. The `Value` is only created once per instance.
|
||||||
/// Multiple invocations with the same instance return the same `Value`.
|
/// Multiple invocations with the same instance return the same `Value`.
|
||||||
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
|
fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value {
|
||||||
if let Some(coverage_context) = self.coverage_context() {
|
|
||||||
debug!("getting pgo_func_name_var for instance={:?}", instance);
|
debug!("getting pgo_func_name_var for instance={:?}", instance);
|
||||||
let mut pgo_func_name_var_map = coverage_context.pgo_func_name_var_map.borrow_mut();
|
let mut pgo_func_name_var_map = self.coverage_cx().pgo_func_name_var_map.borrow_mut();
|
||||||
pgo_func_name_var_map
|
pgo_func_name_var_map
|
||||||
.entry(instance)
|
.entry(instance)
|
||||||
.or_insert_with(|| create_pgo_func_name_var(self, instance))
|
.or_insert_with(|| create_pgo_func_name_var(self, instance))
|
||||||
} else {
|
|
||||||
bug!("Could not get the `coverage_context`");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +113,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
cond_bitmaps.push(cond_bitmap);
|
cond_bitmaps.push(cond_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.coverage_context()
|
self.coverage_cx().mcdc_condition_bitmap_map.borrow_mut().insert(instance, cond_bitmaps);
|
||||||
.expect("always present when coverage is enabled")
|
|
||||||
.mcdc_condition_bitmap_map
|
|
||||||
.borrow_mut()
|
|
||||||
.insert(instance, cond_bitmaps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
@ -143,8 +134,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(coverage_context) = bx.coverage_context() else { return };
|
let mut coverage_map = bx.coverage_cx().function_coverage_map.borrow_mut();
|
||||||
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
|
|
||||||
let func_coverage = coverage_map
|
let func_coverage = coverage_map
|
||||||
.entry(instance)
|
.entry(instance)
|
||||||
.or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info));
|
.or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info));
|
||||||
|
@ -186,7 +176,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
CoverageKind::CondBitmapUpdate { index, decision_depth } => {
|
CoverageKind::CondBitmapUpdate { index, decision_depth } => {
|
||||||
drop(coverage_map);
|
drop(coverage_map);
|
||||||
let cond_bitmap = coverage_context
|
let cond_bitmap = bx
|
||||||
|
.coverage_cx()
|
||||||
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
|
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
|
||||||
.expect("mcdc cond bitmap should have been allocated for updating");
|
.expect("mcdc cond bitmap should have been allocated for updating");
|
||||||
let cond_index = bx.const_i32(index as i32);
|
let cond_index = bx.const_i32(index as i32);
|
||||||
|
@ -194,7 +185,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
|
CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
|
||||||
drop(coverage_map);
|
drop(coverage_map);
|
||||||
let cond_bitmap = coverage_context
|
let cond_bitmap = bx.coverage_cx()
|
||||||
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
|
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
|
||||||
.expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
|
.expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
|
||||||
assert!(
|
assert!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue