diff options
| -rw-r--r-- | llvm/include/llvm/LTO/LTO.h | 41 | ||||
| -rw-r--r-- | llvm/lib/LTO/LTO.cpp | 31 | ||||
| -rw-r--r-- | llvm/tools/gold/gold-plugin.cpp | 6 |
3 files changed, 54 insertions, 24 deletions
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h index 7ef6ee1e155..80e94e8efbc 100644 --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -106,6 +106,8 @@ class InputFile { // FIXME: Remove the LLVMContext once we have bitcode symbol tables. LLVMContext Ctx; std::unique_ptr<object::IRObjectFile> Obj; + std::vector<StringRef> Comdats; + DenseMap<const Comdat *, unsigned> ComdatMap; public: /// Create an InputFile. @@ -124,6 +126,7 @@ public: friend LTO; object::basic_symbol_iterator I; + const InputFile *File; const GlobalValue *GV; uint32_t Flags; SmallString<64> Name; @@ -154,7 +157,10 @@ public: } 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,13 @@ public: return GV && GV->isThreadLocal(); } - Expected<StringRef> getComdat() const { - if (!GV) - return ""; - const GlobalObject *GO; - if (auto *GA = dyn_cast<GlobalAlias>(GV)) { - GO = GA->getBaseObject(); - if (!GO) - return make_error<StringError>("Unable to determine comdat of alias!", - inconvertibleErrorCode()); - } else { - GO = cast<GlobalObject>(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<int> because aliases point to an + // arbitrary ConstantExpr and that might not actually be a constant. That + // means we might not be able to find what an alias is aliased to and + // so find its comdat. + Expected<int> getComdatIndex() const; uint64_t getCommonSize() const { assert(Flags & object::BasicSymbolRef::SF_Common); @@ -212,7 +209,8 @@ public: 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 +234,8 @@ public: /// A range over the symbols in this InputFile. iterator_range<symbol_iterator> 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 +249,9 @@ public: MemoryBufferRef getMemoryBufferRef() const { return Obj->getMemoryBufferRef(); } + + // Returns a table with all the comdats used by this file. + ArrayRef<StringRef> getComdatTable() const { return Comdats; } }; /// This class wraps an output stream for a native object. Most clients should diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index b4efb4a4db6..d43b4d56ff1 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -218,9 +218,36 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { 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<int> InputFile::Symbol::getComdatIndex() const { + if (!GV) + return -1; + const GlobalObject *GO; + if (auto *GA = dyn_cast<GlobalAlias>(GV)) { + GO = GA->getBaseObject(); + if (!GO) + return make_error<StringError>("Unable to determine comdat of alias!", + inconvertibleErrorCode()); + } else { + GO = cast<GlobalObject>(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 @@ Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, 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); diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp index 1366c0f77fd..7c5d48144b2 100644 --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -526,9 +526,11 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 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; } |

