[llvm] r318805 - Object: Improve COFF irsymtab comdat representation.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 21 14:06:20 PST 2017


Author: pcc
Date: Tue Nov 21 14:06:20 2017
New Revision: 318805

URL: http://llvm.org/viewvc/llvm-project?rev=318805&view=rev
Log:
Object: Improve COFF irsymtab comdat representation.

Change the representation of COFF comdats so that a COFF linker
is able to accurately resolve comdats between IR and native object
files. Specifically, apply name mangling to comdat names consistently
with native object files, and do not export comdats with an internal
leader because they do not affect symbol resolution.

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

Modified:
    llvm/trunk/lib/Object/IRSymtab.cpp
    llvm/trunk/test/LTO/Resolution/X86/symtab.ll

Modified: llvm/trunk/lib/Object/IRSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/IRSymtab.cpp?rev=318805&r1=318804&r2=318805&view=diff
==============================================================================
--- llvm/trunk/lib/Object/IRSymtab.cpp (original)
+++ llvm/trunk/lib/Object/IRSymtab.cpp Tue Nov 21 14:06:20 2017
@@ -72,7 +72,7 @@ struct Builder {
           BumpPtrAllocator &Alloc)
       : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {}
 
-  DenseMap<const Comdat *, unsigned> ComdatMap;
+  DenseMap<const Comdat *, int> ComdatMap;
   Mangler Mang;
   Triple TT;
 
@@ -97,6 +97,8 @@ struct Builder {
                   reinterpret_cast<const char *>(Objs.data() + Objs.size()));
   }
 
+  Expected<int> getComdatIndex(const Comdat *C, const Module *M);
+
   Error addModule(Module *M);
   Error addSymbol(const ModuleSymbolTable &Msymtab,
                   const SmallPtrSet<GlobalValue *, 8> &Used,
@@ -140,6 +142,35 @@ Error Builder::addModule(Module *M) {
   return Error::success();
 }
 
+Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
+  auto P = ComdatMap.insert(std::make_pair(C, Comdats.size()));
+  if (P.second) {
+    std::string Name;
+    if (TT.isOSBinFormatCOFF()) {
+      const GlobalValue *GV = M->getNamedValue(C->getName());
+      if (!GV)
+        return make_error<StringError>("Could not find leader",
+                                       inconvertibleErrorCode());
+      // Internal leaders do not affect symbol resolution, therefore they do not
+      // appear in the symbol table.
+      if (GV->hasLocalLinkage()) {
+        P.first->second = -1;
+        return -1;
+      }
+      llvm::raw_string_ostream OS(Name);
+      Mang.getNameWithPrefix(OS, GV, false);
+    } else {
+      Name = C->getName();
+    }
+
+    storage::Comdat Comdat;
+    setStr(Comdat.Name, Saver.save(Name));
+    Comdats.push_back(Comdat);
+  }
+
+  return P.first->second;
+}
+
 Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
                          const SmallPtrSet<GlobalValue *, 8> &Used,
                          ModuleSymbolTable::Symbol Msym) {
@@ -216,14 +247,10 @@ Error Builder::addSymbol(const ModuleSym
     return make_error<StringError>("Unable to determine comdat of alias!",
                                    inconvertibleErrorCode());
   if (const Comdat *C = Base->getComdat()) {
-    auto P = ComdatMap.insert(std::make_pair(C, Comdats.size()));
-    Sym.ComdatIndex = P.first->second;
-
-    if (P.second) {
-      storage::Comdat Comdat;
-      setStr(Comdat.Name, C->getName());
-      Comdats.push_back(Comdat);
-    }
+    Expected<int> ComdatIndexOrErr = getComdatIndex(C, GV->getParent());
+    if (!ComdatIndexOrErr)
+      return ComdatIndexOrErr.takeError();
+    Sym.ComdatIndex = *ComdatIndexOrErr;
   }
 
   if (TT.isOSBinFormatCOFF()) {

Modified: llvm/trunk/test/LTO/Resolution/X86/symtab.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/Resolution/X86/symtab.ll?rev=318805&r1=318804&r2=318805&view=diff
==============================================================================
--- llvm/trunk/test/LTO/Resolution/X86/symtab.ll (original)
+++ llvm/trunk/test/LTO/Resolution/X86/symtab.ll Tue Nov 21 14:06:20 2017
@@ -17,6 +17,15 @@ define i32 @fun() {
   ret i32 0
 }
 
+; CHECK: D------X @fun2 at 8
+; CHECK-NEXT: comdat @fun2 at 8
+$fun2 = comdat any
+define x86_fastcallcc i32 @fun2(i32 inreg %a, i32 inreg %b) comdat {
+entry:
+  %add = add nsw i32 %b, %a
+  ret i32 %add
+}
+
 ; CHECK: H------- _g1
 @g1 = hidden global i32 0
 
@@ -43,11 +52,19 @@ define i32 @fun() {
 @g8 = common global i32 0, align 8
 
 ; CHECK: D------- _g9
-; CHECK-NEXT: comdat g9
+; CHECK-NEXT: comdat _g9
 $g9 = comdat any
 @g9 = global i32 0, comdat
 
-; CHECK: D--WI--- _g10
-; CHECK-NEXT: comdat g9
+; CHECK-NOT: _g10
+$g10 = comdat any
+ at g10 = internal global i32 0, comdat
+
+; CHECK: D------- _g11
+; CHECK-NOT: comdat
+ at g11 = global i32 0, comdat($g10)
+
+; CHECK: D--WI--- _a1
+; CHECK-NEXT: comdat _g9
 ; CHECK-NEXT: fallback _g9
- at g10 = weak alias i32, i32* @g9
+ at a1 = weak alias i32, i32* @g9




More information about the llvm-commits mailing list