From: Peter Collingbourne Date: Thu, 8 Jun 2017 01:26:14 +0000 (+0000) Subject: Object: Factor out the code for creating the irsymtab for an arbitrary bitcode file. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f040d163f556eceaa232273a1ba1f82eae1406ef;p=llvm Object: Factor out the code for creating the irsymtab for an arbitrary bitcode file. This code now lives in lib/Object. The idea is that it can now be reused by IRObjectFile among other things. Differential Revision: https://reviews.llvm.org/D31921 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304958 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index 0ea89011e88..b4b6677037d 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -15,6 +15,7 @@ #define LLVM_OBJECT_IROBJECTFILE_H #include "llvm/ADT/PointerUnion.h" +#include "llvm/Object/IRSymtab.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Object/SymbolicFile.h" @@ -61,7 +62,20 @@ public: static Expected> create(MemoryBufferRef Object, LLVMContext &Context); }; + +/// The contents of a bitcode file and its irsymtab. Any underlying data +/// for the irsymtab are owned by Symtab and Strtab. +struct IRSymtabFile { + std::vector Mods; + SmallVector Symtab, Strtab; + irsymtab::Reader TheReader; +}; + +/// Reads a bitcode file, creating its irsymtab if necessary. +Expected readIRSymtab(MemoryBufferRef MBRef); + } + } #endif diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index e7b32be4c84..a5398977cb6 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -36,6 +36,9 @@ #include namespace llvm { + +class BitcodeModule; + namespace irsymtab { namespace storage { @@ -314,6 +317,16 @@ inline Reader::symbol_range Reader::module_symbols(unsigned I) const { SymbolRef(MEnd, MEnd, nullptr, this)}; } +/// The contents of the irsymtab in a bitcode file. Any underlying data for the +/// irsymtab are owned by Symtab and Strtab. +struct FileContents { + SmallVector Symtab, Strtab; + Reader TheReader; +}; + +/// Reads the contents of a bitcode file, creating its irsymtab if necessary. +Expected readBitcode(ArrayRef Mods); + } // end namespace irsymtab } // end namespace llvm diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 6d322b26684..9d2a44045d6 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -315,54 +315,19 @@ InputFile::~InputFile() = default; Expected> InputFile::create(MemoryBufferRef Object) { std::unique_ptr File(new InputFile); - ErrorOr BCOrErr = - IRObjectFile::findBitcodeInMemBuffer(Object); - if (!BCOrErr) - return errorCodeToError(BCOrErr.getError()); - - Expected> BMsOrErr = - getBitcodeModuleList(*BCOrErr); - if (!BMsOrErr) - return BMsOrErr.takeError(); - - if (BMsOrErr->empty()) - return make_error("Bitcode file does not contain any modules", - inconvertibleErrorCode()); - - File->Mods = *BMsOrErr; - - LLVMContext Ctx; - std::vector Mods; - std::vector> OwnedMods; - for (auto BM : *BMsOrErr) { - Expected> MOrErr = - BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, - /*IsImporting*/ false); - if (!MOrErr) - return MOrErr.takeError(); - - if ((*MOrErr)->getDataLayoutStr().empty()) - return make_error("input module has no datalayout", - inconvertibleErrorCode()); - - Mods.push_back(MOrErr->get()); - OwnedMods.push_back(std::move(*MOrErr)); - } - - SmallVector Symtab; - if (Error E = irsymtab::build(Mods, Symtab, File->Strtab)) - return std::move(E); + Expected FOrErr = readIRSymtab(Object); + if (!FOrErr) + return FOrErr.takeError(); - irsymtab::Reader R({Symtab.data(), Symtab.size()}, - {File->Strtab.data(), File->Strtab.size()}); - File->TargetTriple = R.getTargetTriple(); - File->SourceFileName = R.getSourceFileName(); - File->COFFLinkerOpts = R.getCOFFLinkerOpts(); - File->ComdatTable = R.getComdatTable(); + File->TargetTriple = FOrErr->TheReader.getTargetTriple(); + File->SourceFileName = FOrErr->TheReader.getSourceFileName(); + File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts(); + File->ComdatTable = FOrErr->TheReader.getComdatTable(); - for (unsigned I = 0; I != Mods.size(); ++I) { + for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) { size_t Begin = File->Symbols.size(); - for (const irsymtab::Reader::SymbolRef &Sym : R.module_symbols(I)) + for (const irsymtab::Reader::SymbolRef &Sym : + FOrErr->TheReader.module_symbols(I)) // Skip symbols that are irrelevant to LTO. Note that this condition needs // to match the one in Skip() in LTO::addRegularLTO(). if (Sym.isGlobal() && !Sym.isFormatSpecific()) @@ -370,6 +335,8 @@ Expected> InputFile::create(MemoryBufferRef Object) { File->ModuleSymIndices.push_back({Begin, File->Symbols.size()}); } + File->Mods = FOrErr->Mods; + File->Strtab = std::move(FOrErr->Strtab); return std::move(File); } diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index bcaee029ce5..9996661fbde 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -139,3 +139,26 @@ IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { return std::unique_ptr( new IRObjectFile(*BCOrErr, std::move(Mods))); } + +Expected object::readIRSymtab(MemoryBufferRef MBRef) { + IRSymtabFile F; + ErrorOr BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(MBRef); + if (!BCOrErr) + return errorCodeToError(BCOrErr.getError()); + + Expected> BMsOrErr = + getBitcodeModuleList(*BCOrErr); + if (!BMsOrErr) + return BMsOrErr.takeError(); + + Expected FCOrErr = irsymtab::readBitcode(*BMsOrErr); + if (!FCOrErr) + return FCOrErr.takeError(); + + F.Mods = std::move(*BMsOrErr); + F.Symtab = std::move(FCOrErr->Symtab); + F.Strtab = std::move(FCOrErr->Strtab); + F.TheReader = std::move(FCOrErr->TheReader); + return std::move(F); +} diff --git a/lib/Object/IRSymtab.cpp b/lib/Object/IRSymtab.cpp index 28558bdd065..fa343618caf 100644 --- a/lib/Object/IRSymtab.cpp +++ b/lib/Object/IRSymtab.cpp @@ -23,7 +23,9 @@ #include "llvm/IR/Mangler.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/MC/StringTableBuilder.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Object/SymbolicFile.h" #include "llvm/Support/Allocator.h" @@ -259,3 +261,35 @@ Error irsymtab::build(ArrayRef Mods, SmallVector &Symtab, SmallVector &Strtab) { return Builder(Symtab, Strtab).build(Mods); } + +Expected irsymtab::readBitcode(ArrayRef BMs) { + FileContents FC; + if (BMs.empty()) + return make_error("Bitcode file does not contain any modules", + inconvertibleErrorCode()); + + LLVMContext Ctx; + std::vector Mods; + std::vector> OwnedMods; + for (auto BM : BMs) { + Expected> MOrErr = + BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, + /*IsImporting*/ false); + if (!MOrErr) + return MOrErr.takeError(); + + if ((*MOrErr)->getDataLayoutStr().empty()) + return make_error("input module has no datalayout", + inconvertibleErrorCode()); + + Mods.push_back(MOrErr->get()); + OwnedMods.push_back(std::move(*MOrErr)); + } + + if (Error E = build(Mods, FC.Symtab, FC.Strtab)) + return std::move(E); + + FC.TheReader = {{FC.Symtab.data(), FC.Symtab.size()}, + {FC.Strtab.data(), FC.Strtab.size()}}; + return std::move(FC); +}