Index: llvm/include/llvm/LTO/LTO.h =================================================================== --- llvm/include/llvm/LTO/LTO.h +++ llvm/include/llvm/LTO/LTO.h @@ -71,7 +71,7 @@ struct SymbolResolution; class ThinBackendProc; -/// An input file. This is a wrapper for IRObjectFile that exposes only the +/// An input file. This is a wrapper for ModuleSymbolTable that exposes only the /// information that an LTO client should need in order to do symbol resolution. class InputFile { // FIXME: Remove LTO class friendship once we have bitcode symbol tables. @@ -80,7 +80,10 @@ // FIXME: Remove the LLVMContext once we have bitcode symbol tables. LLVMContext Ctx; - std::unique_ptr Obj; + ModuleSymbolTable SymTab; + std::unique_ptr Mod; + MemoryBufferRef MBRef; + std::vector Comdats; DenseMap ComdatMap; @@ -90,9 +93,9 @@ class symbol_iterator; - /// This is a wrapper for object::basic_symbol_iterator that exposes only the - /// information that an LTO client should need in order to do symbol - /// resolution. + /// This is a wrapper for ArrayRef::iterator that + /// exposes only the information that an LTO client should need in order to do + /// symbol resolution. /// /// This object is ephemeral; it is only valid as long as an iterator obtained /// from symbols() refers to it. @@ -100,9 +103,9 @@ friend symbol_iterator; friend LTO; - object::basic_symbol_iterator I; + ArrayRef::iterator I; + const ModuleSymbolTable &SymTab; const InputFile *File; - const GlobalValue *GV; uint32_t Flags; SmallString<64> Name; @@ -112,10 +115,9 @@ } void skip() { - const object::SymbolicFile *Obj = I->getObject(); - auto E = Obj->symbol_end(); + ArrayRef::iterator E = SymTab.symbols().end(); while (I != E) { - Flags = I->getFlags(); + Flags = SymTab.getSymbolFlags(*I); if (!shouldSkip()) break; ++I; @@ -126,14 +128,17 @@ Name.clear(); { raw_svector_ostream OS(Name); - I->printName(OS); + SymTab.printSymbolName(OS, *I); } - GV = cast(Obj)->getSymbolGV(I->getRawDataRefImpl()); } + bool isGV() const { return I->is(); } + GlobalValue *getGV() const { return I->get(); } + public: - Symbol(object::basic_symbol_iterator I, const InputFile *File) - : I(I), File(File) { + Symbol(ArrayRef::iterator I, + const ModuleSymbolTable &SymTab, const InputFile *File) + : I(I), SymTab(SymTab), File(File) { skip(); } @@ -142,16 +147,16 @@ uint32_t getFlags() const { return Flags; } GlobalValue::VisibilityTypes getVisibility() const { - if (GV) - return GV->getVisibility(); + if (isGV()) + return getGV()->getVisibility(); return GlobalValue::DefaultVisibility; } bool canBeOmittedFromSymbolTable() const { - return GV && llvm::canBeOmittedFromSymbolTable(GV); + return isGV() && llvm::canBeOmittedFromSymbolTable(getGV()); } bool isTLS() const { // FIXME: Expose a thread-local flag for module asm symbols. - return GV && GV->isThreadLocal(); + return isGV() && getGV()->isThreadLocal(); } // Returns the index of the comdat this symbol is in or -1 if the symbol @@ -164,16 +169,16 @@ uint64_t getCommonSize() const { assert(Flags & object::BasicSymbolRef::SF_Common); - if (!GV) + if (!isGV()) return 0; - return GV->getParent()->getDataLayout().getTypeAllocSize( - GV->getType()->getElementType()); + return getGV()->getParent()->getDataLayout().getTypeAllocSize( + getGV()->getType()->getElementType()); } unsigned getCommonAlignment() const { assert(Flags & object::BasicSymbolRef::SF_Common); - if (!GV) + if (!isGV()) return 0; - return GV->getAlignment(); + return getGV()->getAlignment(); } }; @@ -181,8 +186,9 @@ Symbol Sym; public: - symbol_iterator(object::basic_symbol_iterator I, const InputFile *File) - : Sym(I, File) {} + symbol_iterator(ArrayRef::iterator I, + const ModuleSymbolTable &SymTab, const InputFile *File) + : Sym(I, SymTab, File) {} symbol_iterator &operator++() { ++Sym.I; @@ -206,17 +212,13 @@ /// A range over the symbols in this InputFile. iterator_range symbols() { - return llvm::make_range(symbol_iterator(Obj->symbol_begin(), this), - symbol_iterator(Obj->symbol_end(), this)); + return llvm::make_range( + symbol_iterator(SymTab.symbols().begin(), SymTab, this), + symbol_iterator(SymTab.symbols().end(), SymTab, this)); } - StringRef getSourceFileName() const { - return Obj->getModule().getSourceFileName(); - } - - MemoryBufferRef getMemoryBufferRef() const { - return Obj->getMemoryBufferRef(); - } + StringRef getSourceFileName() const { return Mod->getSourceFileName(); } + MemoryBufferRef getMemoryBufferRef() const { return MBRef; } // Returns a table with all the comdats used by this file. ArrayRef getComdatTable() const { return Comdats; } @@ -399,8 +401,7 @@ // Global mapping from mangled symbol names to resolutions. StringMap GlobalResolutions; - void addSymbolToGlobalRes(object::IRObjectFile *Obj, - SmallPtrSet &Used, + void addSymbolToGlobalRes(SmallPtrSet &Used, const InputFile::Symbol &Sym, SymbolResolution Res, unsigned Partition); Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -184,13 +184,22 @@ Expected> InputFile::create(MemoryBufferRef Object) { std::unique_ptr File(new InputFile); - Expected> IRObj = - IRObjectFile::create(Object, File->Ctx); - if (!IRObj) - return IRObj.takeError(); - File->Obj = std::move(*IRObj); - - for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) { + ErrorOr BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(Object); + if (!BCOrErr) + return errorCodeToError(BCOrErr.getError()); + File->MBRef = *BCOrErr; + + Expected> MOrErr = + getLazyBitcodeModule(*BCOrErr, File->Ctx, + /*ShouldLazyLoadMetadata*/ true); + if (!MOrErr) + return MOrErr.takeError(); + + File->Mod = std::move(*MOrErr); + File->SymTab.addModule(File->Mod.get()); + + for (const auto &C : File->Mod->getComdatSymbolTable()) { auto P = File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size())); assert(P.second); @@ -202,17 +211,12 @@ } Expected InputFile::Symbol::getComdatIndex() const { - if (!GV) + if (!isGV()) 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); - } + const GlobalObject *GO = getGV()->getBaseObject(); + if (!GO) + return make_error("Unable to determine comdat of alias!", + inconvertibleErrorCode()); if (const Comdat *C = GO->getComdat()) { auto I = File->ComdatMap.find(C); assert(I != File->ComdatMap.end()); @@ -239,11 +243,10 @@ ThinLTO(std::move(Backend)) {} // Add the given symbol to the GlobalResolutions map, and resolve its partition. -void LTO::addSymbolToGlobalRes(IRObjectFile *Obj, - SmallPtrSet &Used, +void LTO::addSymbolToGlobalRes(SmallPtrSet &Used, const InputFile::Symbol &Sym, SymbolResolution Res, unsigned Partition) { - GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); + GlobalValue *GV = Sym.isGV() ? Sym.getGV() : nullptr; auto &GlobalRes = GlobalResolutions[Sym.getName()]; if (GV) { @@ -288,14 +291,13 @@ writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); // FIXME: move to backend - Module &M = Input->Obj->getModule(); + Module &M = *Input->Mod; if (!Conf.OverrideTriple.empty()) M.setTargetTriple(Conf.OverrideTriple); else if (M.getTargetTriple().empty()) M.setTargetTriple(Conf.DefaultTriple); - MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); - Expected HasThinLTOSummary = hasGlobalValueSummary(MBRef); + Expected HasThinLTOSummary = hasGlobalValueSummary(Input->MBRef); if (!HasThinLTOSummary) return HasThinLTOSummary.takeError(); @@ -313,17 +315,20 @@ llvm::make_unique("ld-temp.o", RegularLTO.Ctx); RegularLTO.Mover = llvm::make_unique(*RegularLTO.CombinedModule); } - Expected> ObjOrErr = - IRObjectFile::create(Input->Obj->getMemoryBufferRef(), RegularLTO.Ctx); - if (!ObjOrErr) - return ObjOrErr.takeError(); - std::unique_ptr Obj = std::move(*ObjOrErr); + Expected> MOrErr = + getLazyBitcodeModule(Input->MBRef, RegularLTO.Ctx, + /*ShouldLazyLoadMetadata*/ true); + if (!MOrErr) + return MOrErr.takeError(); - Module &M = Obj->getModule(); + Module &M = **MOrErr; if (Error Err = M.materializeMetadata()) return Err; UpgradeDebugInfo(M); + ModuleSymbolTable SymTab; + SymTab.addModule(&M); + SmallPtrSet Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); @@ -335,16 +340,18 @@ auto ResI = Res.begin(); for (const InputFile::Symbol &Sym : - make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr), - InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) { + make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab, + nullptr), + InputFile::symbol_iterator(SymTab.symbols().end(), SymTab, + nullptr))) { assert(ResI != Res.end()); SymbolResolution Res = *ResI++; - addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0); + addSymbolToGlobalRes(Used, Sym, Res, 0); - GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) continue; - if (Res.Prevailing && GV) { + if (Res.Prevailing && Sym.isGV()) { + GlobalValue *GV = Sym.getGV(); Keep.push_back(GV); switch (GV->getLinkage()) { default: @@ -363,8 +370,7 @@ if (Sym.getFlags() & object::BasicSymbolRef::SF_Common) { // FIXME: We should figure out what to do about commons defined by asm. // For now they aren't reported correctly by ModuleSymbolTable. - assert(GV); - auto &CommonRes = RegularLTO.Commons[GV->getName()]; + auto &CommonRes = RegularLTO.Commons[Sym.getGV()->getName()]; CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize()); CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment()); CommonRes.Prevailing |= Res.Prevailing; @@ -374,7 +380,7 @@ } assert(ResI == Res.end()); - return RegularLTO.Mover->move(Obj->takeModule(), Keep, + return RegularLTO.Mover->move(std::move(*MOrErr), Keep, [](GlobalValue &, IRMover::ValueAdder) {}, /* LinkModuleInlineAsm */ true); } @@ -382,11 +388,11 @@ // Add a ThinLTO object to the link. Error LTO::addThinLTO(std::unique_ptr Input, ArrayRef Res) { - Module &M = Input->Obj->getModule(); + Module &M = *Input->Mod; SmallPtrSet Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); - MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); + MemoryBufferRef MBRef = Input->MBRef; Expected> SummaryObjOrErr = object::ModuleSummaryIndexObjectFile::create(MBRef); if (!SummaryObjOrErr) @@ -398,12 +404,10 @@ for (const InputFile::Symbol &Sym : Input->symbols()) { assert(ResI != Res.end()); SymbolResolution Res = *ResI++; - addSymbolToGlobalRes(Input->Obj.get(), Used, Sym, Res, - ThinLTO.ModuleMap.size() + 1); + addSymbolToGlobalRes(Used, Sym, Res, ThinLTO.ModuleMap.size() + 1); - GlobalValue *GV = Input->Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); - if (Res.Prevailing && GV) - ThinLTO.PrevailingModuleForGUID[GV->getGUID()] = + if (Res.Prevailing && Sym.isGV()) + ThinLTO.PrevailingModuleForGUID[Sym.getGV()->getGUID()] = MBRef.getBufferIdentifier(); } assert(ResI == Res.end());