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 gccjit::RValue;
|
||||||
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods};
|
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::coverage::{
|
use rustc_middle::mir::Coverage;
|
||||||
CodeRegion,
|
|
||||||
CounterValueReference,
|
|
||||||
ExpressionOperandId,
|
|
||||||
InjectedExpressionId,
|
|
||||||
Op,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
|
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
|
|
||||||
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
fn set_function_source_hash(
|
fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
|
||||||
&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 {
|
|
||||||
// TODO(antoyo)
|
// 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_llvm::RustString;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::coverage::{
|
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;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::subst::InternalSubsts;
|
||||||
use rustc_middle::ty::Instance;
|
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> {
|
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(
|
fn set_function_source_hash(
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: Instance<'tcx>,
|
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(
|
fn add_coverage_counter(
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: Instance<'tcx>,
|
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(
|
fn add_coverage_counter_expression(
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: Instance<'tcx>,
|
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 {
|
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool {
|
||||||
if let Some(coverage_context) = self.coverage_context() {
|
if let Some(coverage_context) = self.coverage_context() {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
|
|
||||||
use rustc_middle::mir::coverage::*;
|
|
||||||
use rustc_middle::mir::Coverage;
|
use rustc_middle::mir::Coverage;
|
||||||
use rustc_middle::mir::SourceScope;
|
use rustc_middle::mir::SourceScope;
|
||||||
|
|
||||||
use super::FunctionCx;
|
use super::FunctionCx;
|
||||||
|
|
||||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
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.
|
// Determine the instance that coverage data was originally generated for.
|
||||||
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
|
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
|
||||||
self.monomorphize(inlined)
|
self.monomorphize(inlined)
|
||||||
|
@ -15,41 +14,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
self.instance
|
self.instance
|
||||||
};
|
};
|
||||||
|
|
||||||
let Coverage { kind, code_region } = coverage;
|
// Handle the coverage info in a backend-specific way.
|
||||||
match kind {
|
bx.add_coverage(instance, coverage);
|
||||||
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"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::StatementKind::Coverage(box ref coverage) => {
|
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)) => {
|
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
|
||||||
let op_val = self.codegen_operand(bx, op);
|
let op_val = self.codegen_operand(bx, op);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::BackendTypes;
|
use super::BackendTypes;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::coverage::*;
|
use rustc_middle::mir::Coverage;
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
|
|
||||||
pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
||||||
|
@ -21,37 +21,9 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
||||||
/// Returns true if the function source hash was added to the coverage map (even if it had
|
/// Handle the MIR coverage info in a backend-specific way.
|
||||||
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
|
///
|
||||||
/// not enabled (a coverage map is not being generated).
|
/// This can potentially be a no-op in backends that don't support
|
||||||
fn set_function_source_hash(
|
/// coverage instrumentation.
|
||||||
&mut self,
|
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue