@@ -37,7 +37,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
37
37
unsafe {
38
38
llvm:: LLVMRustSetLinkage ( g, base:: linkage_to_llvm ( linkage) ) ;
39
39
llvm:: LLVMRustSetVisibility ( g, base:: visibility_to_llvm ( visibility) ) ;
40
- if self . should_assume_dso_local ( linkage , visibility ) {
40
+ if self . should_assume_dso_local ( g , false ) {
41
41
llvm:: LLVMRustSetDSOLocal ( g, true ) ;
42
42
}
43
43
}
@@ -85,7 +85,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
85
85
attributes:: from_fn_attrs ( self , lldecl, instance) ;
86
86
87
87
unsafe {
88
- if self . should_assume_dso_local ( linkage , visibility ) {
88
+ if self . should_assume_dso_local ( lldecl , false ) {
89
89
llvm:: LLVMRustSetDSOLocal ( lldecl, true ) ;
90
90
}
91
91
}
@@ -95,28 +95,48 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
95
95
}
96
96
97
97
impl CodegenCx < ' ll , ' tcx > {
98
- /// Whether a definition (NB: not declaration!) can be assumed to be local to a group of
98
+ /// Whether a definition or declaration can be assumed to be local to a group of
99
99
/// libraries that form a single DSO or executable.
100
100
pub ( crate ) unsafe fn should_assume_dso_local (
101
101
& self ,
102
- linkage : Linkage ,
103
- visibility : Visibility ,
102
+ llval : & llvm :: Value ,
103
+ is_declaration : bool ,
104
104
) -> bool {
105
- if matches ! ( linkage, Linkage :: Internal | Linkage :: Private ) {
105
+ let linkage = llvm:: LLVMRustGetLinkage ( llval) ;
106
+ let visibility = llvm:: LLVMRustGetVisibility ( llval) ;
107
+
108
+ if matches ! ( linkage, llvm:: Linkage :: InternalLinkage | llvm:: Linkage :: PrivateLinkage ) {
106
109
return true ;
107
110
}
108
111
109
- if visibility != Visibility :: Default && linkage != Linkage :: ExternalWeak {
112
+ if visibility != llvm:: Visibility :: Default && linkage != llvm:: Linkage :: ExternalWeakLinkage
113
+ {
110
114
return true ;
111
115
}
112
116
113
- // Static relocation model should force copy relocations everywhere.
114
- if self . tcx . sess . relocation_model ( ) == RelocModel :: Static {
117
+ // Symbols from executables can't really be imported any further.
118
+ let all_exe = self . tcx . sess . crate_types ( ) . iter ( ) . all ( |ty| * ty == CrateType :: Executable ) ;
119
+ let is_declaration_for_linker =
120
+ is_declaration || linkage == llvm:: Linkage :: AvailableExternallyLinkage ;
121
+ if all_exe && !is_declaration_for_linker {
115
122
return true ;
116
123
}
117
124
118
- // Symbols from executables can't really be imported any further.
119
- if self . tcx . sess . crate_types ( ) . iter ( ) . all ( |ty| * ty == CrateType :: Executable ) {
125
+ // PowerPC64 prefers TOC indirection to avoid copy relocations.
126
+ if matches ! ( & * self . tcx. sess. target. arch, "powerpc64" | "powerpc64le" ) {
127
+ return false ;
128
+ }
129
+
130
+ // Thread-local variables generally don't support copy relocations.
131
+ let is_thread_local_var = llvm:: LLVMIsAGlobalVariable ( llval)
132
+ . map ( |v| llvm:: LLVMIsThreadLocal ( v) == llvm:: True )
133
+ . unwrap_or ( false ) ;
134
+ if is_thread_local_var {
135
+ return false ;
136
+ }
137
+
138
+ // Static relocation model should force copy relocations everywhere.
139
+ if self . tcx . sess . relocation_model ( ) == RelocModel :: Static {
120
140
return true ;
121
141
}
122
142
0 commit comments