]> granicus.if.org Git - llvm/commitdiff
Teach shouldAssumeDSOLocal about tls.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 27 Jun 2016 20:19:14 +0000 (20:19 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 27 Jun 2016 20:19:14 +0000 (20:19 +0000)
Fixes a fixme about handling other visibilities.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273921 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Analysis.cpp
lib/Target/TargetMachine.cpp
test/CodeGen/X86/tls.ll

index 73bd3d29eae59a97fd8d839ede3725b01fe971f7..d3b3a9de110baaec1808e5bd4212c77d48499dfe 100644 (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 (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;
 }
 
index b62471597e07bd46fe540a31c304b5deb94e26ef..220f1f3183d9653d06500471e8bc4551ce8dc779 100644 (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;
index 0f3d3adec4c3c0698bb7634aeb765a2dba74b152..85c51e618b2a78a310da8f51c3b0ae52551494de 100644 (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
+}