implemented query for coverage data
This commit adds a query that allows the CoverageData to be pulled from a call on tcx, avoiding the need to change the `codegen_intrinsic_call()` signature (no need to pass in the FunctionCx or any additional arguments. The commit does not change where/when the CoverageData is computed. It's still done in the `pass`, and saved in the MIR `Body`. See discussion (in progress) here: https://github.com/rust-lang/rust/pull/73488#discussion_r443825646
This commit is contained in:
parent
933fe80577
commit
f4a79385cf
6 changed files with 25 additions and 13 deletions
|
@ -16,7 +16,6 @@ use rustc_codegen_ssa::common::TypeKind;
|
||||||
use rustc_codegen_ssa::glue;
|
use rustc_codegen_ssa::glue;
|
||||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||||
use rustc_codegen_ssa::mir::FunctionCx;
|
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_codegen_ssa::MemFlags;
|
use rustc_codegen_ssa::MemFlags;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -82,14 +81,14 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
fn codegen_intrinsic_call<'b, Bx: BuilderMethods<'b, 'tcx>>(
|
fn codegen_intrinsic_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
fx: &FunctionCx<'b, 'tcx, Bx>,
|
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||||
args: &[OperandRef<'tcx, &'ll Value>],
|
args: &[OperandRef<'tcx, &'ll Value>],
|
||||||
llresult: &'ll Value,
|
llresult: &'ll Value,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
caller_instance: ty::Instance<'tcx>,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let callee_ty = instance.monomorphic_ty(tcx);
|
let callee_ty = instance.monomorphic_ty(tcx);
|
||||||
|
@ -141,8 +140,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
self.call(llfn, &[], None)
|
self.call(llfn, &[], None)
|
||||||
}
|
}
|
||||||
"count_code_region" => {
|
"count_code_region" => {
|
||||||
let coverage_data = fx.mir.coverage_data.as_ref().unwrap();
|
let coverage_data = tcx
|
||||||
let mangled_fn = tcx.symbol_name(fx.instance);
|
.coverage_data(caller_instance.def_id())
|
||||||
|
.as_ref()
|
||||||
|
.expect("LLVM intrinsic count_code_region call has associated coverage_data");
|
||||||
|
let mangled_fn = tcx.symbol_name(caller_instance);
|
||||||
let (mangled_fn_name, _len_val) = self.const_str(mangled_fn.name);
|
let (mangled_fn_name, _len_val) = self.const_str(mangled_fn.name);
|
||||||
let hash = self.const_u64(coverage_data.hash);
|
let hash = self.const_u64(coverage_data.hash);
|
||||||
let index = args[0].immediate();
|
let index = args[0].immediate();
|
||||||
|
|
|
@ -688,12 +688,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
bx.codegen_intrinsic_call(
|
bx.codegen_intrinsic_call(
|
||||||
self,
|
|
||||||
*instance.as_ref().unwrap(),
|
*instance.as_ref().unwrap(),
|
||||||
&fn_abi,
|
&fn_abi,
|
||||||
&args,
|
&args,
|
||||||
dest,
|
dest,
|
||||||
terminator.source_info.span,
|
terminator.source_info.span,
|
||||||
|
self.instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
|
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
|
||||||
|
|
|
@ -21,9 +21,9 @@ use self::operand::{OperandRef, OperandValue};
|
||||||
|
|
||||||
/// Master context for codegenning from MIR.
|
/// Master context for codegenning from MIR.
|
||||||
pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
||||||
pub instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
|
|
||||||
pub mir: &'tcx mir::Body<'tcx>,
|
mir: &'tcx mir::Body<'tcx>,
|
||||||
|
|
||||||
debug_context: Option<FunctionDebugContext<Bx::DIScope>>,
|
debug_context: Option<FunctionDebugContext<Bx::DIScope>>,
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::BackendTypes;
|
use super::BackendTypes;
|
||||||
use crate::mir::operand::OperandRef;
|
use crate::mir::operand::OperandRef;
|
||||||
use crate::mir::FunctionCx;
|
|
||||||
use crate::traits::BuilderMethods;
|
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::call::FnAbi;
|
use rustc_target::abi::call::FnAbi;
|
||||||
|
@ -10,14 +8,14 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
|
||||||
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
|
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
|
||||||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
||||||
/// add them to librustc_codegen_llvm/context.rs
|
/// add them to librustc_codegen_llvm/context.rs
|
||||||
fn codegen_intrinsic_call<'a, Bx: BuilderMethods<'a, 'tcx>>(
|
fn codegen_intrinsic_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
fx: &FunctionCx<'a, 'tcx, Bx>,
|
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||||
args: &[OperandRef<'tcx, Self::Value>],
|
args: &[OperandRef<'tcx, Self::Value>],
|
||||||
llresult: Self::Value,
|
llresult: Self::Value,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
caller_instance: ty::Instance<'tcx>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn abort(&mut self);
|
fn abort(&mut self);
|
||||||
|
|
|
@ -214,6 +214,12 @@ rustc_queries! {
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query coverage_data(key: DefId) -> Option<mir::CoverageData> {
|
||||||
|
desc { |tcx| "retrieving coverage data, if computed from MIR for `{}`", tcx.def_path_str(key) }
|
||||||
|
storage(ArenaCacheSelector<'tcx>)
|
||||||
|
cache_on_disk_if { key.is_local() }
|
||||||
|
}
|
||||||
|
|
||||||
query promoted_mir(key: DefId) -> IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
query promoted_mir(key: DefId) -> IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
||||||
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
|
||||||
storage(ArenaCacheSelector<'tcx>)
|
storage(ArenaCacheSelector<'tcx>)
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::mir::visit::Visitor as _;
|
use rustc_middle::mir::visit::Visitor as _;
|
||||||
use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
|
use rustc_middle::mir::{traversal, Body, ConstQualifs, CoverageData, MirPhase, Promoted};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::steal::Steal;
|
use rustc_middle::ty::steal::Steal;
|
||||||
use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
|
||||||
|
@ -53,6 +53,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
|
||||||
mir_drops_elaborated_and_const_checked,
|
mir_drops_elaborated_and_const_checked,
|
||||||
optimized_mir,
|
optimized_mir,
|
||||||
is_mir_available,
|
is_mir_available,
|
||||||
|
coverage_data,
|
||||||
promoted_mir,
|
promoted_mir,
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
|
@ -422,6 +423,11 @@ fn run_optimization_passes<'tcx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn coverage_data(tcx: TyCtxt<'_>, def_id: DefId) -> Option<CoverageData> {
|
||||||
|
let body = tcx.optimized_mir(def_id);
|
||||||
|
body.coverage_data.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
|
fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
|
||||||
if tcx.is_constructor(def_id) {
|
if tcx.is_constructor(def_id) {
|
||||||
// There's no reason to run all of the MIR passes on constructors when
|
// There's no reason to run all of the MIR passes on constructors when
|
||||||
|
|
Loading…
Reference in a new issue