]> granicus.if.org Git - llvm/commitdiff
LTO: Link non-prevailing weak_odr or linkonce_odr globals into the combined module...
authorPeter Collingbourne <peter@pcc.me.uk>
Thu, 2 Feb 2017 05:22:42 +0000 (05:22 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Thu, 2 Feb 2017 05:22:42 +0000 (05:22 +0000)
These linkages mean that the ultimately prevailing symbol will have the same
semantics as any non-prevailing copy of the symbol, so we are free to ignore
the linker's resolution.

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

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

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

index 4d0c039891eae528f43deb583bf9d0c596c1ceb2..df19ded398d25b1e67bd068873b0be56e7204830 100644 (file)
@@ -446,6 +446,11 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
     if (GV.hasAppendingLinkage())
       Keep.push_back(&GV);
 
+  DenseSet<GlobalObject *> AliasedGlobals;
+  for (auto &GA : M.aliases())
+    if (GlobalObject *GO = GA.getBaseObject())
+      AliasedGlobals.insert(GO);
+
   for (const InputFile::Symbol &Sym :
        make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab,
                                              nullptr),
@@ -471,13 +476,21 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
           GV->setLinkage(GlobalValue::WeakODRLinkage);
           break;
         }
-      } else if (GV->hasAvailableExternallyLinkage()) {
-        // We can link available_externally symbols even if they are
-        // non-prevailing.
+      } else if (isa<GlobalObject>(GV) &&
+                 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
+                  GV->hasAvailableExternallyLinkage()) &&
+                 !AliasedGlobals.count(cast<GlobalObject>(GV))) {
+        // Either of the above three types of linkage indicates that the
+        // chosen prevailing symbol will have the same semantics as this copy of
+        // the symbol, so we can link it with available_externally linkage. We
+        // only need to do this if the symbol is undefined.
         GlobalValue *CombinedGV =
             RegularLTO.CombinedModule->getNamedValue(GV->getName());
-        if (!CombinedGV || CombinedGV->isDeclaration())
+        if (!CombinedGV || CombinedGV->isDeclaration()) {
           Keep.push_back(GV);
+          GV->setLinkage(GlobalValue::AvailableExternallyLinkage);
+          cast<GlobalObject>(GV)->setComdat(nullptr);
+        }
       }
     }
     // Common resolution: collect the maximum size/alignment over all commons.
diff --git a/test/LTO/Resolution/X86/Inputs/link-odr-availextern-odr.ll b/test/LTO/Resolution/X86/Inputs/link-odr-availextern-odr.ll
new file mode 100644 (file)
index 0000000..76e745a
--- /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 linkonce_odr i32 @f() {
+  ret i32 2
+}
index 4af79b64b2a90b2bc180251ca37220b5a4223f35..5a3cc3884db1188198f42185288e5ddc64181192 100644 (file)
@@ -3,16 +3,29 @@
 
 ; RUN: llvm-as %s -o %t1
 ; RUN: llvm-as %S/Inputs/link-odr-availextern-ae.ll -o %t2ae
+; RUN: llvm-as %S/Inputs/link-odr-availextern-odr.ll -o %t2odr
 
 ; 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 %t1 %t2odr -r %t1,f,p -r %t2odr,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 %t2odr %t1 -r %t1,f,p -r %t2odr,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
 
+; RUN: llvm-lto2 -o %t3 %t2odr -r %t2odr,f, -save-temps
+; RUN: llvm-dis < %t3.0.0.preopt.bc -o - | FileCheck --check-prefix=NONPREVAILING %s
+
+; RUN: llvm-lto2 -o %t3 %t2odr %t1 -r %t1,f, -r %t2odr,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"