Skip to content
12 changes: 7 additions & 5 deletions src/librustc_codegen_llvm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_ssa/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>,

Expand Down
6 changes: 2 additions & 4 deletions src/librustc_codegen_ssa/traits/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_middle/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>)
Expand Down
8 changes: 7 additions & 1 deletion src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
};
Expand Down Expand Up @@ -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
Expand Down