introduce is_foreign_item
query
This may seem like overkill, but it's exactly what we want/need for incremental compilation I think. In particular, while generating code for some codegen unit X, we can wind up querying about any number of external items, and we only want to be forced to rebuild X is some of those changed from a foreign item to otherwise. Factoring this into a query means we would re-run only if some `false` became `true` (or vice versa).
This commit is contained in:
parent
1785bca513
commit
8289e5a73e
5 changed files with 30 additions and 10 deletions
|
@ -88,6 +88,7 @@ pub enum DepNode<D: Clone + Debug> {
|
|||
// predicates for an item wind up in `ItemSignature`).
|
||||
AssociatedItems(D),
|
||||
ItemSignature(D),
|
||||
IsForeignItem(D),
|
||||
TypeParamPredicates((D, D)),
|
||||
SizedConstraint(D),
|
||||
AdtDestructor(D),
|
||||
|
@ -171,6 +172,7 @@ impl<D: Clone + Debug> DepNode<D> {
|
|||
TransCrateItem,
|
||||
AssociatedItems,
|
||||
ItemSignature,
|
||||
IsForeignItem,
|
||||
AssociatedItemDefIds,
|
||||
InherentImpls,
|
||||
TypeckTables,
|
||||
|
@ -221,6 +223,7 @@ impl<D: Clone + Debug> DepNode<D> {
|
|||
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
|
||||
AssociatedItems(ref d) => op(d).map(AssociatedItems),
|
||||
ItemSignature(ref d) => op(d).map(ItemSignature),
|
||||
IsForeignItem(ref d) => op(d).map(IsForeignItem),
|
||||
TypeParamPredicates((ref item, ref param)) => {
|
||||
Some(TypeParamPredicates((try_opt!(op(item)), try_opt!(op(param)))))
|
||||
}
|
||||
|
|
|
@ -380,6 +380,9 @@ define_maps! { <'tcx>
|
|||
pub adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
|
||||
pub adt_sized_constraint: SizedConstraint(DefId) -> Ty<'tcx>,
|
||||
|
||||
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
|
||||
pub is_foreign_item: IsForeignItem(DefId) -> bool,
|
||||
|
||||
/// Maps from def-id of a type or region parameter to its
|
||||
/// (inferred) variance.
|
||||
pub variances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>>,
|
||||
|
|
|
@ -111,6 +111,7 @@ provide! { <'tcx> tcx, def_id, cdata
|
|||
closure_kind => { cdata.closure_kind(def_id.index) }
|
||||
closure_type => { cdata.closure_ty(def_id.index, tcx) }
|
||||
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
|
||||
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
|
||||
}
|
||||
|
||||
impl CrateStore for cstore::CStore {
|
||||
|
|
|
@ -14,18 +14,18 @@
|
|||
//! and methods are represented as just a fn ptr and not a full
|
||||
//! closure.
|
||||
|
||||
use llvm::{self, ValueRef};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::subst::Substs;
|
||||
use attributes;
|
||||
use common::{self, CrateContext};
|
||||
use monomorphize;
|
||||
use consts;
|
||||
use declare;
|
||||
use monomorphize::Instance;
|
||||
use llvm::{self, ValueRef};
|
||||
use monomorphize::{self, Instance};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, TypeFoldable};
|
||||
use rustc::ty::subst::Substs;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use trans_item::TransItem;
|
||||
use type_of;
|
||||
use rustc::ty::TypeFoldable;
|
||||
|
||||
/// Translates a reference to a fn/method item, monomorphizing and
|
||||
/// inlining as it goes.
|
||||
|
@ -102,15 +102,17 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
let attrs = instance.def.attrs(ccx.tcx());
|
||||
attributes::from_fn_attrs(ccx, &attrs, llfn);
|
||||
|
||||
let is_local_def = ccx.shared().translation_items().borrow()
|
||||
.contains(&TransItem::Fn(instance));
|
||||
if is_local_def {
|
||||
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
|
||||
// Perhaps questionable, but we assume that anything defined
|
||||
// *in Rust code* may unwind. Foreign items like `extern "C" {
|
||||
// fn foo(); }` are assumed not to unwind **unless** they have
|
||||
// a `#[unwind]` attribute.
|
||||
if !ty::queries::is_foreign_item::get(tcx, DUMMY_SP, instance.def_id()) {
|
||||
attributes::unwind(llfn, true);
|
||||
unsafe {
|
||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||
}
|
||||
}
|
||||
|
||||
if ccx.use_dll_storage_attrs() &&
|
||||
ccx.sess().cstore.is_dllimport_foreign_item(instance.def_id())
|
||||
{
|
||||
|
|
|
@ -99,6 +99,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
trait_def,
|
||||
adt_def,
|
||||
impl_trait_ref,
|
||||
is_foreign_item,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
@ -1530,3 +1531,13 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
|
|||
let substs = Substs::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs, fty)
|
||||
}
|
||||
|
||||
fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> bool {
|
||||
match tcx.hir.get_if_local(def_id) {
|
||||
Some(hir_map::NodeForeignItem(..)) => true,
|
||||
Some(_) => false,
|
||||
_ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue