llvm.org GIT mirror llvm / 63476a8
Reference to hidden symbols do not have to go through non-lazy pointer in non-pic mode. rdar://7187172. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80904 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
14 changed file(s) with 99 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
12981298 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
12991299 }
13001300
1301 if (Subtarget->GVIsIndirectSymbol(GV, RelocM == Reloc::Static))
1301 if (Subtarget->GVIsIndirectSymbol(GV, RelocM))
13021302 Result = DAG.getLoad(PtrVT, dl, Chain, Result, NULL, 0);
13031303
13041304 return Result;
9494 }
9595
9696 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
97 bool ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const {
98 // If symbol visibility is hidden, the extra load is not needed if
99 // the symbol is definitely defined in the current translation unit.
100 bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage();
101 if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
97 bool
98 ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const {
99 if (RelocM == Reloc::Static)
102100 return false;
103 return !isStatic && (isDecl || GV->isWeakForLinker());
101
102 // GV with ghost linkage (in JIT lazy compilation mode) do not require an
103 // extra load from stub.
104 bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
105
106 if (!isTargetDarwin()) {
107 // Extra load is needed for all externally visible.
108 if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
109 return false;
110 return true;
111 } else {
112 if (RelocM == Reloc::PIC_) {
113 // If this is a strong reference to a definition, it is definitely not
114 // through a stub.
115 if (!isDecl && !GV->isWeakForLinker())
116 return false;
117
118 // Unless we have a symbol with hidden visibility, we have to go through a
119 // normal $non_lazy_ptr stub because this symbol might be resolved late.
120 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
121 return true;
122
123 // If symbol visibility is hidden, we have a stub for common symbol
124 // references and external declarations.
125 if (isDecl || GV->hasCommonLinkage())
126 // Hidden $non_lazy_ptr reference.
127 return true;
128
129 return false;
130 } else {
131 // If this is a strong reference to a definition, it is definitely not
132 // through a stub.
133 if (!isDecl && !GV->isWeakForLinker())
134 return false;
135
136 // Unless we have a symbol with hidden visibility, we have to go through a
137 // normal $non_lazy_ptr stub because this symbol might be resolved late.
138 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
139 return true;
140 }
141 }
142
143 return false;
104144 }
1414 #define ARMSUBTARGET_H
1515
1616 #include "llvm/Target/TargetInstrItineraries.h"
17 #include "llvm/Target/TargetMachine.h"
1718 #include "llvm/Target/TargetSubtarget.h"
1819 #include
1920
132133
133134 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect
134135 /// symbol.
135 bool GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const;
136 bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const;
136137 };
137138 } // End llvm namespace
138139
165165 Name = LSDAName.str();
166166 } else if (GV) {
167167 bool isIndirect = Subtarget->isTargetDarwin() &&
168 Subtarget->GVIsIndirectSymbol(GV,
169 TM.getRelocationModel() == Reloc::Static);
168 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
170169 if (!isIndirect)
171170 Name = Mang->getMangledName(GV);
172171 else {
305305 Suffix = "$stub";
306306 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
307307 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
308 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
309308 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
310309 Suffix = "$non_lazy_ptr";
311310
320319 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
321320 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
322321 GVStubs[Name] = Mang->getMangledName(GV);
323 else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
324 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
322 else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
325323 HiddenGVStubs[Name] = Mang->getMangledName(GV);
326324 else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
327325 FnStubs[Name] = Mang->getMangledName(GV);
359357 case X86II::MO_NO_FLAG: // No flag.
360358 break;
361359 case X86II::MO_DARWIN_NONLAZY:
362 case X86II::MO_DARWIN_HIDDEN_NONLAZY:
363360 case X86II::MO_DLLIMPORT:
364361 case X86II::MO_DARWIN_STUB:
365362 // These affect the name of the symbol, not any suffix.
6161 Suffix = "$stub";
6262 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
6363 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
64 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
6564 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
6665 Suffix = "$non_lazy_ptr";
6766
8382 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
8483 GVStubs[Name] = Mang->getMangledName(GV);
8584 break;
86 case X86II::MO_DARWIN_HIDDEN_NONLAZY:
8785 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
8886 HiddenGVStubs[Name] = Mang->getMangledName(GV);
8987 break;
168166
169167 // These affect the name of the symbol, not any suffix.
170168 case X86II::MO_DARWIN_NONLAZY:
171 case X86II::MO_DARWIN_HIDDEN_NONLAZY:
172169 case X86II::MO_DLLIMPORT:
173170 case X86II::MO_DARWIN_STUB:
174171 case X86II::MO_TLSGD:
169169 /// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub.
170170 MO_DARWIN_NONLAZY_PIC_BASE = 15,
171171
172 /// MO_DARWIN_HIDDEN_NONLAZY - On a symbol operand "FOO", this indicates
173 /// that the reference is actually to the "FOO$non_lazy_ptr" symbol, which
174 /// is a non-PIC-base-relative reference to a hidden dyld lazy pointer stub.
175 MO_DARWIN_HIDDEN_NONLAZY = 16,
176
177172 /// MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this
178173 /// indicates that the reference is actually to "FOO$non_lazy_ptr -PICBASE",
179174 /// which is a PIC-base-relative reference to a hidden dyld lazy pointer
180175 /// stub.
181 MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE = 17
176 MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE = 16
182177 };
183178 }
184179
192187 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref.
193188 case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref.
194189 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: // Hidden $non_lazy_ptr ref.
195 case X86II::MO_DARWIN_HIDDEN_NONLAZY: // Hidden $non_lazy_ptr ref.
196190 return true;
197191 default:
198192 return false;
107107 // normal $non_lazy_ptr stub because this symbol might be resolved late.
108108 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
109109 return X86II::MO_DARWIN_NONLAZY;
110
111 // If symbol visibility is hidden, we have a stub for common symbol
112 // references and external declarations.
113 if (isDecl || GV->hasCommonLinkage()) {
114 // Hidden $non_lazy_ptr reference.
115 return X86II::MO_DARWIN_HIDDEN_NONLAZY;
116 }
117
110
118111 // Otherwise, no stub.
119112 return X86II::MO_NO_FLAG;
120113 }
None ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 2
0 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | FileCheck %s
11
22 @x = weak hidden global i32 0 ; [#uses=1]
33
44 define i32 @t() nounwind readonly {
55 entry:
6 ; CHECK: t:
7 ; CHECK: ldr
8 ; CHECK-NEXT: ldr
69 %0 = load i32* @x, align 4 ; [#uses=1]
710 ret i32 %0
811 }
None ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 6
1 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep non_lazy_ptr
2 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep long | count 4
0 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 | FileCheck %s
31
42 @x = external hidden global i32 ; [#uses=1]
53 @y = extern_weak hidden global i32 ; [#uses=1]
64
75 define i32 @t() nounwind readonly {
86 entry:
7 ; CHECK: LCPI1_0:
8 ; CHECK-NEXT: .long _x
9 ; CHECK: LCPI1_1:
10 ; CHECK-NEXT: .long _y
11
912 %0 = load i32* @x, align 4 ; [#uses=1]
1013 %1 = load i32* @y, align 4 ; [#uses=1]
1114 %2 = add i32 %1, %0 ; [#uses=1]
None ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | \
1 ; RUN: grep .private_extern | count 2
0 ; RUN: llvm-as < %s | llc -mtriple=arm-linux | FileCheck %s -check-prefix=LINUX
1 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
22
3 %struct.Person = type { i32 }
43 @a = hidden global i32 0
54 @b = external global i32
65
6 define weak hidden void @t1() nounwind {
7 ; LINUX: .hidden t1
8 ; LINUX: t1:
79
8 define weak hidden void @_ZN6Person13privateMethodEv(%struct.Person* %this) {
10 ; DARWIN: .private_extern _t1
11 ; DARWIN: t1:
912 ret void
1013 }
1114
12 declare void @function(i32)
15 define weak void @t2() nounwind {
16 ; LINUX: t2:
17 ; LINUX: .hidden a
1318
14 define weak void @_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) {
19 ; DARWIN: t2:
20 ; DARWIN: .private_extern _a
1521 ret void
1622 }
17
None ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 3
1 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
2 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long | count 2
3 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s -check-prefix=X32
1 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | FileCheck %s -check-prefix=X64
42
53 @x = external hidden global i32 ; [#uses=1]
64 @y = extern_weak hidden global i32 ; [#uses=1]
75
86 define i32 @t() nounwind readonly {
97 entry:
8 ; X32: _t:
9 ; X32: movl _y, %eax
10
11 ; X64: _t:
12 ; X64: movl _y(%rip), %eax
13
1014 %0 = load i32* @x, align 4 ; [#uses=1]
1115 %1 = load i32* @y, align 4 ; [#uses=1]
1216 %2 = add i32 %1, %0 ; [#uses=1]
None ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
1 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long
2 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s
31
42 @x = common hidden global i32 0 ; [#uses=1]
53
64 define i32 @t() nounwind readonly {
75 entry:
6 ; CHECK: t:
7 ; CHECK: movl _x, %eax
8 ; CHECK: .comm _x,4
89 %0 = load i32* @x, align 4 ; [#uses=1]
910 ret i32 %0
1011 }
None ; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | \
1 ; RUN: grep .hidden | count 2
2 ; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8.8.0 | \
3 ; RUN: grep .private_extern | count 2
0 ; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | FileCheck %s -check-prefix=LINUX
1 ; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8 | FileCheck %s -check-prefix=DARWIN
42
5 %struct.Person = type { i32 }
63 @a = hidden global i32 0
74 @b = external global i32
85
6 define weak hidden void @t1() nounwind {
7 ; LINUX: .hidden t1
8 ; LINUX: t1:
99
10 define weak hidden void @_ZN6Person13privateMethodEv(%struct.Person* %this) {
10 ; DARWIN: .private_extern _t1
11 ; DARWIN: t1:
1112 ret void
1213 }
1314
14 declare void @function(i32)
15 define weak void @t2() nounwind {
16 ; LINUX: t2:
17 ; LINUX: .hidden a
1518
16 define weak void @_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) {
19 ; DARWIN: t2:
20 ; DARWIN: .private_extern _a
1721 ret void
1822 }
1923