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
This commit is contained in:
Evan Cheng 2009-09-03 07:04:02 +00:00
parent 8aa9fba7cb
commit 63476a8040
14 changed files with 99 additions and 58 deletions

View File

@ -1299,7 +1299,7 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
} }
if (Subtarget->GVIsIndirectSymbol(GV, RelocM == Reloc::Static)) if (Subtarget->GVIsIndirectSymbol(GV, RelocM))
Result = DAG.getLoad(PtrVT, dl, Chain, Result, NULL, 0); Result = DAG.getLoad(PtrVT, dl, Chain, Result, NULL, 0);
return Result; return Result;

View File

@ -95,11 +95,51 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
} }
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
bool ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const { bool
// If symbol visibility is hidden, the extra load is not needed if ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const {
// the symbol is definitely defined in the current translation unit. if (RelocM == Reloc::Static)
bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage();
if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
return false; return false;
return !isStatic && (isDecl || GV->isWeakForLinker());
// GV with ghost linkage (in JIT lazy compilation mode) do not require an
// extra load from stub.
bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
if (!isTargetDarwin()) {
// Extra load is needed for all externally visible.
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
return false;
return true;
} else {
if (RelocM == Reloc::PIC_) {
// If this is a strong reference to a definition, it is definitely not
// through a stub.
if (!isDecl && !GV->isWeakForLinker())
return false;
// Unless we have a symbol with hidden visibility, we have to go through a
// normal $non_lazy_ptr stub because this symbol might be resolved late.
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
return true;
// If symbol visibility is hidden, we have a stub for common symbol
// references and external declarations.
if (isDecl || GV->hasCommonLinkage())
// Hidden $non_lazy_ptr reference.
return true;
return false;
} else {
// If this is a strong reference to a definition, it is definitely not
// through a stub.
if (!isDecl && !GV->isWeakForLinker())
return false;
// Unless we have a symbol with hidden visibility, we have to go through a
// normal $non_lazy_ptr stub because this symbol might be resolved late.
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
return true;
}
}
return false;
} }

View File

