about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs80
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs12
9 files changed, 77 insertions, 86 deletions
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 915dd3d9eda..a69241e456f 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -389,7 +389,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
 
     fn llvm_cconv(&self) -> llvm::CallConv {
         match self.conv {
-            Conv::C | Conv::Rust => llvm::CCallConv,
+            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
             Conv::AmdGpuKernel => llvm::AmdGpuKernel,
             Conv::AvrInterrupt => llvm::AvrInterrupt,
             Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
@@ -546,6 +546,18 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
         if cconv != llvm::CCallConv {
             llvm::SetInstructionCallConv(callsite, cconv);
         }
+
+        if self.conv == Conv::CCmseNonSecureCall {
+            // This will probably get ignored on all targets but those supporting the TrustZone-M
+            // extension (thumbv8m targets).
+            unsafe {
+                llvm::AddCallSiteAttrString(
+                    callsite,
+                    llvm::AttributePlace::Function,
+                    rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
+                );
+            }
+        }
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 29415973ed0..5effe687528 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -732,10 +732,7 @@ pub unsafe fn optimize_thin_module(
     let diag_handler = cgcx.create_diag_handler();
 
     let module_name = &thin_module.shared.module_names[thin_module.idx];
-    let split_dwarf_file = cgcx
-        .output_filenames
-        .split_dwarf_filename(cgcx.split_dwarf_kind, Some(module_name.to_str().unwrap()));
-    let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file };
+    let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
     let tm =
         (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, &e))?;
 
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index e225730dce0..326ae354ccf 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -23,13 +23,11 @@ use rustc_fs_util::{link_or_copy, path_to_c_string};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::bug;
 use rustc_middle::ty::TyCtxt;
-use rustc_session::config::{
-    self, Lto, OutputType, Passes, SanitizerSet, SplitDwarfKind, SwitchWithOptPath,
-};
+use rustc_session::config::{self, Lto, OutputType, Passes, SanitizerSet, SwitchWithOptPath};
 use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::InnerSpan;
-use rustc_target::spec::{CodeModel, RelocModel};
+use rustc_target::spec::{CodeModel, RelocModel, SplitDebuginfo};
 use tracing::debug;
 
 use libc::{c_char, c_int, c_uint, c_void, size_t};
@@ -93,9 +91,12 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
 }
 
 pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
-    let split_dwarf_file = tcx
-        .output_filenames(LOCAL_CRATE)
-        .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(mod_name));
+    let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
+        tcx.output_filenames(LOCAL_CRATE)
+            .split_dwarf_filename(tcx.sess.split_debuginfo(), Some(mod_name))
+    } else {
+        None
+    };
     let config = TargetMachineFactoryConfig { split_dwarf_file };
     target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))(config)
         .unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
