mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
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:
parent
8aa9fba7cb
commit
63476a8040
@ -1299,7 +1299,7 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
|
||||
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);
|
||||
|
||||
return Result;
|
||||
|
@ -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.
|
||||
bool ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const {
|
||||
// If symbol visibility is hidden, the extra load is not needed if
|
||||
// the symbol is definitely defined in the current translation unit.
|
||||
bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage();
|
||||
if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
|
||||
bool
|
||||
ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const {
|
||||
if (RelocM == Reloc::Static)
|
||||
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;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define ARMSUBTARGET_H
|
||||
|
||||
#include "llvm/Target/TargetInstrItineraries.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetSubtarget.h"
|
||||
#include <string>
|
||||
|
||||
@ -133,7 +134,7 @@ protected:
|
||||
|
||||
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect
|
||||
/// symbol.
|
||||
bool GVIsIndirectSymbol(GlobalValue *GV, bool isStatic) const;
|
||||
bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const;
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -166,8 +166,7 @@ namespace {
|
||||
Name = LSDAName.str();
|
||||
} else if (GV) {
|
||||
bool isIndirect = Subtarget->isTargetDarwin() &&
|
||||
Subtarget->GVIsIndirectSymbol(GV,
|
||||
TM.getRelocationModel() == Reloc::Static);
|
||||
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
|
||||
if (!isIndirect)
|
||||
Name = Mang->getMangledName(GV);
|
||||
else {
|
||||
|
@ -306,7 +306,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
|
||||
Suffix = "$stub";
|
||||
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
|
||||
Suffix = "$non_lazy_ptr";
|
||||
|
||||
@ -321,8 +320,7 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
|
||||
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
|
||||
GVStubs[Name] = Mang->getMangledName(GV);
|
||||
else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
|
||||
else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
|
||||
HiddenGVStubs[Name] = Mang->getMangledName(GV);
|
||||
else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
|
||||
FnStubs[Name] = Mang->getMangledName(GV);
|
||||
@ -360,7 +358,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
|
||||
case X86II::MO_NO_FLAG: // No flag.
|
||||
break;
|
||||
case X86II::MO_DARWIN_NONLAZY:
|
||||
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
|
||||
case X86II::MO_DLLIMPORT:
|
||||
case X86II::MO_DARWIN_STUB:
|
||||
// These affect the name of the symbol, not any suffix.
|
||||
|
@ -62,7 +62,6 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
|
||||
Suffix = "$stub";
|
||||
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
|
||||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
|
||||
Suffix = "$non_lazy_ptr";
|
||||
|
||||
@ -84,7 +83,6 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
|
||||
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
|
||||
GVStubs[Name] = Mang->getMangledName(GV);
|
||||
break;
|
||||
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
|
||||
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
|
||||
HiddenGVStubs[Name] = Mang->getMangledName(GV);
|
||||
break;
|
||||
@ -169,7 +167,6 @@ MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
|
||||
|
||||
// These affect the name of the symbol, not any suffix.
|
||||
case X86II::MO_DARWIN_NONLAZY:
|
||||
case X86II::MO_DARWIN_HIDDEN_NONLAZY:
|
||||
case X86II::MO_DLLIMPORT:
|
||||
case X86II::MO_DARWIN_STUB:
|
||||
case X86II::MO_TLSGD:
|
||||
|
@ -170,16 +170,11 @@ namespace X86II {
|
||||
/// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub.
|
||||
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
|
||||
/// 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
|
||||
/// 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: // Normal $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;
|
||||
default:
|
||||
return false;
|
||||
|
@ -108,14 +108,7 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
|
||||
// normal $non_lazy_ptr stub because this symbol might be resolved late.
|
||||
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
|
||||
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.
|
||||
return X86II::MO_NO_FLAG;
|
||||
}
|
||||
|
@ -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]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
; CHECK: t:
|
||||
; CHECK: ldr
|
||||
; CHECK-NEXT: ldr
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
ret i32 %0
|
||||
}
|
||||
|
@ -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-darwin | grep non_lazy_ptr
|
||||
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep long | count 4
|
||||
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 | FileCheck %s
|
||||
|
||||
@x = external hidden global i32 ; <i32*> [#uses=1]
|
||||
@y = extern_weak hidden global i32 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
; CHECK: LCPI1_0:
|
||||
; CHECK-NEXT: .long _x
|
||||
; CHECK: LCPI1_1:
|
||||
; CHECK-NEXT: .long _y
|
||||
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
%1 = load i32* @y, align 4 ; <i32> [#uses=1]
|
||||
%2 = add i32 %1, %0 ; <i32> [#uses=1]
|
||||
|
@ -1,18 +1,23 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | \
|
||||
; RUN: grep .private_extern | count 2
|
||||
; RUN: llvm-as < %s | llc -mtriple=arm-linux | FileCheck %s -check-prefix=LINUX
|
||||
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
|
||||
|
||||
%struct.Person = type { i32 }
|
||||
@a = hidden global i32 0
|
||||
@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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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 | grep non_lazy_ptr
|
||||
; 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
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s -check-prefix=X32
|
||||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | FileCheck %s -check-prefix=X64
|
||||
|
||||
@x = external hidden global i32 ; <i32*> [#uses=1]
|
||||
@y = extern_weak hidden global i32 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
; X32: _t:
|
||||
; X32: movl _y, %eax
|
||||
|
||||
; X64: _t:
|
||||
; X64: movl _y(%rip), %eax
|
||||
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
%1 = load i32* @y, align 4 ; <i32> [#uses=1]
|
||||
%2 = add i32 %1, %0 ; <i32> [#uses=1]
|
||||
|
@ -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 | grep long
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | FileCheck %s
|
||||
|
||||
@x = common hidden global i32 0 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
; CHECK: t:
|
||||
; CHECK: movl _x, %eax
|
||||
; CHECK: .comm _x,4
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
ret i32 %0
|
||||
}
|
||||
|
@ -1,20 +1,24 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | \
|
||||
; RUN: grep .hidden | count 2
|
||||
; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8.8.0 | \
|
||||
; RUN: grep .private_extern | count 2
|
||||
; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | FileCheck %s -check-prefix=LINUX
|
||||
; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin8 | FileCheck %s -check-prefix=DARWIN
|
||||
|
||||
%struct.Person = type { i32 }
|
||||
@a = hidden global i32 0
|
||||
@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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user