Skip to content

Commit 07890c5

Browse files
committed
Add target_features to TransFnAttrs
Part of #47320
1 parent 39f9d23 commit 07890c5

File tree

9 files changed

+101
-101
lines changed

9 files changed

+101
-101
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,6 @@ define_dep_nodes!( <'tcx>
636636
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
637637

638638
[input] TargetFeaturesWhitelist,
639-
[] TargetFeaturesEnabled(DefId),
640639

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

src/librustc/hir/check_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> {
4747
impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
4848
/// Check any attribute.
4949
fn check_attributes(&self, item: &hir::Item, target: Target) {
50-
self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
50+
self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id));
5151

5252
for attr in &item.attrs {
5353
if let Some(name) = attr.name() {

src/librustc/hir/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,7 @@ pub struct TransFnAttrs {
22172217
pub flags: TransFnAttrFlags,
22182218
pub inline: InlineAttr,
22192219
pub export_name: Option<Symbol>,
2220+
pub target_features: Vec<Symbol>,
22202221
}
22212222

22222223
bitflags! {
@@ -2238,6 +2239,7 @@ impl TransFnAttrs {
22382239
flags: TransFnAttrFlags::empty(),
22392240
inline: InlineAttr::None,
22402241
export_name: None,
2242+
target_features: vec![],
22412243
}
22422244
}
22432245

src/librustc/ich/impls_hir.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,11 +1148,13 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
11481148
flags,
11491149
inline,
11501150
export_name,
1151+
ref target_features,
11511152
} = *self;
11521153

11531154
flags.hash_stable(hcx, hasher);
11541155
inline.hash_stable(hcx, hasher);
11551156
export_name.hash_stable(hcx, hasher);
1157+
target_features.hash_stable(hcx, hasher);
11561158
}
11571159
}
11581160

src/librustc/ty/maps/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ define_maps! { <'tcx>
384384

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

389388
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
390389
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)

src/librustc/ty/maps/plumbing.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
930930
DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); }
931931

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

935934
DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
936935
DepKind::Features => { force!(features_query, LOCAL_CRATE); }

src/librustc_trans/attributes.rs

Lines changed: 12 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,15 @@
1212
use std::ffi::{CStr, CString};
1313

1414
use rustc::hir::TransFnAttrFlags;
15-
use rustc::hir::Unsafety;
1615
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
1716
use rustc::session::config::Sanitizer;
18-
use rustc::ty::TyCtxt;
1917
use rustc::ty::maps::Providers;
20-
use rustc_data_structures::fx::FxHashSet;
2118
use rustc_data_structures::sync::Lrc;
2219

2320
use llvm::{self, Attribute, ValueRef};
2421
use llvm::AttributePlace::Function;
2522
use llvm_util;
2623
pub use syntax::attr::{self, InlineAttr};
27-
use syntax::ast;
2824
use context::CodegenCx;
2925

3026
/// Mark LLVM function to use provided inline heuristic.
@@ -127,10 +123,18 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
127123
unwind(llfn, false);
128124
}
129125

