From: Rafael Espindola Date: Mon, 27 Jun 2016 20:19:14 +0000 (+0000) Subject: Teach shouldAssumeDSOLocal about tls. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc84e94c11129347e63649f1a713ac0ebb183bad;p=llvm Teach shouldAssumeDSOLocal about tls. Fixes a fixme about handling other visibilities. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273921 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp index 73bd3d29eae..d3b3a9de110 100644 --- a/lib/CodeGen/Analysis.cpp +++ b/lib/CodeGen/Analysis.cpp @@ -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 (TT.isOSBinFormatMachO()) { + if (RM == Reloc::Static) + return true; + return GV && GV->isStrongDefinitionForLinker(); + } - // If the symbol is defined, it cannot be preempted. - if (GV && !GV->isDeclarationForLinker()) - return true; - return false; - } + assert(TT.isOSBinFormatELF()); + assert(RM != Reloc::DynamicNoPIC); - // ELF supports preemption of other symbols. - return false; - } + 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; - assert(TT.isOSBinFormatMachO()); - if (GV && GV->isStrongDefinitionForLinker()) - 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; } diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index b62471597e0..220f1f3183d 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -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; diff --git a/test/CodeGen/X86/tls.ll b/test/CodeGen/X86/tls.ll index 0f3d3adec4c..85c51e618b2 100644 --- a/test/CodeGen/X86/tls.ll +++ b/test/CodeGen/X86/tls.ll @@ -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 +}