From: Rafael Espindola Date: Wed, 2 Mar 2016 15:43:50 +0000 (+0000) Subject: Handle comdat in LTO. X-Git-Tag: llvmorg-3.9.0-rc1~12676 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4de44b7ef87bcef83798eee69fdcbfab9866d52e;p=platform%2Fupstream%2Fllvm.git Handle comdat in LTO. llvm-svn: 262489 --- diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 78abcf95fbee..8b8cf02a8de7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -13,6 +13,7 @@ #include "Symbols.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Object/IRObjectFile.h" #include "llvm/Support/raw_ostream.h" @@ -441,13 +442,27 @@ bool BitcodeFile::classof(const InputFile *F) { return F->kind() == BitcodeKind; } -void BitcodeFile::parse() { +void BitcodeFile::parse(DenseSet &ComdatGroups) { LLVMContext Context; ErrorOr> ObjOrErr = IRObjectFile::create(MB, Context); fatal(ObjOrErr); IRObjectFile &Obj = **ObjOrErr; + const Module &M = Obj.getModule(); + + DenseSet KeptComdats; + for (const auto &P : M.getComdatSymbolTable()) { + StringRef N = Saver.save(P.first()); + if (ComdatGroups.insert(N).second) + KeptComdats.insert(&P.second); + } + for (const BasicSymbolRef &Sym : Obj.symbols()) { + if (const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl())) + if (const Comdat *C = GV->getComdat()) + if (!KeptComdats.count(C)) + continue; + SmallString<64> Name; raw_svector_ostream OS(Name); Sym.printName(OS); diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 18debd420b59..48fe27d31f2d 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -183,7 +183,7 @@ class BitcodeFile : public InputFile { public: explicit BitcodeFile(MemoryBufferRef M); static bool classof(const InputFile *F); - void parse(); + void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return SymbolBodies; } private: diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 095ad86764c6..6892968cf040 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -82,7 +82,7 @@ void SymbolTable::addFile(std::unique_ptr File) { // LLVM bitcode file. if (auto *F = dyn_cast(FileP)) { BitcodeFiles.emplace_back(cast(File.release())); - F->parse(); + F->parse(ComdatGroups); for (SymbolBody *B : F->getSymbols()) resolve(B); return; @@ -151,8 +151,8 @@ template void SymbolTable::addCombinedLtoObject() { if (BitcodeFiles.empty()) return; ObjectFile *Obj = createCombinedLtoObject(); - // FIXME: We probably have to ignore comdats here. - Obj->parse(ComdatGroups); + llvm::DenseSet DummyGroups; + Obj->parse(DummyGroups); for (SymbolBody *Body : Obj->getSymbols()) { Symbol *Sym = insert(Body); Sym->Body = Body; diff --git a/lld/test/ELF/lto/comdat.ll b/lld/test/ELF/lto/comdat.ll new file mode 100644 index 000000000000..e1384d0abd23 --- /dev/null +++ b/lld/test/ELF/lto/comdat.ll @@ -0,0 +1,21 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +; CHECK: Name: foo +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +$foo = comdat any +define void @foo() comdat { + ret void +} +