about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-28 23:49:28 +0000
committerbors <bors@rust-lang.org>2018-04-28 23:49:28 +0000
commitf4c1f0ce93137049bd6c25d3289bf12bfc00426d (patch)
treedc72d394dfc4ab800d57482a930d946470ffcbcf
parent66363b288141ed2af4b95fb4205a56dce6248363 (diff)
parent622371153c66f9e371f587205d14040534060c18 (diff)
downloadrust-f4c1f0ce93137049bd6c25d3289bf12bfc00426d.tar.gz
rust-f4c1f0ce93137049bd6c25d3289bf12bfc00426d.zip
Auto merge of #50188 - alexcrichton:feature-all-the-things, r=eddyb
Add `-C target-feature` to all functions

Previously the features specified to LLVM via `-C target-feature` were only
reflected in the `TargetMachine` but this change *also* reflects these and the
base features inside each function itself. This change matches clang and...

Closes rust-lang-nursery/stdsimd#427
-rw-r--r--src/librustc_trans/attributes.rs30
-rw-r--r--src/librustc_trans/back/write.rs31
-rw-r--r--src/test/codegen/target-feature-on-functions.rs19
3 files changed, 47 insertions, 33 deletions
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index eb5c7396ae0..f455c19cc0b 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -14,6 +14,7 @@ use std::ffi::{CStr, CString};
 use rustc::hir::{self, TransFnAttrFlags};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::session::Session;
 use rustc::session::config::Sanitizer;
 use rustc::ty::TyCtxt;
 use rustc::ty::maps::Providers;
@@ -104,6 +105,18 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
         cstr("probe-stack\0"), cstr("__rust_probestack\0"));
 }
 
+pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
+    const RUSTC_SPECIFIC_FEATURES: &[&str] = &[
+        "crt-static",
+    ];
+
+    let cmdline = sess.opts.cg.target_feature.split(',')
+        .filter(|f| !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)));
+    sess.target.target.options.features.split(',')
+        .chain(cmdline)
+        .filter(|l| !l.is_empty())
+}
+
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
 pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
@@ -131,13 +144,16 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
         unwind(llfn, false);
     }
 
-    let features =
-        trans_fn_attrs.target_features
-        .iter()
-        .map(|f| {
-            let feature = &*f.as_str();
-            format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
-        })
+    let features = llvm_target_features(cx.tcx.sess)
+        .map(|s| s.to_string())
+        .chain(
+            trans_fn_attrs.target_features
+                .iter()
+                .map(|f| {
+                    let feature = &*f.as_str();
+                    format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
+                })
+        )
         .collect::<Vec<String>>()
         .join(",");
 
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 613a07cd269..148e3d0025c 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use attributes;
 use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
 use back::lto::{self, ModuleBuffer, ThinBuffer};
 use back::link::{self, get_linker, remove};
@@ -111,31 +112,6 @@ pub fn write_output_file(
     }
 }
 
-// On android, we by default compile for armv7 processors. This enables
-// things like double word CAS instructions (rather than emulating them)
-// which are *far* more efficient. This is obviously undesirable in some
-// cases, so if any sort of target feature is specified we don't append v7
-// to the feature list.
-//
-// On iOS only armv7 and newer are supported. So it is useful to
-// get all hardware potential via VFP3 (hardware floating point)
-// and NEON (SIMD) instructions supported by LLVM.
-// Note that without those flags various linking errors might
-// arise as some of intrinsics are converted into function calls
-// and nobody provides implementations those functions
-fn target_feature(sess: &Session) -> String {
-    let rustc_features = [
-        "crt-static",
-    ];
-    let requested_features = sess.opts.cg.target_feature.split(',');
-    let llvm_features = requested_features.filter(|f| {
-        !rustc_features.iter().any(|s| f.contains(s))
-    });
-    format!("{},{}",
-            sess.target.target.options.features,
-            llvm_features.collect::<Vec<_>>().join(","))
-}
-
 fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
     match optimize {
       config::OptLevel::No => llvm::CodeGenOptLevel::None,
@@ -203,7 +179,10 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
         None => &*sess.target.target.options.cpu
     };
     let cpu = CString::new(cpu.as_bytes()).unwrap();
-    let features = CString::new(target_feature(sess).as_bytes()).unwrap();
+    let features = attributes::llvm_target_features(sess)
+        .collect::<Vec<_>>()
+        .join(",");
+    let features = CString::new(features).unwrap();
     let is_pie_binary = !find_features && is_pie_binary(sess);
     let trap_unreachable = sess.target.target.options.trap_unreachable;
 
diff --git a/src/test/codegen/target-feature-on-functions.rs b/src/test/codegen/target-feature-on-functions.rs
new file mode 100644
index 00000000000..e3cc2c753e5
--- /dev/null
+++ b/src/test/codegen/target-feature-on-functions.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// only-x86_64
+// compile-flags: -C target-feature=+avx
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn foo() {
+    // CHECK: attributes #0 = { {{.*}}"target-features"="+avx"{{.*}} }
+}