Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incr.comp.: Turn translation-related attributes into a query #48712

Merged
merged 9 commits into from
Mar 8, 2018
4 changes: 1 addition & 3 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ define_dep_nodes!( <'tcx>
[] IsReachableNonGeneric(DefId),
[] IsMirAvailable(DefId),
[] ItemAttrs(DefId),
[] TransFnAttrs(DefId),
[] FnArgNames(DefId),
[] DylibDepFormats(CrateNum),
[] IsPanicRuntime(CrateNum),
Expand Down Expand Up @@ -626,8 +627,6 @@ define_dep_nodes!( <'tcx>
[input] AllCrateNums,
[] ExportedSymbols(CrateNum),
[eval_always] CollectAndPartitionTranslationItems,
[] ExportName(DefId),
[] ContainsExternIndicator(DefId),
[] IsTranslatedItem(DefId),
[] CodegenUnit(InternedString),
[] CompileCodegenUnit(InternedString),
Expand All @@ -637,7 +636,6 @@ define_dep_nodes!( <'tcx>
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },

[input] TargetFeaturesWhitelist,
[] TargetFeaturesEnabled(DefId),

[] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
/// Check any attribute.
fn check_attributes(&self, item: &hir::Item, target: Target) {
self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id));

for attr in &item.attrs {
if let Some(name) = attr.name() {
Expand Down
50 changes: 50 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ pub use self::Visibility::{Public, Inherited};
use hir::def::Def;
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
use util::nodemap::{NodeMap, FxHashSet};
use mir::mono::Linkage;

use syntax_pos::{Span, DUMMY_SP};
use syntax::codemap::{self, Spanned};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::attr::InlineAttr;
use syntax::ext::hygiene::SyntaxContext;
use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
Expand Down Expand Up @@ -2210,3 +2212,51 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;
pub fn provide(providers: &mut Providers) {
providers.describe_def = map::describe_def;
}

#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
pub struct TransFnAttrs {
pub flags: TransFnAttrFlags,
pub inline: InlineAttr,
pub export_name: Option<Symbol>,
pub target_features: Vec<Symbol>,
pub linkage: Option<Linkage>,
}

bitflags! {
#[derive(RustcEncodable, RustcDecodable)]
pub struct TransFnAttrFlags: u8 {
const COLD = 0b0000_0001;
const ALLOCATOR = 0b0000_0010;
const UNWIND = 0b0000_0100;
const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000;
const NAKED = 0b0001_0000;
const NO_MANGLE = 0b0010_0000;
const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
}
}

impl TransFnAttrs {
pub fn new() -> TransFnAttrs {
TransFnAttrs {
flags: TransFnAttrFlags::empty(),
inline: InlineAttr::None,
export_name: None,
target_features: vec![],
linkage: None,
}
}

/// True if `#[inline]` or `#[inline(always)]` is present.
pub fn requests_inline(&self) -> bool {
match self.inline {
InlineAttr::Hint | InlineAttr::Always => true,
InlineAttr::None | InlineAttr::Never => false,
}
}

/// True if `#[no_mangle]` or `#[export_name(...)]` is present.
pub fn contains_extern_indicator(&self) -> bool {
self.flags.contains(TransFnAttrFlags::NO_MANGLE) || self.export_name.is_some()
}
}

38 changes: 38 additions & 0 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
use std::mem;
use syntax::ast;
use syntax::attr;

impl<'gcx> HashStable<StableHashingContext<'gcx>> for DefId {
#[inline]
Expand Down Expand Up @@ -1138,6 +1139,43 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::TraitCandidate {
}
}

impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
let hir::TransFnAttrs {
flags,
inline,
export_name,
ref target_features,
linkage,
} = *self;

flags.hash_stable(hcx, hasher);
inline.hash_stable(hcx, hasher);
export_name.hash_stable(hcx, hasher);
target_features.hash_stable(hcx, hasher);
linkage.hash_stable(hcx, hasher);
}
}

impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
self.bits().hash_stable(hcx, hasher);
}
}

impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
}
}

impl_stable_hash_for!(struct hir::Freevar {
def,
Expand Down
21 changes: 13 additions & 8 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.

use hir::TransFnAttrs;
use hir::map as hir_map;
use hir::def::Def;
use hir::def_id::{DefId, CrateNum};
Expand Down Expand Up @@ -43,8 +44,8 @@ fn generics_require_inlining(generics: &hir::Generics) -> bool {
// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
fn item_might_be_inlined(item: &hir::Item) -> bool {
if attr::requests_inline(&item.attrs) {
fn item_might_be_inlined(item: &hir::Item, attrs: TransFnAttrs) -> bool {
if attrs.requests_inline() {
return true
}

Expand All @@ -60,14 +61,15 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_item: &hir::ImplItem,
impl_src: DefId) -> bool {
if attr::requests_inline(&impl_item.attrs) ||
let trans_fn_attrs = tcx.trans_fn_attrs(impl_item.hir_id.owner_def_id());
if trans_fn_attrs.requests_inline() ||
generics_require_inlining(&impl_item.generics) {
return true
}
if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
match tcx.hir.find(impl_node_id) {
Some(hir_map::NodeItem(item)) =>
item_might_be_inlined(&item),
item_might_be_inlined(&item, trans_fn_attrs),
Some(..) | None =>
span_bug!(impl_item.span, "impl did is not an item")
}
Expand Down Expand Up @@ -160,7 +162,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match self.tcx.hir.find(node_id) {
Some(hir_map::NodeItem(item)) => {
match item.node {
hir::ItemFn(..) => item_might_be_inlined(&item),
hir::ItemFn(..) =>
item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)),
_ => false,
}
}
Expand All @@ -176,8 +179,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match impl_item.node {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Method(..) => {
let attrs = self.tcx.trans_fn_attrs(def_id);
if generics_require_inlining(&impl_item.generics) ||
attr::requests_inline(&impl_item.attrs) {
attrs.requests_inline() {
true
} else {
let impl_did = self.tcx
Expand Down Expand Up @@ -229,7 +233,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
false
};
let def_id = self.tcx.hir.local_def_id(item.id);
let is_extern = self.tcx.contains_extern_indicator(def_id);
let is_extern = self.tcx.trans_fn_attrs(def_id).contains_extern_indicator();
if reachable || is_extern {
self.reachable_symbols.insert(search_item);
}
Expand All @@ -246,7 +250,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir_map::NodeItem(item) => {
match item.node {
hir::ItemFn(.., body) => {
if item_might_be_inlined(&item) {
let def_id = self.tcx.hir.local_def_id(item.id);
if item_might_be_inlined(&item, self.tcx.trans_fn_attrs(def_id)) {
self.visit_nested_body(body);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub struct CodegenUnit<'tcx> {
size_estimate: Option<usize>,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum Linkage {
External,
AvailableExternally,
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ impl<'tcx> InstanceDef<'tcx> {
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>
) -> bool {
use syntax::attr::requests_inline;
if self.is_inline(tcx) {
return true
}
Expand All @@ -106,8 +105,8 @@ impl<'tcx> InstanceDef<'tcx> {
// available to normal end-users.
return true
}
requests_inline(&self.attrs(tcx)[..]) ||
tcx.is_const_fn(self.def_id())
let trans_fn_attrs = tcx.trans_fn_attrs(self.def_id());
trans_fn_attrs.requests_inline() || tcx.is_const_fn(self.def_id())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/maps/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,8 +687,8 @@ impl_disk_cacheable_query!(borrowck, |def_id| def_id.is_local());
impl_disk_cacheable_query!(mir_borrowck, |def_id| def_id.is_local());
impl_disk_cacheable_query!(mir_const_qualif, |def_id| def_id.is_local());
impl_disk_cacheable_query!(check_match, |def_id| def_id.is_local());
impl_disk_cacheable_query!(contains_extern_indicator, |_| true);
impl_disk_cacheable_query!(def_symbol_name, |_| true);
impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local());
impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local());
impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local());
impl_disk_cacheable_query!(trans_fn_attrs, |_| true);
10 changes: 6 additions & 4 deletions src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use dep_graph::{DepConstructor, DepNode};
use errors::DiagnosticBuilder;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::def::{Def, Export};
use hir::{self, TraitCandidate, ItemLocalId};
use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs};
use hir::svh::Svh;
use lint;
use middle::borrowck::BorrowCheckResult;
Expand Down Expand Up @@ -235,6 +235,7 @@ define_maps! { <'tcx>
[] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
[] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
[] fn item_attrs: ItemAttrs(DefId) -> Lrc<[ast::Attribute]>,
[] fn trans_fn_attrs: trans_fn_attrs(DefId) -> TransFnAttrs,
[] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
[] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
Expand Down Expand Up @@ -362,8 +363,6 @@ define_maps! { <'tcx>
[] fn collect_and_partition_translation_items:
collect_and_partition_translation_items_node(CrateNum)
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
[] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
[] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
Expand All @@ -385,7 +384,6 @@ define_maps! { <'tcx>

[] fn target_features_whitelist:
target_features_whitelist_node(CrateNum) -> Lrc<FxHashSet<String>>,
[] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Lrc<Vec<String>>,

// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
Expand All @@ -403,6 +401,10 @@ fn features_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::Features
}

fn trans_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
DepConstructor::TransFnAttrs { 0: id }
}

fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
DepConstructor::EraseRegionsTy { ty }
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/maps/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ impl<'sess> OnDiskCache<'sess> {
encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
encode_query_results::<check_match, _>(tcx, enc, qri)?;
encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
}

// Encode diagnostics
Expand Down
8 changes: 2 additions & 6 deletions src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
DepKind::TransFnAttrs => { force!(trans_fn_attrs, def_id!()); }
DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
Expand Down Expand Up @@ -925,15 +926,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::CollectAndPartitionTranslationItems => {
force!(collect_and_partition_translation_items, LOCAL_CRATE);
}
DepKind::ExportName => { force!(export_name, def_id!()); }
DepKind::ContainsExternIndicator => {
force!(contains_extern_indicator, def_id!());
}
DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); }
DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }

DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }

DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
DepKind::Features => { force!(features_query, LOCAL_CRATE); }
Expand Down Expand Up @@ -997,10 +993,10 @@ impl_load_from_cache!(
MirConstQualif => mir_const_qualif,
SymbolName => def_symbol_name,
ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
ContainsExternIndicator => contains_extern_indicator,
CheckMatch => check_match,
TypeOfItem => type_of,
GenericsOfItem => generics_of,
PredicatesOfItem => predicates_of,
UsedTraitImports => used_trait_imports,
TransFnAttrs => trans_fn_attrs,
);
4 changes: 2 additions & 2 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
} else if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
let generics = self.tcx.generics_of(def_id);
let types = generics.parent_types as usize + generics.types.len();
let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs);
let needs_inline = types > 0 || tcx.trans_fn_attrs(def_id).requests_inline();
let is_const_fn = sig.constness == hir::Constness::Const;
let ast = if is_const_fn { Some(body) } else { None };
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
Expand Down Expand Up @@ -1123,7 +1123,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
hir::ItemFn(_, _, constness, _, ref generics, _) => {
let has_tps = generics.ty_params().next().is_some();
let needs_inline = has_tps || attr::requests_inline(&item.attrs);
let needs_inline = has_tps || tcx.trans_fn_attrs(def_id).requests_inline();
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
if needs_inline || constness == hir::Constness::Const || always_encode_mir {
self.encode_optimized_mir(def_id)
Expand Down
Loading