about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/mono_item.rs
diff options
context:
space:
mode:
authorBoris-Chengbiao Zhou <bobo1239@web.de>2021-05-25 23:54:07 +0200
committerBoris-Chengbiao Zhou <bobo1239@web.de>2021-05-28 03:48:39 +0200
commit4a76934aa7e46acad5f150ff394601c0b6d6d53f (patch)
tree7e7ee05406f9eff6db96a32a18d276dcb9c9b65d /compiler/rustc_codegen_llvm/src/mono_item.rs
parente51830b90afd339332892a8f20db1957d43bf086 (diff)
downloadrust-4a76934aa7e46acad5f150ff394601c0b6d6d53f.tar.gz
rust-4a76934aa7e46acad5f150ff394601c0b6d6d53f.zip
Fix static relocation model for PowerPC64
We now also use `should_assume_dso_local()` for declarations and port two
additional cases from clang:
- Exclude PPC64 [1]
- Exclude thread-local variables [2]

[1]: https://github.com/llvm/llvm-project/blob/033138ea452f5f493fb5095e5963419905ad12e1/clang/lib/CodeGen/CodeGenModule.cpp#L1038-L1040
[2]: https://github.com/llvm/llvm-project/blob/033138ea452f5f493fb5095e5963419905ad12e1/clang/lib/CodeGen/CodeGenModule.cpp#L1048-L1050
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/mono_item.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs42
1 files changed, 31 insertions, 11 deletions
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index fc1f364e9c6..93456443aa0 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -37,7 +37,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe {
             llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
             llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
-            if self.should_assume_dso_local(linkage, visibility) {
+            if self.should_assume_dso_local(g, false) {
                 llvm::LLVMRustSetDSOLocal(g, true);
             }
         }
@@ -85,7 +85,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         attributes::from_fn_attrs(self, lldecl, instance);
 
         unsafe {
-            if self.should_assume_dso_local(linkage, visibility) {
+            if self.should_assume_dso_local(lldecl, false) {
                 llvm::LLVMRustSetDSOLocal(lldecl, true);
             }
         }
@@ -95,28 +95,48 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 }
 
 impl CodegenCx<'ll, 'tcx> {
-    /// Whether a definition (NB: not declaration!) can be assumed to be local to a group of
+    /// Whether a definition or declaration can be assumed to be local to a group of
     /// libraries that form a single DSO or executable.
     pub(crate) unsafe fn should_assume_dso_local(
         &self,
-        linkage: Linkage,
-        visibility: Visibility,
+        llval: &llvm::Value,
+        is_declaration: bool,
     ) -> bool {
-        if matches!(linkage, Linkage::Internal | Linkage::Private) {
+        let linkage = llvm::LLVMRustGetLinkage(llval);
+        let visibility = llvm::LLVMRustGetVisibility(llval);
+
+        if matches!(linkage, llvm::Linkage::InternalLinkage | llvm::Linkage::PrivateLinkage) {
             return true;
         }
 
-        if visibility != Visibility::Default && linkage != Linkage::ExternalWeak {
+        if visibility != llvm::Visibility::Default && linkage != llvm::Linkage::ExternalWeakLinkage
+        {
             return true;
         }
 
-        // Static relocation model should force copy relocations everywhere.
-        if self.tcx.sess.relocation_model() == RelocModel::Static {
+        // Symbols from executables can't really be imported any further.
+        let all_exe = self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable);
+        let is_declaration_for_linker =
+            is_declaration || linkage == llvm::Linkage::AvailableExternallyLinkage;
+        if all_exe && !is_declaration_for_linker {
             return true;
         }
 
-        // Symbols from executables can't really be imported any further.
-        if self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable) {
+        // PowerPC64 prefers TOC indirection to avoid copy relocations.
+        if matches!(&*self.tcx.sess.target.arch, "powerpc64" | "powerpc64le") {
+            return false;
+        }
+
+        // Thread-local variables generally don't support copy relocations.
+        let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
+            .map(|v| llvm::LLVMIsThreadLocal(v) == llvm::True)
+            .unwrap_or(false);
+        if is_thread_local_var {
+            return false;
+        }
+
+        // Static relocation model should force copy relocations everywhere.
+        if self.tcx.sess.relocation_model() == RelocModel::Static {
             return true;
         }