Skip to content

Commit

Permalink
-Z call-metadata: add call metadata to LLVM IR
Browse files Browse the repository at this point in the history
this implements eRFC rust-lang#59412
  • Loading branch information
japaric committed Apr 7, 2019
1 parent 11510b2 commit 4701025
Show file tree
Hide file tree
Showing 20 changed files with 705 additions and 102 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2597,6 +2597,7 @@ dependencies = [
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_llvm 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down
24 changes: 24 additions & 0 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T
}
}

impl<'a, 'tcx> ToStableHashKey<StableHashingContext<'a>> for ty::Instance<'tcx> {
type KeyType = Fingerprint;

#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
let mut hasher = StableHasher::new();
let mut hcx: StableHashingContext<'a> = hcx.clone();
self.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
}
}

impl<'a, 'tcx> ToStableHashKey<StableHashingContext<'a>> for ty::ExistentialTraitRef<'tcx> {
type KeyType = Fingerprint;

#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
let mut hasher = StableHasher::new();
let mut hcx: StableHashingContext<'a> = hcx.clone();
self.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
Expand Down
27 changes: 25 additions & 2 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,8 +861,13 @@ rustc_queries! {
}

Codegen {
query collect_and_partition_mono_items(_: CrateNum)
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>) {
query collect_and_partition_mono_items(_: CrateNum) -> (
Arc<DefIdSet>,
Arc<Vec<Arc<CodegenUnit<'tcx>>>>,
Arc<FxHashSet<ty::Instance<'tcx>>>,
Arc<FxHashSet<ty::Instance<'tcx>>>,
Arc<FxHashMap<ty::Instance<'tcx>, Arc<FxHashSet<ty::ExistentialTraitRef<'tcx>>>>>
) {
eval_always
desc { "collect_and_partition_mono_items" }
}
Expand All @@ -874,6 +879,24 @@ rustc_queries! {
query backend_optimization_level(_: CrateNum) -> OptLevel {
desc { "optimization level used by backend" }
}

// -Z call-metadata
// functions that may be called via a function pointer
query function_pointer(instance: ty::Instance<'tcx>) -> bool {
no_force
desc { "checking if `{}` may be called via a function pointer", instance }
}

// trait methods that may be called via dynamic dispatch
query dynamic_dispatch(instance: ty::Instance<'tcx>) -> bool {
no_force
desc { "checking if `{}` may be called via dynamic dispatch", instance }
}

query drop_glue(instance: ty::Instance<'tcx>) -> Option<Arc<FxHashSet<ty::ExistentialTraitRef<'tcx>>>> {
no_force
desc { "checking if `{}` may be called by a trait object destructor", instance }
}
}

Other {
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
the same values as the target option of the same name"),
allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
"only allow the listed language features to be enabled in code (space separated)"),
call_metadata: bool = (false, parse_bool, [UNTRACKED],
"adds call metadata to LLVM IR"),
}

pub fn default_lib_output() -> CrateType {
Expand Down
37 changes: 35 additions & 2 deletions src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::hir::Unsafety;
use crate::hir::def::Namespace;
use crate::hir::def::{Def, Namespace};
use crate::hir::def_id::DefId;
use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
use crate::ty::{self, AssociatedItemContainer, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
use crate::ty::print::{FmtPrinter, Printer};
use crate::traits;
use rustc_target::spec::abi::Abi;
use rustc_macros::HashStable;
use syntax::symbol::Symbol;

use std::fmt;
use std::iter;
Expand Down Expand Up @@ -54,6 +55,38 @@ impl<'a, 'tcx> Instance<'tcx> {
)
}

pub fn trait_ref_and_method(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
) -> Option<(ty::ExistentialTraitRef<'tcx>, Symbol)> {
let def_id = self.def_id();
if let Some(Def::Method(..)) = tcx.describe_def(def_id) {
let item = tcx.associated_item(def_id);

let trait_ref = match item.container {
AssociatedItemContainer::TraitContainer(trait_def_id) => {
ty::TraitRef::from_method(tcx, trait_def_id, self.substs)
}

AssociatedItemContainer::ImplContainer(impl_def_id) => {
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
trait_ref
} else {
// inherent method
return None;
}
}
};

Some((
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
item.ident.name,
))
} else {
None
}
}

fn fn_sig_noadjust(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> PolyFnSig<'tcx> {
let ty = self.ty(tcx);
match ty.sty {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ num_cpus = "1.0"
rustc-demangle = "0.1.4"
rustc_llvm = { path = "../librustc_llvm" }
memmap = "0.6"
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }

[features]
# This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm`
Expand Down
25 changes: 22 additions & 3 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::llvm::{self, AttributePlace};
use crate::builder::Builder;
use crate::common;
use crate::context::CodegenCx;
use crate::type_::Type;
use crate::type_of::{LayoutLlvmExt, PointerKind};
use crate::value::Value;
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::{CallKind, MemFlags};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::mir::operand::OperandValue;
use rustc_target::abi::call::ArgType;
Expand Down Expand Up @@ -856,9 +857,27 @@ impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn apply_attrs_callsite(
&mut self,
ty: &FnType<'tcx, Ty<'tcx>>,
callsite: Self::Value
callsite: Self::Value,
call_kind: CallKind<'tcx>,
) {
ty.apply_attrs_callsite(self, callsite)
ty.apply_attrs_callsite(self, callsite);

match call_kind {
// no extra metadata
CallKind::Direct => {}

CallKind::FnPtr => {
common::add_callsite_fn_metadata(self.cx, ty, callsite)
}

CallKind::DynamicDispatch(trait_ref, method) => {
common::add_callsite_dyn_metadata(self.cx, trait_ref, method, callsite)
}

CallKind::DropGlue(trait_ref) => {
common::add_callsite_drop_metadata(self.cx, trait_ref, callsite)
}
}
}

fn get_param(&self, index: usize) -> Self::Value {
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_codegen_llvm/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! closure.
use crate::attributes;
use crate::common;
use crate::llvm;
use crate::monomorphize::Instance;
use crate::context::CodegenCx;
Expand All @@ -16,7 +17,7 @@ use rustc::ty::layout::{LayoutOf, HasTyCtxt};

/// Codegens a reference to a fn/method item, monomorphizing and
/// inlining as it goes.
///
//
/// # Parameters
///
/// - `cx`: the crate context
Expand Down Expand Up @@ -188,5 +189,11 @@ pub fn get_fn(

cx.instances.borrow_mut().insert(instance, llfn);

common::add_define_metadata(
cx,
instance,
llfn,
);

llfn
}
Loading

0 comments on commit 4701025

Please sign in to comment.