Add case for count_code_region() extern lang_item

As suggested in PR feedback:

https://github.com/rust-lang/rust/pull/73011#discussion_r435728923

This allows count_code_region() to be handled like a normal intrinsic so
the InstanceDef::InjectedCode variant is no longer needed.
This commit is contained in:
Rich Kadel 2020-06-05 09:14:45 -07:00
parent 2c5c2a6bc2
commit d2cd59a031
13 changed files with 27 additions and 54 deletions

View File

@ -1941,22 +1941,13 @@ extern "rust-intrinsic" {
///
/// Perma-unstable: do not use.
pub fn miri_start_panic(payload: *mut u8) -> !;
}
/// Defines the `count_code_region` intrinsic as a `LangItem`. `LangItem`s require a function body
/// to register its DefId with the LangItem entry. The function body is never actually called (and
/// is therefore implemented as an aborting stub) because it is replaced with the LLVM intrinsic
/// `llvm.instrprof.increment` by
/// `rustc_codegen_llvm::intrinsic::IntrinsicCallMethods::codegen_intrinsic_call()`.
#[cfg(not(bootstrap))]
#[cfg_attr(not(bootstrap), lang = "count_code_region")]
fn count_code_region(_index: u32) {
// remove `unsafe` (and safety comment) on bootstrap bump
#[cfg_attr(not(bootstrap), allow(unused_unsafe))]
// SAFETY: the `abort` intrinsic has no requirements to be called.
unsafe {
abort()
}
/// Internal placeholder for injecting code coverage counters when the "instrument-coverage"
/// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code
/// generation.
#[cfg(not(bootstrap))]
#[cfg_attr(not(bootstrap), lang = "count_code_region")]
pub fn count_code_region(_index: u32);
}
// Some functions are defined here because they accidentally got made

View File

@ -566,10 +566,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Handle intrinsics old codegen wants Expr's for, ourselves.
let intrinsic = match def {
Some(ty::InstanceDef::Intrinsic(def_id))
| Some(ty::InstanceDef::InjectedCode(def_id)) => {
Some(bx.tcx().item_name(def_id).as_str())
}
Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id).as_str()),
_ => None,
};
let intrinsic = intrinsic.as_ref().map(|s| &s[..]);

View File