@ -15,6 +15,7 @@
#define ARMSUBTARGET_H #define ARMSUBTARGET_H
#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetInstrItineraries.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetSubtarget.h" #include "llvm/Target/TargetSubtarget.h"
#include <string> #include <string>
@ -133,7 +134,7 @@ protected:
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect
/// symbol. /// symbol.
bool GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const; bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const;
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -166,8 +166,7 @@ namespace {
Name = LSDAName.str(); Name = LSDAName.str();
} else if (GV) { } else if (GV) {
bool isIndirect = Subtarget->isTargetDarwin() && bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
TM.getRelocationModel() == Reloc::Static);
if (!isIndirect) if (!isIndirect)
Name = Mang->getMangledName(GV); Name = Mang->getMangledName(GV);
else { else {

View File

@ -306,7 +306,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
Suffix = "$stub"; Suffix = "$stub";
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
Suffix = "$non_lazy_ptr"; Suffix = "$non_lazy_ptr";
@ -321,8 +320,7 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
GVStubs[Name] = Mang->getMangledName(GV); GVStubs[Name] = Mang->getMangledName(GV);
else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY || else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
HiddenGVStubs[Name] = Mang->getMangledName(GV); HiddenGVStubs[Name] = Mang->getMangledName(GV);
else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
FnStubs[Name] = Mang->getMangledName(GV); FnStubs[Name] = Mang->getMangledName(GV);
@ -360,7 +358,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
case X86II::MO_NO_FLAG: // No flag. case X86II::MO_NO_FLAG: // No flag.
break; break;
case X86II::MO_DARWIN_NONLAZY: case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
case X86II::MO_DLLIMPORT: case X86II::MO_DLLIMPORT:
case X86II::MO_DARWIN_STUB: case X86II::MO_DARWIN_STUB:
// These affect the name of the symbol, not any suffix. // These affect the name of the symbol, not any suffix.

View File

@ -62,7 +62,6 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
Suffix = "$stub"; Suffix = "$stub";
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
Suffix = "$non_lazy_ptr"; Suffix = "$non_lazy_ptr";
@ -84,7 +83,6 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
case X86II::MO_DARWIN_NONLAZY_PIC_BASE: case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
GVStubs[Name] = Mang->getMangledName(GV); GVStubs[Name] = Mang->getMangledName(GV);
break; break;
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
HiddenGVStubs[Name] = Mang->getMangledName(GV); HiddenGVStubs[Name] = Mang->getMangledName(GV);
break; break;
@ -169,7 +167,6 @@ MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
// These affect the name of the symbol, not any suffix. // These affect the name of the symbol, not any suffix.
case X86II::MO_DARWIN_NONLAZY: case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
case X86II::MO_DLLIMPORT: case X86II::MO_DLLIMPORT:
case X86II::MO_DARWIN_STUB: case X86II::MO_DARWIN_STUB:
case X86II::MO_TLSGD: case X86II::MO_TLSGD:

View File

@ -170,16 +170,11 @@ namespace X86II {
/// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub. /// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub.
MO_DARWIN_NONLAZY_PIC_BASE = 15, MO_DARWIN_NONLAZY_PIC_BASE = 15,
/// MO_DARWIN_HIDDEN_NONLAZY - On a symbol operand "FOO", this indicates
/// that the reference is actually to the "FOO$non_lazy_ptr" symbol, which
/// is a non-PIC-base-relative reference to a hidden dyld lazy pointer stub.
MO_DARWIN_HIDDEN_NONLAZY = 16,
/// MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this /// MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this
/// indicates that the reference is actually to "FOO$non_lazy_ptr -PICBASE", /// indicates that the reference is actually to "FOO$non_lazy_ptr -PICBASE",
/// which is a PIC-base-relative reference to a hidden dyld lazy pointer /// which is a PIC-base-relative reference to a hidden dyld lazy pointer
/// stub. /// stub.
MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE = 17 MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE = 16
}; };
} }
@ -193,7 +188,6 @@ inline static bool isGlobalStubReference(unsigned char TargetFlag) {
case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref.
case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref.
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: // Hidden $non_lazy_ptr ref. case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: // Hidden $non_lazy_ptr ref.
case X86II::MO_DARWIN_HIDDEN_NONLAZY: // Hidden $non_lazy_ptr ref.
return true; return true;
default: default:
return false; return false;

View File

@ -108,14 +108,7 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
// normal $non_lazy_ptr stub because this symbol might be resolved late. // normal $non_lazy_ptr stub because this symbol might be resolved late.
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
return X86II::MO_DARWIN_NONLAZY; return X86II::MO_DARWIN_NONLAZY;
// If symbol visibility is hidden, we have a stub for common symbol
// references and external declarations.
if (isDecl || GV->hasCommonLinkage()) {
// Hidden $non_lazy_ptr reference.
return X86II::MO_DARWIN_HIDDEN_NONLAZY;
}
// Otherwise, no stub. // Otherwise, no stub.
return X86II::MO_NO_FLAG; return X86II::MO_NO_FLAG;
} }

View File

