diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/write.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm_util.rs | 33 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/va_arg.rs | 6 |
5 files changed, 42 insertions, 6 deletions
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::<Vec<_>>(); + 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/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 72ba5bbd5f2..444a9d4ba04 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -292,7 +292,7 @@ fn add_unreachable_coverage<'tcx>( if let Some(non_codegenned_file_name) = tcx.covered_file_name(non_codegenned_def_id) { let def_ids = unreachable_def_ids_by_file .entry(*non_codegenned_file_name) - .or_insert_with(|| Vec::new()); + .or_insert_with(Vec::new); def_ids.push(non_codegenned_def_id); } } 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 a3139ce5a34..a9d57ea8b8a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -8,7 +8,7 @@ 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::slice; use std::str; @@ -221,6 +221,37 @@ pub fn target_cpu(sess: &Session) -> &str { handle_native(name) } +pub fn handle_native_features(sess: &Session) -> Vec<String> { + match sess.opts.cg.target_cpu { + Some(ref s) => { + if s != "native" { + return vec![]; + } + + 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"); + }; + + llvm::LLVMDisposeMessage(ptr); + + features_string + }; + + features_string.split(",").map(|s| s.to_owned()).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)), diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 3fc56eecdd0..07fde27b5a3 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -9,7 +9,7 @@ use rustc_codegen_ssa::{ }; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::Ty; -use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Align, Endian, HasDataLayout, LayoutOf, Size}; fn round_pointer_up_to_alignment( bx: &mut Builder<'a, 'll, 'tcx>, @@ -52,7 +52,7 @@ fn emit_direct_ptr_va_arg( let next = bx.inbounds_gep(addr, &[full_direct_size]); bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi); - if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.endian == "big" { + if size.bytes() < slot_size.bytes() && bx.tcx().sess.target.endian == Endian::Big { let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32); let adjusted = bx.inbounds_gep(addr, &[adjusted_size]); (bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align) @@ -105,7 +105,7 @@ fn emit_aapcs_va_arg( let mut end = bx.build_sibling_block("va_arg.end"); let zero = bx.const_i32(0); let offset_align = Align::from_bytes(4).unwrap(); - assert!(&*bx.tcx().sess.target.endian == "little"); + assert_eq!(bx.tcx().sess.target.endian, Endian::Little); let gr_type = target_ty.is_any_ptr() || target_ty.is_integral(); let (reg_off, reg_top_index, slot_size) = if gr_type { |