@ -352,7 +352,6 @@ impl<'tcx> CodegenUnit<'tcx> {
InstanceDef::VtableShim(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::Intrinsic(..)
| InstanceDef::InjectedCode(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::ClosureOnceShim { .. }

View File

@ -21,10 +21,6 @@ pub enum InstanceDef<'tcx> {
Item(DefId),
Intrinsic(DefId),
/// Injected call to a placeholder function that is replaced with
/// For example: `core::intrinsic::count_code_region()` for code coverage.
InjectedCode(DefId),
/// `<T as Trait>::method` where `method` receives unsizeable `self: Self`.
VtableShim(DefId),
@ -153,7 +149,6 @@ impl<'tcx> InstanceDef<'tcx> {
| InstanceDef::FnPtrShim(def_id, _)
| InstanceDef::Virtual(def_id, _)
| InstanceDef::Intrinsic(def_id)
| InstanceDef::InjectedCode(def_id)
| InstanceDef::ClosureOnceShim { call_once: def_id }
| InstanceDef::DropGlue(def_id, _)
| InstanceDef::CloneShim(def_id, _) => def_id,
@ -241,7 +236,6 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"),
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
InstanceDef::InjectedCode(_) => write!(f, " - injected-code"),
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({:?})", ty),
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
@ -421,7 +415,6 @@ impl<'tcx> Instance<'tcx> {
| InstanceDef::FnPtrShim(..)
| InstanceDef::Item(_)
| InstanceDef::Intrinsic(..)
| InstanceDef::InjectedCode(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::VtableShim(..) => Some(self.substs),

View File

@ -2717,7 +2717,6 @@ impl<'tcx> TyCtxt<'tcx> {
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::Intrinsic(..)
| ty::InstanceDef::InjectedCode(..)
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::ClosureOnceShim { .. }

View File

@ -674,7 +674,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)),
ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
ty::InstanceDef::InjectedCode(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
ty::InstanceDef::FnPtrShim(def_id, ref ty) => {
Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
}
@ -847,7 +846,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
VtableShim(did) => VtableShim(did.fold_with(folder)),
ReifyShim(did) => ReifyShim(did.fold_with(folder)),
Intrinsic(did) => Intrinsic(did.fold_with(folder)),
InjectedCode(did) => InjectedCode(did.fold_with(folder)),
FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
Virtual(did, i) => Virtual(did.fold_with(folder), i),
ClosureOnceShim { call_once } => {
@ -863,12 +861,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
use crate::ty::InstanceDef::*;
self.substs.visit_with(visitor)
|| match self.def {
Item(did)
| VtableShim(did)
| ReifyShim(did)
| Intrinsic(did)
| InjectedCode(did)
| Virtual(did, _) => did.visit_with(visitor),
Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
did.visit_with(visitor)
}
FnPtrShim(did, ty) | CloneShim(did, ty) => {
did.visit_with(visitor) || ty.visit_with(visitor)
}

View File

@ -257,9 +257,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
M::call_intrinsic(self, instance, args, ret, unwind)
}
ty::InstanceDef::InjectedCode(..) => {
M::call_intrinsic(self, instance, args, ret, unwind)
}
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }

View File

@ -714,9 +714,7 @@ fn visit_instance_use<'tcx>(
}
match instance.def {
ty::InstanceDef::Virtual(..)
| ty::InstanceDef::Intrinsic(_)
| ty::InstanceDef::InjectedCode(_) => {
ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => {
if !is_direct_call {
bug!("{:?} being reified", instance);
}
@ -753,7 +751,6 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Intrinsic(_)
| ty::InstanceDef::InjectedCode(_)
| ty::InstanceDef::CloneShim(..) => return true,
};

View File

@ -322,7 +322,6 @@ fn mono_item_visibility(
| InstanceDef::FnPtrShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::Intrinsic(..)
| InstanceDef::InjectedCode(..)
| InstanceDef::ClosureOnceShim { .. }
| InstanceDef::DropGlue(..)
| InstanceDef::CloneShim(..) => return Visibility::Hidden,
@ -718,7 +717,6 @@ fn characteristic_def_id_of_mono_item<'tcx>(
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::Intrinsic(..)
| ty::InstanceDef::InjectedCode(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::CloneShim(..) => return None,

View File

@ -109,9 +109,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
ty::InstanceDef::Intrinsic(_) => {
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
}
ty::InstanceDef::InjectedCode(_) => {
bug!("creating shims from injected code ({:?}) is unsupported", instance)
}
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);

View File

@ -5,10 +5,12 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::lang_items;
use rustc_hir::lang_items::ITEM_REFS;
use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
use rustc_middle::middle::lang_items::whitelisted;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::CrateType;
use rustc_span::symbol::sym;
use rustc_span::symbol::Symbol;
use rustc_span::Span;
@ -70,11 +72,21 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
}
impl<'a, 'tcx> Context<'a, 'tcx> {
fn register(&mut self, name: Symbol, span: Span) {
fn register(&mut self, name: Symbol, span: Span, hir_id: hir::HirId) {
if let Some(&item) = WEAK_ITEMS_REFS.get(&name) {
if self.items.require(item).is_err() {
self.items.missing.push(item);
}
} else if name == sym::count_code_region {
// `core::intrinsics::code_count_region()` is (currently) the only `extern` lang item
// that is never actually linked. It is not a `weak_lang_item` that can be registered
// when used, and should be registered here instead.
if let Some((item_index, _)) = ITEM_REFS.get(&*name.as_str()).cloned() {
if self.items.items[item_index].is_none() {
let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
self.items.items[item_index] = Some(item_def_id);
}
}
} else {
struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name)
.emit();
@ -91,7 +103,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
if let Some((lang_item, _)) = hir::lang_items::extract(&i.attrs) {
self.register(lang_item, i.span);
self.register(lang_item, i.span, i.hir_id);
}
intravisit::walk_foreign_item(self, i)
}

View File

@ -35,10 +35,6 @@ fn resolve_instance<'tcx>(
debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def_id)
}
ty::FnDef(def_id, _) if Some(def_id) == tcx.lang_items().count_code_region_fn() => {
debug!(" => injected placeholder function to be replaced");
ty::InstanceDef::InjectedCode(def_id)
}
ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
let ty = substs.type_at(0);

View File

@ -347,6 +347,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
return;
}
"count_code_region" => (0, vec![tcx.types.u32], tcx.mk_unit()),
ref other => {
struct_span_err!(
tcx.sess,