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::mir::operand::{OperandRef, OperandValue};
|
||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
use rustc_codegen_ssa::mir::FunctionCx;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
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> {
|
||||
fn codegen_intrinsic_call<'b, Bx: BuilderMethods<'b, 'tcx>>(
|
||||
fn codegen_intrinsic_call(
|
||||
&mut self,
|
||||
fx: &FunctionCx<'b, 'tcx, Bx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
args: &[OperandRef<'tcx, &'ll Value>],
|
||||
llresult: &'ll Value,
|
||||
span: Span,
|
||||
caller_instance: ty::Instance<'tcx>,
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let callee_ty = instance.monomorphic_ty(tcx);
|
||||
|
@ -141,8 +140,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
self.call(llfn, &[], None)
|
||||
}
|
||||
"count_code_region" => {
|
||||
let coverage_data = fx.mir.coverage_data.as_ref().unwrap();
|
||||
let mangled_fn = tcx.symbol_name(fx.instance);
|
||||
let coverage_data = tcx
|
||||
.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 hash = self.const_u64(coverage_data.hash);
|
||||
let index = args[0].immediate();
|
||||
|
|
|
@ -688,12 +688,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
.collect();
|
||||
|
||||
bx.codegen_intrinsic_call(
|
||||
self,
|
||||
*instance.as_ref().unwrap(),
|
||||
&fn_abi,
|
||||
&args,
|
||||
dest,
|
||||
terminator.source_info.span,
|
||||
self.instance,
|
||||
);
|
||||
|
||||
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
|
||||
|
|
|
@ -21,9 +21,9 @@ use self::operand::{OperandRef, OperandValue};
|
|||
|
||||
/// Master context for codegenning from MIR.
|
||||
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>>,
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use super::BackendTypes;
|
||||
use crate::mir::operand::OperandRef;
|
||||
use crate::mir::FunctionCx;
|
||||
use crate::traits::BuilderMethods;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
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,
|
||||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
||||
/// add them to librustc_codegen_llvm/context.rs
|
||||
fn codegen_intrinsic_call<'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
fn codegen_intrinsic_call(
|
||||
&mut self,
|
||||
fx: &FunctionCx<'a, 'tcx, Bx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
args: &[OperandRef<'tcx, Self::Value>],
|
||||
llresult: Self::Value,
|
||||
span: Span,
|
||||
caller_instance: ty::Instance<'tcx>,
|
||||
);
|
||||
|
||||
fn abort(&mut self);
|
||||
|
|
|
@ -214,6 +214,12 @@ rustc_queries! {
|
|||
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>> {
|
||||
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
|
||||
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_index::vec::IndexVec;
|
||||
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::steal::Steal;
|
||||
use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
|
||||
|
@ -53,6 +53,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
|
|||
mir_drops_elaborated_and_const_checked,
|
||||
optimized_mir,
|
||||
is_mir_available,
|
||||
coverage_data,
|
||||
promoted_mir,
|
||||
..*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<'_> {
|
||||
if tcx.is_constructor(def_id) {
|
||||
// There's no reason to run all of the MIR passes on constructors when
|
||||
|
|
Loading…
Reference in a new issue