130-
let target_features = cx.tcx.target_features_enabled(id);
131-
132-
if !target_features.is_empty() {
133-
let val = CString::new(target_features.join(",")).unwrap();
126+
let features =
127+
trans_fn_attrs.target_features
128+
.iter()
129+
.map(|f| {
130+
let feature = &*f.as_str();
131+
format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
132+
})
133+
.collect::<Vec<String>>()
134+
.join(",");
135+
136+
if !features.is_empty() {
137+
let val = CString::new(features).unwrap();
134138
llvm::AddFunctionAttrStringValue(
135139
llfn, llvm::AttributePlace::Function,
136140
cstr("target-features\0"), &val);
@@ -149,89 +153,4 @@ pub fn provide(providers: &mut Providers) {
149153
.map(|c| c.to_string())
150154
.collect())
151155
};
152-
153-
providers.target_features_enabled = |tcx, id| {
154-
let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
155-
let mut target_features = Vec::new();
156-
for attr in tcx.get_attrs(id).iter() {
157-
if !attr.check_name("target_feature") {
158-
continue
159-
}
160-
if let Some(val) = attr.value_str() {
161-
for feat in val.as_str().split(",").map(|f| f.trim()) {
162-
if !feat.is_empty() && !feat.contains('\0') {
163-
target_features.push(feat.to_string());
164-
}
165-
}
166-
let msg = "#[target_feature = \"..\"] is deprecated and will \
167-
eventually be removed, use \
168-
#[target_feature(enable = \"..\")] instead";
169-
tcx.sess.span_warn(attr.span, &msg);
170-
continue
171-
}
172-
173-
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
174-
let msg = "#[target_feature(..)] can only be applied to \
175-
`unsafe` function";
176-
tcx.sess.span_err(attr.span, msg);
177-
}
178-
from_target_feature(tcx, attr, &whitelist, &mut target_features);
179-
}
180-
Lrc::new(target_features)
181-
};
182-
}
183-
184-
fn from_target_feature(
185-
tcx: TyCtxt,
186-
attr: &ast::Attribute,
187-
whitelist: &FxHashSet<String>,
188-
target_features: &mut Vec<String>,
189-
) {
190-
let list = match attr.meta_item_list() {
191-
Some(list) => list,
192-
None => {
193-
let msg = "#[target_feature] attribute must be of the form \
194-
#[target_feature(..)]";
195-
tcx.sess.span_err(attr.span, &msg);
196-
return
197-
}
198-
};
199-
200-
for item in list {
201-
if !item.check_name("enable") {
202-
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
203-
currently";
204-
tcx.sess.span_err(item.span, &msg);
205-
continue
206-
}
207-
let value = match item.value_str() {
208-
Some(list) => list,
209-
None => {
210-
let msg = "#[target_feature] attribute must be of the form \
211-
#[target_feature(enable = \"..\")]";
212-
tcx.sess.span_err(item.span, &msg);
213-
continue
214-
}
215-
};
216-
let value = value.as_str();
217-
for feature in value.split(',') {
218-
if whitelist.contains(feature) {
219-
let llvm_feature = llvm_util::to_llvm_feature(&tcx.sess, feature);
220-
target_features.push(format!("+{}", llvm_feature));
221-
continue
222-
}
223-
224-
let msg = format!("the feature named `{}` is not valid for \
225-
this target", feature);
226-
let mut err = tcx.sess.struct_span_err(item.span, &msg);
227-
228-
if feature.starts_with("+") {
229-
let valid = whitelist.contains(&feature[1..]);
230-
if valid {
231-
err.help("consider removing the leading `+` in the feature name");
232-
}
233-
}
234-
err.emit();
235-
}
236-
}
237156
}

src/librustc_trans_utils/trans_crate.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use rustc::middle::cstore::EncodedMetadata;
4444
use rustc::middle::cstore::MetadataLoader;
4545
use rustc::dep_graph::DepGraph;
4646
use rustc_back::target::Target;
47+
use rustc_data_structures::fx::FxHashSet;
4748
use rustc_mir::monomorphize::collector;
4849
use link::{build_link_meta, out_filename};
4950

@@ -198,8 +199,9 @@ impl TransCrate for MetadataOnlyTransCrate {
198199

199200
fn provide(&self, providers: &mut Providers) {
200201
::symbol_names::provide(providers);
201-
providers.target_features_enabled = |_tcx, _id| {
202-
Lrc::new(Vec::new()) // Just a dummy
202+
203+
providers.target_features_whitelist = |_tcx, _cnum| {
204+
Lrc::new(FxHashSet()) // Just a dummy
203205
};
204206
}
205207
fn provide_extern(&self, _providers: &mut Providers) {}

src/librustc_typeck/collect.rs

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use rustc::ty::{ToPredicate, ReprOptions};
3636
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
3737
use rustc::ty::maps::Providers;
3838
use rustc::ty::util::IntTypeExt;
39+
use rustc::util::nodemap::FxHashSet;
3940
use util::nodemap::FxHashMap;
4041

4142
use rustc_const_math::ConstInt;
@@ -47,10 +48,10 @@ use syntax::codemap::Spanned;
4748
use syntax::symbol::{Symbol, keywords};
4849
use syntax_pos::{Span, DUMMY_SP};
4950

50-
use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags};
51+
use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags, Unsafety};
5152
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
5253
use rustc::hir::def::{Def, CtorKind};
53-
use rustc::hir::def_id::DefId;
54+
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
5455

5556
///////////////////////////////////////////////////////////////////////////
5657
// Main entry point
@@ -1727,11 +1728,68 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
17271728
}
17281729
}
17291730

