mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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
This commit is contained in:
commit
f4c1f0ce93
@ -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(",");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
19
src/test/codegen/target-feature-on-functions.rs
Normal file
19
src/test/codegen/target-feature-on-functions.rs
Normal file
@ -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"{{.*}} }
|
||||
}
|
Loading…
Reference in New Issue
Block a user