From bf801590503447cc5b1ddd520b39d2957d90368b Mon Sep 17 00:00:00 2001 From: Andrew Sun Date: Wed, 6 Jan 2021 03:23:54 -0500 Subject: [PATCH 1/3] Make target-cpu=native detect individual features --- compiler/rustc_codegen_llvm/src/back/write.rs | 3 ++- compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/llvm_util.rs | 20 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 230e11f274e..68f319ade1e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -164,7 +164,8 @@ pub fn target_machine_factory( let code_model = to_llvm_code_model(sess.code_model()); - let features = attributes::llvm_target_features(sess).collect::>(); + let mut features = llvm_util::handle_native_features(sess); + features.extend(attributes::llvm_target_features(sess).map(|s| s.to_owned())); let mut singlethread = sess.target.singlethread; // On the wasm target once the `atomics` feature is enabled that means that diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 92ac770aca5..502f3b44af1 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -12,6 +12,7 @@ #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(or_patterns)] +#![feature(stdsimd)] #![recursion_limit = "256"] use back::write::{create_informational_target_machine, create_target_machine}; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a3139ce5a34..2da06e6babe 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -10,6 +10,7 @@ use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; use std::ffi::CString; +use std::detect; use std::slice; use std::str; use std::sync::atomic::{AtomicBool, Ordering}; @@ -221,6 +222,25 @@ pub fn target_cpu(sess: &Session) -> &str { handle_native(name) } +pub fn handle_native_features(sess: &Session) -> Vec { + const LLVM_NOT_RECOGNIZED: &[&str] = &["tsc"]; + + match sess.opts.cg.target_cpu { + Some(ref s) => { + if s != "native" { + return vec![]; + } + + detect::features() + .map(|(feature, support)| (to_llvm_feature(sess, feature), support)) + .filter(|(feature, _)| !LLVM_NOT_RECOGNIZED.contains(feature)) + .map(|(feature, support)| (if support { "+" } else { "-" }).to_owned() + feature) + .collect() + } + None => vec![], + } +} + pub fn tune_cpu(sess: &Session) -> Option<&str> { match sess.opts.debugging_opts.tune_cpu { Some(ref s) => Some(handle_native(&**s)), From bc4c5bac408f96db0a0e1c8934ff0c403b3986d3 Mon Sep 17 00:00:00 2001 From: Andrew Sun Date: Thu, 7 Jan 2021 23:25:19 -0500 Subject: [PATCH 2/3] Use LLVMGetHostCPUFeatures instead of stdsimd --- compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 ++++ compiler/rustc_codegen_llvm/src/llvm_util.rs | 18 +++++++++--------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 502f3b44af1..92ac770aca5 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -12,7 +12,6 @@ #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(or_patterns)] -#![feature(stdsimd)] #![recursion_limit = "256"] use back::write::{create_informational_target_machine, create_target_machine}; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 707aaa2b53f..e359d9f8c9c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1708,6 +1708,10 @@ extern "C" { PM: &PassManager<'_>, ); + pub fn LLVMGetHostCPUFeatures() -> *mut c_char; + + pub fn LLVMDisposeMessage(message: *mut c_char); + // Stuff that's in llvm-wrapper/ because it's not upstream yet. /// Opens an object file. diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 2da06e6babe..e0771313f76 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -8,9 +8,8 @@ use rustc_session::config::PrintRequest; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; -use std::ffi::CString; +use std::ffi::{CStr, CString}; -use std::detect; use std::slice; use std::str; use std::sync::atomic::{AtomicBool, Ordering}; @@ -223,19 +222,20 @@ pub fn target_cpu(sess: &Session) -> &str { } pub fn handle_native_features(sess: &Session) -> Vec { - const LLVM_NOT_RECOGNIZED: &[&str] = &["tsc"]; - match sess.opts.cg.target_cpu { Some(ref s) => { if s != "native" { return vec![]; } - detect::features() - .map(|(feature, support)| (to_llvm_feature(sess, feature), support)) - .filter(|(feature, _)| !LLVM_NOT_RECOGNIZED.contains(feature)) - .map(|(feature, support)| (if support { "+" } else { "-" }).to_owned() + feature) - .collect() + let ptr = unsafe { llvm::LLVMGetHostCPUFeatures() }; + let str = unsafe { CStr::from_ptr(ptr).to_string_lossy() }; + + let features = str.split(",").map(|s| s.to_owned()).collect(); + + unsafe { llvm::LLVMDisposeMessage(ptr) }; + + features } None => vec![], } From 80ca198212e967684557075b2f86b44e18048c70 Mon Sep 17 00:00:00 2001 From: Andrew Sun Date: Fri, 8 Jan 2021 11:50:21 -0500 Subject: [PATCH 3/3] Check if the pointer is null/string is not utf8 --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 21 +++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index e0771313f76..a9d57ea8b8a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -228,14 +228,25 @@ pub fn handle_native_features(sess: &Session) -> Vec { return vec![]; } - let ptr = unsafe { llvm::LLVMGetHostCPUFeatures() }; - let str = unsafe { CStr::from_ptr(ptr).to_string_lossy() }; + let features_string = unsafe { + let ptr = llvm::LLVMGetHostCPUFeatures(); + let features_string = if !ptr.is_null() { + CStr::from_ptr(ptr) + .to_str() + .unwrap_or_else(|e| { + bug!("LLVM returned a non-utf8 features string: {}", e); + }) + .to_owned() + } else { + bug!("could not allocate host CPU features, LLVM returned a `null` string"); + }; - let features = str.split(",").map(|s| s.to_owned()).collect(); + llvm::LLVMDisposeMessage(ptr); - unsafe { llvm::LLVMDisposeMessage(ptr) }; + features_string + }; - features + features_string.split(",").map(|s| s.to_owned()).collect() } None => vec![], }