1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Teach shouldAssumeDSOLocal about tls.

Fixes a fixme about handling other visibilities.

llvm-svn: 273921
This commit is contained in:
Rafael Espindola 2016-06-27 20:19:14 +00:00
parent d83587b695
commit bd0bb55f04
3 changed files with 43 additions and 31 deletions

View File

@ -651,33 +651,32 @@ bool llvm::shouldAssumeDSOLocal(Reloc::Model RM, const Triple &TT,
if (TT.isOSBinFormatCOFF())
return true;
if (RM == Reloc::Static)
return true;
if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility()))
return true;
if (TT.isOSBinFormatELF()) {
assert(RM != Reloc::DynamicNoPIC);
// Some linkers can use copy relocations with pie executables.
if (M.getPIELevel() != PIELevel::Default) {
if (CanUseCopyRelocWithPIE)
return true;
// If the symbol is defined, it cannot be preempted.
if (GV && !GV->isDeclarationForLinker())
return true;
return false;
}
// ELF supports preemption of other symbols.
return false;
if (TT.isOSBinFormatMachO()) {
if (RM == Reloc::Static)
return true;
return GV && GV->isStrongDefinitionForLinker();
}
assert(TT.isOSBinFormatMachO());
if (GV && GV->isStrongDefinitionForLinker())
return true;
assert(TT.isOSBinFormatELF());
assert(RM != Reloc::DynamicNoPIC);
bool IsExecutable =
RM == Reloc::Static || M.getPIELevel() != PIELevel::Default;
if (IsExecutable) {
// If the symbol is defined, it cannot be preempted.
if (GV && !GV->isDeclarationForLinker())
return true;
bool IsTLS = GV && GV->isThreadLocal();
// Check if we can use copy relocations.
if (!IsTLS && (RM == Reloc::Static || CanUseCopyRelocWithPIE))
return true;
}
// ELF supports preemption of other symbols.
return false;
}

View File

@ -13,6 +13,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
@ -106,22 +107,19 @@ static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
}
TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
bool isLocal = GV->hasLocalLinkage();
bool isDeclaration = GV->isDeclaration();
bool isPIC = getRelocationModel() == Reloc::PIC_;
bool isPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
// FIXME: what should we do for protected and internal visibility?
// For variables, is internal different from hidden?
bool isHidden = GV->hasHiddenVisibility();
bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
Reloc::Model RM = getRelocationModel();
bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
bool IsLocal = shouldAssumeDSOLocal(RM, TargetTriple, *GV->getParent(), GV);
TLSModel::Model Model;
if (isPIC && !isPIE) {
if (isLocal || isHidden)
if (IsSharedLibrary) {
if (IsLocal)
Model = TLSModel::LocalDynamic;
else
Model = TLSModel::GeneralDynamic;
} else {
if (!isDeclaration || isHidden)
if (IsLocal)
Model = TLSModel::LocalExec;
else
Model = TLSModel::InitialExec;

View File

@ -10,6 +10,7 @@
@i3 = internal thread_local global i32 15
@i4 = hidden thread_local global i32 15
@i5 = external hidden thread_local global i32
@i6 = external protected thread_local global i32
@s1 = thread_local global i16 15
@b1 = thread_local global i8 0
@b2 = thread_local(localexec) global i8 0
@ -438,3 +439,17 @@ entry:
ret i8* @b2
}
define i32* @f16() {
; X32_LINUX-LABEL: f16:
; X32_LINUX: movl %gs:0, %eax
; X32_LINUX-NEXT: leal i6@NTPOFF(%eax), %eax
; X32_LINUX-NEXT: ret
; X64_LINUX-LABEL: f16:
; X64_LINUX: movq %fs:0, %rax
; X64_LINUX-NEXT: leaq i6@TPOFF(%rax), %rax
; X64_LINUX-NEXT: ret
ret i32* @i6
}