diff options
| author | Boris-Chengbiao Zhou <bobo1239@web.de> | 2021-05-25 23:54:07 +0200 |
|---|---|---|
| committer | Boris-Chengbiao Zhou <bobo1239@web.de> | 2021-05-28 03:48:39 +0200 |
| commit | 4a76934aa7e46acad5f150ff394601c0b6d6d53f (patch) | |
| tree | 7e7ee05406f9eff6db96a32a18d276dcb9c9b65d /compiler/rustc_codegen_llvm/src/mono_item.rs | |
| parent | e51830b90afd339332892a8f20db1957d43bf086 (diff) | |
| download | rust-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.rs | 42 |
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; } |