1731+
fn from_target_feature(
1732+
tcx: TyCtxt,
1733+
attr: &ast::Attribute,
1734+
whitelist: &FxHashSet<String>,
1735+
target_features: &mut Vec<Symbol>,
1736+
) {
1737+
let list = match attr.meta_item_list() {
1738+
Some(list) => list,
1739+
None => {
1740+
let msg = "#[target_feature] attribute must be of the form \
1741+
#[target_feature(..)]";
1742+
tcx.sess.span_err(attr.span, &msg);
1743+
return
1744+
}
1745+
};
1746+
1747+
for item in list {
1748+
if !item.check_name("enable") {
1749+
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
1750+
currently";
1751+
tcx.sess.span_err(item.span, &msg);
1752+
continue
1753+
}
1754+
let value = match item.value_str() {
1755+
Some(list) => list,
1756+
None => {
1757+
let msg = "#[target_feature] attribute must be of the form \
1758+
#[target_feature(enable = \"..\")]";
1759+
tcx.sess.span_err(item.span, &msg);
1760+
continue
1761+
}
1762+
};
1763+
let value = value.as_str();
1764+
for feature in value.split(',') {
1765+
if whitelist.contains(feature) {
1766+
target_features.push(Symbol::intern(feature));
1767+
continue
1768+
}
1769+
1770+
let msg = format!("the feature named `{}` is not valid for \
1771+
this target", feature);
1772+
let mut err = tcx.sess.struct_span_err(item.span, &msg);
1773+
1774+
if feature.starts_with("+") {
1775+
let valid = whitelist.contains(&feature[1..]);
1776+
if valid {
1777+
err.help("consider removing the leading `+` in the feature name");
1778+
}
1779+
}
1780+
err.emit();
1781+
}
1782+
}
1783+
}
1784+
1785+
17301786
fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAttrs {
17311787
let attrs = tcx.get_attrs(id);
17321788

17331789
let mut trans_fn_attrs = TransFnAttrs::new();
17341790

1791+
let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
1792+
17351793
for attr in attrs.iter() {
17361794
if attr.check_name("cold") {
17371795
trans_fn_attrs.flags |= TransFnAttrFlags::COLD;
@@ -1790,6 +1848,26 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
17901848
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
17911849
.emit();
17921850
}
1851+
} else if attr.check_name("target_feature") {
1852+
if let Some(val) = attr.value_str() {
1853+
for feat in val.as_str().split(",").map(|f| f.trim()) {
1854+
if !feat.is_empty() && !feat.contains('\0') {
1855+
trans_fn_attrs.target_features.push(Symbol::intern(feat));
1856+
}
1857+
}
1858+
let msg = "#[target_feature = \"..\"] is deprecated and will \
1859+
eventually be removed, use \
1860+
#[target_feature(enable = \"..\")] instead";
1861+
tcx.sess.span_warn(attr.span, &msg);
1862+
continue
1863+
}
1864+
1865+
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
1866+
let msg = "#[target_feature(..)] can only be applied to \
1867+
`unsafe` function";
1868+
tcx.sess.span_err(attr.span, msg);
1869+
}
1870+
from_target_feature(tcx, attr, &whitelist, &mut trans_fn_attrs.target_features);
17931871
}
17941872
}
17951873

0 commit comments

Comments
 (0)