Fix lazy linking of comdat members.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 24 Mar 2016 00:06:03 +0000 (00:06 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 24 Mar 2016 00:06:03 +0000 (00:06 +0000)
If not for lazy linking of linkonce GVs, comdats are just a
preprocessing before symbol resolution.

Lazy linking complicates it since when we pick a visible member of
comdat, we have to make sure the rest of it passes symbol resolution
too.

llvm-svn: 264223

llvm/lib/Linker/LinkModules.cpp
llvm/test/Linker/comdat9.ll

index d3c3ea3..9ee3fb3 100644 (file)
@@ -76,8 +76,8 @@ class ModuleLinker {
       ComdatsChosen;
   bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK,
                        bool &LinkFromSrc);
-  // Keep track of the global value members of each comdat in source.
-  DenseMap<const Comdat *, std::vector<GlobalValue *>> ComdatMembers;
+  // Keep track of the lazy linked global members of each comdat in source.
+  DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers;
 
   /// Given a global in the source module, return the global in the
   /// destination module that is being linked to, if any.
@@ -446,8 +446,8 @@ void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) {
   const Comdat *SC = GV.getComdat();
   if (!SC)
     return;
-  for (GlobalValue *GV2 : ComdatMembers[SC]) {
-    if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols())
+  for (GlobalValue *GV2 : LazyComdatMembers[SC]) {
+    if (shouldInternalizeLinkedSymbols())
       Internalize.insert(GV2->getName());
     Add(*GV2);
   }
@@ -533,16 +533,19 @@ bool ModuleLinker::run() {
   }
 
   for (GlobalVariable &GV : SrcM->globals())
-    if (const Comdat *SC = GV.getComdat())
-      ComdatMembers[SC].push_back(&GV);
+    if (GV.hasLinkOnceLinkage())
+      if (const Comdat *SC = GV.getComdat())
+        LazyComdatMembers[SC].push_back(&GV);
 
   for (Function &SF : *SrcM)
-    if (const Comdat *SC = SF.getComdat())
-      ComdatMembers[SC].push_back(&SF);
+    if (SF.hasLinkOnceLinkage())
+      if (const Comdat *SC = SF.getComdat())
+        LazyComdatMembers[SC].push_back(&SF);
 
   for (GlobalAlias &GA : SrcM->aliases())
-    if (const Comdat *SC = GA.getComdat())
-      ComdatMembers[SC].push_back(&GA);
+    if (GA.hasLinkOnceLinkage())
+      if (const Comdat *SC = GA.getComdat())
+        LazyComdatMembers[SC].push_back(&GA);
 
   // Insert all of the globals in src into the DstM module... without linking
   // initializers (which could refer to functions not yet mapped over).
@@ -563,9 +566,8 @@ bool ModuleLinker::run() {
     const Comdat *SC = GV->getComdat();
     if (!SC)
       continue;
-    for (GlobalValue *GV2 : ComdatMembers[SC])
-      if (GV2->hasInternalLinkage())
-        ValuesToLink.insert(GV2);
+    for (GlobalValue *GV2 : LazyComdatMembers[SC])
+      ValuesToLink.insert(GV2);
   }
 
   if (shouldInternalizeLinkedSymbols()) {
index 4f6f2cf..6f177e6 100644 (file)
@@ -11,7 +11,7 @@ define internal void @f() comdat($c) {
 ; CHECK-DAG: define internal void @f() comdat($c)
 
 $f2 = comdat largest
-define internal void @f2() comdat($f2) {
+define linkonce_odr void @f2() comdat($f2) {
   ret void
 }
 define void @f3() comdat($f2) {
@@ -19,4 +19,4 @@ define void @f3() comdat($f2) {
 }
 
 ; CHECK-DAG: $f2 = comdat largest
-; CHECK-DAG: define internal void @f2() comdat {
+; CHECK-DAG: define linkonce_odr void @f2()