@ -1,9 +1,12 @@
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 2 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | FileCheck %s
@x = weak hidden global i32 0 ; <i32*> [#uses=1] @x = weak hidden global i32 0 ; <i32*> [#uses=1]
define i32 @t() nounwind readonly { define i32 @t() nounwind readonly {
entry: entry:
; CHECK: t:
; CHECK: ldr
; CHECK-NEXT: ldr
%0 = load i32* @x, align 4 ; <i32> [#uses=1] %0 = load i32* @x, align 4 ; <i32> [#uses=1]
ret i32 %0 ret i32 %0
} }

View File

@ -1,12 +1,15 @@
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 6 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 | FileCheck %s
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep non_lazy_ptr
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep long | count 4
@x = external hidden global i32 ; <i32*> [#uses=1] @x = external hidden global i32 ; <i32*> [#uses=1]
@y = extern_weak hidden global i32 ; <i32*> [#uses=1] @y = extern_weak hidden global i32 ; <i32*> [#uses=1]
define i32 @t() nounwind readonly { define i32 @t() nounwind readonly {
entry: entry:
; CHECK: LCPI1_0:
; CHECK-NEXT: .long _x
; CHECK: LCPI1_1:
; CHECK-NEXT: .long _y
%0 = load i32* @x, align 4 ; <i32> [#uses=1] %0 = load i32* @x, align 4 ; <i32> [#uses=1]
%1 = load i32* @y, align 4 ; <i32> [#uses=1] %1 = load i32* @y, align 4 ; <i32> [#uses=1]
%2 = add i32 %1, %0 ; <i32> [#uses=1] %2 = add i32 %1, %0 ; <i32> [#uses=1]

View File

@ -1,18 +1,23 @@
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | \ ; RUN: llvm-as < %s | llc -mtriple=arm-linux | FileCheck %s -check-prefix=LINUX
; RUN: grep .private_extern | count 2 ; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
%struct.Person = type { i32 }
@a = hidden global i32 0 @a = hidden global i32 0
@b = external global i32 @b = external global i32
define weak hidden void @t1() nounwind {
; LINUX: .hidden t1
; LINUX: t1:
define weak hidden void @_ZN6Person13privateMethodEv(%struct.Person* %this) { ; DARWIN: .private_extern _t1
; DARWIN: t1:
ret void ret void
} }
declare void @function(i32) define weak void @t2() nounwind {
; LINUX: t2:
; LINUX: .hidden a
define weak void @_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) { ; DARWIN: t2:
; DARWIN: .private_extern _a
ret void ret void
} }

View File

@ -1,13 +1,17 @@
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 3 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s -check-prefix=X32
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | FileCheck %s -check-prefix=X64
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long | count 2
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
@x = external hidden global i32 ; <i32*> [#uses=1] @x = external hidden global i32 ; <i32*> [#uses=1]
@y = extern_weak hidden global i32 ; <i32*> [#uses=1] @y = extern_weak hidden global i32 ; <i32*> [#uses=1]
define i32 @t() nounwind readonly { define i32 @t() nounwind readonly {
entry: entry:
; X32: _t:
; X32: movl _y, %eax
; X64: _t:
; X64: movl _y(%rip), %eax
%0 = load i32* @x, align 4 ; <i32> [#uses=1] %0 = load i32* @x, align 4 ; <i32> [#uses=1]
%1 = load i32* @y, align 4 ; <i32> [#uses=1] %1 = load i32* @y, align 4 ; <i32> [#uses=1]
%2 = add i32 %1, %0 ; <i32> [#uses=1] %2 = add i32 %1, %0 ; <i32> [#uses=1]

View File

@ -1,11 +1,12 @@
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm
@x = common hidden global i32 0 ; <i32*> [#uses=1] @x = common hidden global i32 0 ; <i32*> [#uses=1]
define i32 @t() nounwind readonly { define i32 @t() nounwind readonly {
entry: entry:
; CHECK: t:
; CHECK: movl _x, %eax
; CHECK: .comm _x,4
%0 = load i32* @x, align 4 ; <i32> [#uses=1] %0 = load i32* @x, align 4 ; <i32> [#uses=1]
ret i32 %0 ret i32 %0
} }

View File

@ -1,20 +1,24 @@
; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | \ ; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | FileCheck %s -check-prefix=LINUX
; RUN: grep .hidden | count 2 ; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8 | FileCheck %s -check-prefix=DARWIN
; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8.8.0 | \
; RUN: grep .private_extern | count 2
%struct.Person = type { i32 }
@a = hidden global i32 0 @a = hidden global i32 0
@b = external global i32 @b = external global i32
define weak hidden void @t1() nounwind {
; LINUX: .hidden t1
; LINUX: t1:
define weak hidden void @_ZN6Person13privateMethodEv(%struct.Person* %this) { ; DARWIN: .private_extern _t1
; DARWIN: t1:
ret void ret void
} }
declare void @function(i32) define weak void @t2() nounwind {
; LINUX: t2:
; LINUX: .hidden a
define weak void @_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) { ; DARWIN: t2:
; DARWIN: .private_extern _a
ret void ret void
} }