@@ -838,11 +839,17 @@ pub(crate) unsafe fn codegen(
                     .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
 
                 let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
-                let dwo_out = match cgcx.split_dwarf_kind {
+                let dwo_out = match cgcx.split_debuginfo {
                     // Don't change how DWARF is emitted in single mode (or when disabled).
-                    SplitDwarfKind::None | SplitDwarfKind::Single => None,
+                    SplitDebuginfo::Off | SplitDebuginfo::Packed => None,
                     // Emit (a subset of the) DWARF into a separate file in split mode.
-                    SplitDwarfKind::Split => Some(dwo_out.as_path()),
+                    SplitDebuginfo::Unpacked => {
+                        if cgcx.target_can_use_split_dwarf {
+                            Some(dwo_out.as_path())
+                        } else {
+                            None
+                        }
+                    }
                 };
 
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
@@ -880,7 +887,7 @@ pub(crate) unsafe fn codegen(
 
     Ok(module.into_compiled_module(
         config.emit_obj != EmitObj::None,
-        cgcx.split_dwarf_kind == SplitDwarfKind::Split,
+        cgcx.target_can_use_split_dwarf && cgcx.split_debuginfo == SplitDebuginfo::Unpacked,
         config.emit_bc,
         &cgcx.output_filenames,
     ))
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 14dd245625d..16e1a8a1242 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -8,9 +8,7 @@ use crate::value::Value;
 use libc::c_uint;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::const_cstr;
-use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::Node;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::interpret::{
     read_target_uint, Allocation, ErrorHandled, GlobalAlloc, Pointer,
@@ -18,7 +16,6 @@ use rustc_middle::mir::interpret::{
 use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, span_bug};
-use rustc_span::symbol::sym;
 use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
 use tracing::debug;
 
@@ -209,70 +206,42 @@ impl CodegenCx<'ll, 'tcx> {
 
         let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
         let sym = self.tcx.symbol_name(instance).name;
+        let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
 
-        debug!("get_static: sym={} instance={:?}", sym, instance);
+        debug!("get_static: sym={} instance={:?} fn_attrs={:?}", sym, instance, fn_attrs);
 
-        let g = if let Some(local_def_id) = def_id.as_local() {
-            let id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
+        let g = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
             let llty = self.layout_of(ty).llvm_type(self);
-            // FIXME: refactor this to work without accessing the HIR
-            let (g, attrs) = match self.tcx.hir().get(id) {
-                Node::Item(&hir::Item { attrs, kind: hir::ItemKind::Static(..), .. }) => {
-                    if let Some(g) = self.get_declared_value(sym) {
-                        if self.val_ty(g) != self.type_ptr_to(llty) {
-                            span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
-                        }
-                    }
-
-                    let g = self.declare_global(sym, llty);
-
-                    if !self.tcx.is_reachable_non_generic(local_def_id) {
-                        unsafe {
-                            llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
-                        }
-                    }
-
-                    (g, attrs)
+            if let Some(g) = self.get_declared_value(sym) {
+                if self.val_ty(g) != self.type_ptr_to(llty) {
+                    span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
                 }
+            }
 
-                Node::ForeignItem(&hir::ForeignItem {
-                    ref attrs,
-                    kind: hir::ForeignItemKind::Static(..),
-                    ..
-                }) => {
-                    let fn_attrs = self.tcx.codegen_fn_attrs(local_def_id);
-                    (check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id), &**attrs)
-                }
-
-                item => bug!("get_static: expected static, found {:?}", item),
-            };
-
-            debug!("get_static: sym={} attrs={:?}", sym, attrs);
+            let g = self.declare_global(sym, llty);
 
-            for attr in attrs {
-                if self.tcx.sess.check_name(attr, sym::thread_local) {
-                    llvm::set_thread_local_mode(g, self.tls_model);
+            if !self.tcx.is_reachable_non_generic(def_id) {
+                unsafe {
+                    llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
                 }
             }
 
             g
         } else {
-            // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
-            debug!("get_static: sym={} item_attr={:?}", sym, self.tcx.item_attrs(def_id));
+            check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id)
+        };
 
-            let attrs = self.tcx.codegen_fn_attrs(def_id);
-            let g = check_and_apply_linkage(&self, &attrs, ty, sym, def_id);
-
-            // Thread-local statics in some other crate need to *always* be linked
-            // against in a thread-local fashion, so we need to be sure to apply the
-            // thread-local attribute locally if it was present remotely. If we
-            // don't do this then linker errors can be generated where the linker
-            // complains that one object files has a thread local version of the
-            // symbol and another one doesn't.
-            if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
-                llvm::set_thread_local_mode(g, self.tls_model);
-            }
+        // Thread-local statics in some other crate need to *always* be linked
+        // against in a thread-local fashion, so we need to be sure to apply the
+        // thread-local attribute locally if it was present remotely. If we
+        // don't do this then linker errors can be generated where the linker
+        // complains that one object files has a thread local version of the
+        // symbol and another one doesn't.
+        if fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
+            llvm::set_thread_local_mode(g, self.tls_model);
+        }
 
+        if !def_id.is_local() {
             let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
                 // ThinLTO can't handle this workaround in all cases, so we don't
                 // emit the attrs. Instead we make them unnecessary by disallowing
@@ -304,8 +273,7 @@ impl CodegenCx<'ll, 'tcx> {
                     }
                 }
             }
-            g
-        };
+        }
 
         if self.use_dll_storage_attrs && self.tcx.is_dllimport_foreign_item(def_id) {
             // For foreign (native) libs we know the exact storage type to use.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 3a4e1492af3..6e7c0b3e347 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -995,10 +995,13 @@ pub fn compile_unit_metadata(
     let flags = "\0";
 
     let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory;
-    let split_name = tcx
-        .output_filenames(LOCAL_CRATE)
-        .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name))
-        .unwrap_or_default();
+    let split_name = if tcx.sess.target_can_use_split_dwarf() {
+        tcx.output_filenames(LOCAL_CRATE)
+            .split_dwarf_filename(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
+    } else {
+        None
+    }
+    .unwrap_or_default();
     let out_dir = out_dir.to_str().unwrap();
     let split_name = split_name.to_str().unwrap();
 
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 92ac770aca5..d11c1592f99 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -351,12 +351,7 @@ impl ModuleLlvm {
         unsafe {
             let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
             let llmod_raw = back::lto::parse_module(llcx, name, buffer, handler)?;
-
-            let split_dwarf_file = cgcx
-                .output_filenames
-                .split_dwarf_filename(cgcx.split_dwarf_kind, Some(name.to_str().unwrap()));
-            let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file };
-
+            let tm_factory_config = TargetMachineFactoryConfig::new(&cgcx, name.to_str().unwrap());
             let tm = match (cgcx.tm_factory)(tm_factory_config) {
                 Ok(m) => m,
                 Err(e) => {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index d9f42efebab..e82198f8f0c 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1100,6 +1100,7 @@ extern "C" {
     // Operations on call sites
     pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
     pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute);
+    pub fn LLVMRustAddCallSiteAttrString(Instr: &Value, index: c_uint, Name: *const c_char);
     pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32);
     pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
     pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index fc40065a966..bb9c6d47373 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -43,6 +43,10 @@ pub fn AddFunctionAttrString(llfn: &'a Value, idx: AttributePlace, attr: &CStr)
     }
 }
 
+pub fn AddCallSiteAttrString(callsite: &Value, idx: AttributePlace, attr: &CStr) {
+    unsafe { LLVMRustAddCallSiteAttrString(callsite, idx.as_uint(), attr.as_ptr()) }
+}
+
 #[derive(Copy, Clone)]
 pub enum AttributePlace {
     ReturnValue,
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 07fde27b5a3..39d08fbee3b 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -105,7 +105,6 @@ 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_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 {
@@ -144,9 +143,14 @@ fn emit_aapcs_va_arg(
     let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
 
     // reg_value = *(@top + reg_off_v);
-    let top = in_reg.gep(top, &[reg_off_v]);
-    let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
-    let reg_value = in_reg.load(top, layout.align.abi);
+    let mut reg_addr = in_reg.gep(top, &[reg_off_v]);
+    if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
+        // On big-endian systems the value is right-aligned in its slot.
+        let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
+        reg_addr = in_reg.gep(reg_addr, &[offset]);
+    }
+    let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(layout.llvm_type(bx)));
+    let reg_value = in_reg.load(reg_addr, layout.align.abi);
     in_reg.br(&end.llbb());
 
     // On Stack block