Index: include/llvm/LTO/LTO.h =================================================================== --- include/llvm/LTO/LTO.h +++ include/llvm/LTO/LTO.h @@ -106,6 +106,8 @@ // FIXME: Remove the LLVMContext once we have bitcode symbol tables. LLVMContext Ctx; std::unique_ptr Obj; + std::vector Comdats; + DenseMap ComdatMap; public: /// Create an InputFile. @@ -124,6 +126,7 @@ friend LTO; object::basic_symbol_iterator I; + const InputFile *File; const GlobalValue *GV; uint32_t Flags; SmallString<64> Name; @@ -154,7 +157,10 @@ } public: - Symbol(object::basic_symbol_iterator I) : I(I) { skip(); } + Symbol(object::basic_symbol_iterator I, const InputFile *File) + : I(I), File(File) { + skip(); + } StringRef getName() const { return Name; } StringRef getIRName() const { @@ -176,22 +182,11 @@ return GV && GV->isThreadLocal(); } - Expected getComdat() const { - if (!GV) - return ""; - const GlobalObject *GO; - if (auto *GA = dyn_cast(GV)) { - GO = GA->getBaseObject(); - if (!GO) - return make_error("Unable to determine comdat of alias!", - inconvertibleErrorCode()); - } else { - GO = cast(GV); - } - if (const Comdat *C = GO->getComdat()) - return C->getName(); - return ""; - } + // Returns the index of the comdat this symbol is in or -1 if the symbol + // is not in a comdat. + // FIXME: We have to return Expected because of the way aliases are + // implemented and the lack of a IR symbol table. + Expected getComdatIndex() const; uint64_t getCommonSize() const { assert(Flags & object::BasicSymbolRef::SF_Common); @@ -212,7 +207,8 @@ Symbol Sym; public: - symbol_iterator(object::basic_symbol_iterator I) : Sym(I) {} + symbol_iterator(object::basic_symbol_iterator I, const InputFile *File) + : Sym(I, File) {} symbol_iterator &operator++() { ++Sym.I; @@ -236,8 +232,8 @@ /// A range over the symbols in this InputFile. iterator_range symbols() { - return llvm::make_range(symbol_iterator(Obj->symbol_begin()), - symbol_iterator(Obj->symbol_end())); + return llvm::make_range(symbol_iterator(Obj->symbol_begin(), this), + symbol_iterator(Obj->symbol_end(), this)); } StringRef getDataLayoutStr() const { @@ -251,6 +247,9 @@ MemoryBufferRef getMemoryBufferRef() const { return Obj->getMemoryBufferRef(); } + + // Returns a table with all the comdats used by this file. + ArrayRef getComdatTable() const { return Comdats; } }; /// This class wraps an output stream for a native object. Most clients should Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -218,9 +218,36 @@ File->Ctx.setDiagnosticHandler(nullptr, nullptr); + for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) { + auto P = + File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size())); + assert(P.second); + File->Comdats.push_back(C.first()); + } + return std::move(File); } +Expected InputFile::Symbol::getComdatIndex() const { + if (!GV) + return -1; + const GlobalObject *GO; + if (auto *GA = dyn_cast(GV)) { + GO = GA->getBaseObject(); + if (!GO) + return make_error("Unable to determine comdat of alias!", + inconvertibleErrorCode()); + } else { + GO = cast(GV); + } + if (const Comdat *C = GO->getComdat()) { + auto I = File->ComdatMap.find(C); + assert(I != File->ComdatMap.end()); + return I->second; + } + return -1; +} + LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, Config &Conf) : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), @@ -332,8 +359,8 @@ auto ResI = Res.begin(); for (const InputFile::Symbol &Sym : - make_range(InputFile::symbol_iterator(Obj->symbol_begin()), - InputFile::symbol_iterator(Obj->symbol_end()))) { + make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr), + InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) { assert(ResI != Res.end()); SymbolResolution Res = *ResI++; addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0); Index: tools/gold/gold-plugin.cpp =================================================================== --- tools/gold/gold-plugin.cpp +++ tools/gold/gold-plugin.cpp @@ -526,9 +526,11 @@ sym.size = 0; sym.comdat_key = nullptr; - StringRef C = check(Sym.getComdat()); - if (!C.empty()) + int CI = check(Sym.getComdatIndex()); + if (CI != -1) { + StringRef C = Obj->getComdatTable()[CI]; sym.comdat_key = strdup(C.str().c_str()); + } sym.resolution = LDPR_UNKNOWN; }