]> granicus.if.org Git - llvm/commitdiff
Linker: Move special casing for available_externally in IRMover to clients. NFCI.
authorPeter Collingbourne <peter@pcc.me.uk>
Thu, 2 Feb 2017 05:12:15 +0000 (05:12 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Thu, 2 Feb 2017 05:12:15 +0000 (05:12 +0000)
The goal is to simplify the semantic model for clients of IRMover.

Differential Revision: https://reviews.llvm.org/D29435

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

lib/LTO/LTO.cpp
lib/Linker/IRMover.cpp
lib/Linker/LinkModules.cpp
test/LTO/Resolution/X86/Inputs/link-odr-availextern-ae.ll [new file with mode: 0644]
test/LTO/Resolution/X86/link-odr-availextern.ll [new file with mode: 0644]
test/Linker/available_externally_a.ll

index e602c64337c33bc618e9f3b6fdb1e64642eee611..4d0c039891eae528f43deb583bf9d0c596c1ceb2 100644 (file)
@@ -455,20 +455,29 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
     SymbolResolution Res = *ResI++;
     addSymbolToGlobalRes(Used, Sym, Res, 0);
 
-    if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
-      continue;
-    if (Res.Prevailing && Sym.isGV()) {
+    if (Sym.isGV()) {
       GlobalValue *GV = Sym.getGV();
-      Keep.push_back(GV);
-      switch (GV->getLinkage()) {
-      default:
-        break;
-      case GlobalValue::LinkOnceAnyLinkage:
-        GV->setLinkage(GlobalValue::WeakAnyLinkage);
-        break;
-      case GlobalValue::LinkOnceODRLinkage:
-        GV->setLinkage(GlobalValue::WeakODRLinkage);
-        break;
+      if (Res.Prevailing) {
+        if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
+          continue;
+        Keep.push_back(GV);
+        switch (GV->getLinkage()) {
+        default:
+          break;
+        case GlobalValue::LinkOnceAnyLinkage:
+          GV->setLinkage(GlobalValue::WeakAnyLinkage);
+          break;
+        case GlobalValue::LinkOnceODRLinkage:
+          GV->setLinkage(GlobalValue::WeakODRLinkage);
+          break;
+        }
+      } else if (GV->hasAvailableExternallyLinkage()) {
+        // We can link available_externally symbols even if they are
+        // non-prevailing.
+        GlobalValue *CombinedGV =
+            RegularLTO.CombinedModule->getNamedValue(GV->getName());
+        if (!CombinedGV || CombinedGV->isDeclaration())
+          Keep.push_back(GV);
       }
     }
     // Common resolution: collect the maximum size/alignment over all commons.
index 9f3cfc0eace45c7795a132ccf889a7c062c42328..468d86d6e0d7030c235003516c15aa2df988bd30 100644 (file)
@@ -870,9 +870,6 @@ bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) {
   if (DGV && !DGV->isDeclarationForLinker())
     return false;
 
-  if (SGV.hasAvailableExternallyLinkage())
-    return true;
-
   if (SGV.isDeclaration() || DoneLinkingBodies)
     return false;
 
index cf2c4ccf523e6b9e695d9680ea21cc0539882628..7ff84db07020a72a5bfe4763854c5909f1de13e8 100644 (file)
@@ -425,7 +425,8 @@ void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) {
     return;
 
   // Add these to the internalize list
-  if (!GV.hasLinkOnceLinkage() && !shouldLinkOnlyNeeded())
+  if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() &&
+      !shouldLinkOnlyNeeded())
     return;
 
   if (shouldInternalizeLinkedSymbols())
diff --git a/test/LTO/Resolution/X86/Inputs/link-odr-availextern-ae.ll b/test/LTO/Resolution/X86/Inputs/link-odr-availextern-ae.ll
new file mode 100644 (file)
index 0000000..f2d180a
--- /dev/null
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define available_externally i32 @f() {
+  ret i32 2
+}
diff --git a/test/LTO/Resolution/X86/link-odr-availextern.ll b/test/LTO/Resolution/X86/link-odr-availextern.ll
new file mode 100644 (file)
index 0000000..4af79b6
--- /dev/null
@@ -0,0 +1,25 @@
+; Tests for correct behavior for non-prevailing resolutions in cases involving
+; *_odr and available_externally linkages.
+
+; RUN: llvm-as %s -o %t1
+; RUN: llvm-as %S/Inputs/link-odr-availextern-ae.ll -o %t2ae
+
+; RUN: llvm-lto2 -o %t3 %t1 %t2ae -r %t1,f,p -r %t2ae,f, -save-temps
+; RUN: llvm-dis < %t3.0.0.preopt.bc -o - | FileCheck --check-prefix=PREVAILING %s
+
+; RUN: llvm-lto2 -o %t3 %t2ae %t1 -r %t1,f,p -r %t2ae,f, -save-temps
+; RUN: llvm-dis < %t3.0.0.preopt.bc -o - | FileCheck --check-prefix=PREVAILING %s
+
+; RUN: llvm-lto2 -o %t3 %t2ae -r %t2ae,f, -save-temps
+; RUN: llvm-dis < %t3.0.0.preopt.bc -o - | FileCheck --check-prefix=NONPREVAILING %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; PREVAILING: define weak_odr i32 @f()
+; PREVAILING-NEXT: ret i32 1
+; NONPREVAILING: define available_externally i32 @f()
+; NONPREVAILING-NEXT: ret i32 2
+define linkonce_odr i32 @f() {
+  ret i32 1
+}
index 3ae4ce29140afa80e7d3e74fbbc8be9d7b6da30d..7a000b6a4aa5962e759305c868e8893b7b6bed0d 100644 (file)
@@ -1,5 +1,7 @@
 ; RUN: llvm-link %s %p/available_externally_b.ll -S -o - | FileCheck %s
+; RUN: llvm-link %s -S -o - | FileCheck --check-prefix=AE-ONLY %s
 
 @foo = available_externally unnamed_addr constant i32 0
 
 ; CHECK: @foo = hidden unnamed_addr constant i32 0
+; AE-ONLY-NOT: @foo