Narrow trait CoverageInfoBuilderMethods
down to just one method
This effectively inlines most of `FunctionCx::codegen_coverage` into the LLVM implementation of `CoverageInfoBuilderMethods`.
This commit is contained in:
parent
6dab6dc5fc
commit
4169d0f756
5 changed files with 69 additions and 102 deletions
|
@ -1,40 +1,15 @@
|
|||
use gccjit::RValue;
|
||||
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::coverage::{
|
||||
CodeRegion,
|
||||
CounterValueReference,
|
||||
ExpressionOperandId,
|
||||
InjectedExpressionId,
|
||||
Op,
|
||||
};
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
|
||||
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
fn set_function_source_hash(
|
||||
&mut self,
|
||||
_instance: Instance<'tcx>,
|
||||
_function_source_hash: u64,
|
||||
) -> bool {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_coverage_counter(&mut self, _instance: Instance<'tcx>, _id: CounterValueReference, _region: CodeRegion) -> bool {
|
||||
fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
|
||||
// TODO(antoyo)
|
||||
false
|
||||
}
|
||||
|
||||
fn add_coverage_counter_expression(&mut self, _instance: Instance<'tcx>, _id: InjectedExpressionId, _lhs: ExpressionOperandId, _op: Op, _rhs: ExpressionOperandId, _region: Option<CodeRegion>) -> bool {
|
||||
// TODO(antoyo)
|
||||
false
|
||||
}
|
||||
|
||||
fn add_coverage_unreachable(&mut self, _instance: Instance<'tcx>, _region: CodeRegion) -> bool {
|
||||
// TODO(antoyo)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_llvm::RustString;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::coverage::{
|
||||
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
|
||||
CodeRegion, CounterValueReference, CoverageKind, ExpressionOperandId, InjectedExpressionId, Op,
|
||||
};
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
|
@ -94,6 +95,54 @@ impl<'ll, 'tcx> CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage) {
|
||||
let bx = self;
|
||||
|
||||
let Coverage { kind, code_region } = coverage.clone();
|
||||
match kind {
|
||||
CoverageKind::Counter { function_source_hash, id } => {
|
||||
if bx.set_function_source_hash(instance, function_source_hash) {
|
||||
// If `set_function_source_hash()` returned true, the coverage map is enabled,
|
||||
// so continue adding the counter.
|
||||
if let Some(code_region) = code_region {
|
||||
// Note: Some counters do not have code regions, but may still be referenced
|
||||
// from expressions. In that case, don't add the counter to the coverage map,
|
||||
// but do inject the counter intrinsic.
|
||||
bx.add_coverage_counter(instance, id, code_region);
|
||||
}
|
||||
|
||||
let coverageinfo = bx.tcx().coverageinfo(instance.def);
|
||||
|
||||
let fn_name = bx.get_pgo_func_name_var(instance);
|
||||
let hash = bx.const_u64(function_source_hash);
|
||||
let num_counters = bx.const_u32(coverageinfo.num_counters);
|
||||
let index = bx.const_u32(id.zero_based_index());
|
||||
debug!(
|
||||
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
|
||||
fn_name, hash, num_counters, index,
|
||||
);
|
||||
bx.instrprof_increment(fn_name, hash, num_counters, index);
|
||||
}
|
||||
}
|
||||
CoverageKind::Expression { id, lhs, op, rhs } => {
|
||||
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
|
||||
}
|
||||
CoverageKind::Unreachable => {
|
||||
bx.add_coverage_unreachable(
|
||||
instance,
|
||||
code_region.expect("unreachable regions always have code regions"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These methods used to be part of trait `CoverageInfoBuilderMethods`, but
|
||||
// after moving most coverage code out of SSA they are now just ordinary methods.
|
||||
impl<'tcx> Builder<'_, '_, 'tcx> {
|
||||
/// Returns true if the function source hash was added to the coverage map (even if it had
|
||||
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
|
||||
/// not enabled (a coverage map is not being generated).
|
||||
fn set_function_source_hash(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
|
@ -115,6 +164,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
|
||||
/// is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_counter(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
|
@ -137,6 +188,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if the expression was added to the coverage map; false if
|
||||
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_counter_expression(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
|
@ -163,6 +216,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
|
||||
/// is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool {
|
||||
if let Some(coverage_context) = self.coverage_context() {
|
||||
debug!(
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use crate::traits::*;
|
||||
|
||||
use rustc_middle::mir::coverage::*;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::mir::SourceScope;
|
||||
|
||||
use super::FunctionCx;
|
||||
|
||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceScope) {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: &Coverage, scope: SourceScope) {
|
||||
// Determine the instance that coverage data was originally generated for.
|
||||
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
|
||||
self.monomorphize(inlined)
|
||||
|
@ -15,41 +14,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
self.instance
|
||||
};
|
||||
|
||||
let Coverage { kind, code_region } = coverage;
|
||||
match kind {
|
||||
CoverageKind::Counter { function_source_hash, id } => {
|
||||
if bx.set_function_source_hash(instance, function_source_hash) {
|
||||
// If `set_function_source_hash()` returned true, the coverage map is enabled,
|
||||
// so continue adding the counter.
|
||||
if let Some(code_region) = code_region {
|
||||
// Note: Some counters do not have code regions, but may still be referenced
|
||||
// from expressions. In that case, don't add the counter to the coverage map,
|
||||
// but do inject the counter intrinsic.
|
||||
bx.add_coverage_counter(instance, id, code_region);
|
||||
}
|
||||
|
||||
let coverageinfo = bx.tcx().coverageinfo(instance.def);
|
||||
|
||||
let fn_name = bx.get_pgo_func_name_var(instance);
|
||||
let hash = bx.const_u64(function_source_hash);
|
||||
let num_counters = bx.const_u32(coverageinfo.num_counters);
|
||||
let index = bx.const_u32(id.zero_based_index());
|
||||
debug!(
|
||||
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
|
||||
fn_name, hash, num_counters, index,
|
||||
);
|
||||
bx.instrprof_increment(fn_name, hash, num_counters, index);
|
||||
}
|
||||
}
|
||||
CoverageKind::Expression { id, lhs, op, rhs } => {
|
||||
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
|
||||
}
|
||||
CoverageKind::Unreachable => {
|
||||
bx.add_coverage_unreachable(
|
||||
instance,
|
||||
code_region.expect("unreachable regions always have code regions"),
|
||||
);
|
||||
}
|
||||
}
|
||||
// Handle the coverage info in a backend-specific way.
|
||||
bx.add_coverage(instance, coverage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
}
|
||||
mir::StatementKind::Coverage(box ref coverage) => {
|
||||
self.codegen_coverage(bx, coverage.clone(), statement.source_info.scope);
|
||||
self.codegen_coverage(bx, coverage, statement.source_info.scope);
|
||||
}
|
||||
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
|
||||
let op_val = self.codegen_operand(bx, op);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::BackendTypes;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::coverage::*;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
||||
|
@ -21,37 +21,9 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
|||
}
|
||||
|
||||
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
||||
/// Returns true if the function source hash was added to the coverage map (even if it had
|
||||
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
|
||||
/// not enabled (a coverage map is not being generated).
|
||||
fn set_function_source_hash(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
function_source_hash: u64,
|
||||
) -> bool;
|
||||
|
||||
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
|
||||
/// is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_counter(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
index: CounterValueReference,
|
||||
region: CodeRegion,
|
||||
) -> bool;
|
||||
|
||||
/// Returns true if the expression was added to the coverage map; false if
|
||||
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_counter_expression(
|
||||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
id: InjectedExpressionId,
|
||||
lhs: ExpressionOperandId,
|
||||
op: Op,
|
||||
rhs: ExpressionOperandId,
|
||||
region: Option<CodeRegion>,
|
||||
) -> bool;
|
||||
|
||||
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
|
||||
/// is not enabled (a coverage map is not being generated).
|
||||
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool;
|
||||
/// Handle the MIR coverage info in a backend-specific way.
|
||||
///
|
||||
/// This can potentially be a no-op in backends that don't support
|
||||
/// coverage instrumentation.
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue