Bitcode: Introduce a BitcodeFileContents data type. NFCI.

This data type includes the contents of a bitcode file.
Right now a bitcode file can only contain modules, but
a later change will add a symbol table.

Differential Revision: https://reviews.llvm.org/D33969

llvm-svn: 305019
This commit is contained in:
Peter Collingbourne 2017-06-08 22:00:24 +00:00
parent 108ca94fa8
commit 8dde4cba4c
6 changed files with 47 additions and 21 deletions

View File

@ -40,6 +40,8 @@ namespace llvm {
return std::move(*Val);
}
struct BitcodeFileContents;
/// Represents a module in a bitcode file.
class BitcodeModule {
// This covers the identification (if present) and module blocks.
@ -61,8 +63,8 @@ namespace llvm {
IdentificationBit(IdentificationBit), ModuleBit(ModuleBit) {}
// Calls the ctor.
friend Expected<std::vector<BitcodeModule>>
getBitcodeModuleList(MemoryBufferRef Buffer);
friend Expected<BitcodeFileContents>
getBitcodeFileContents(MemoryBufferRef Buffer);
Expected<std::unique_ptr<Module>> getModuleImpl(LLVMContext &Context,
bool MaterializeAll,
@ -99,6 +101,13 @@ namespace llvm {
Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId);
};
struct BitcodeFileContents {
std::vector<BitcodeModule> Mods;
};
/// Returns the contents of a bitcode file.
Expected<BitcodeFileContents> getBitcodeFileContents(MemoryBufferRef Buffer);
/// Returns a list of modules in the specified bitcode buffer.
Expected<std::vector<BitcodeModule>>
getBitcodeModuleList(MemoryBufferRef Buffer);

View File

@ -20,6 +20,7 @@
#include "llvm/Object/SymbolicFile.h"
namespace llvm {
class BitcodeModule;
class Mangler;
class Module;
class GlobalValue;

View File

@ -37,7 +37,7 @@
namespace llvm {
class BitcodeModule;
struct BitcodeFileContents;
namespace irsymtab {
@ -325,7 +325,7 @@ struct FileContents {
};
/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
Expected<FileContents> readBitcode(ArrayRef<BitcodeModule> Mods);
Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
} // end namespace irsymtab
} // end namespace llvm

View File

@ -5370,12 +5370,20 @@ static Expected<StringRef> readStrtab(BitstreamCursor &Stream) {
Expected<std::vector<BitcodeModule>>
llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
auto FOrErr = getBitcodeFileContents(Buffer);
if (!FOrErr)
return FOrErr.takeError();
return std::move(FOrErr->Mods);
}
Expected<BitcodeFileContents>
llvm::getBitcodeFileContents(MemoryBufferRef Buffer) {
Expected<BitstreamCursor> StreamOrErr = initStream(Buffer);
if (!StreamOrErr)
return StreamOrErr.takeError();
BitstreamCursor &Stream = *StreamOrErr;
std::vector<BitcodeModule> Modules;
BitcodeFileContents F;
while (true) {
uint64_t BCBegin = Stream.getCurrentByteNo();
@ -5383,7 +5391,7 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
// of the bitcode stream (e.g. Apple's ar tool). If we are close enough to
// the end that there cannot possibly be another module, stop looking.
if (BCBegin + 8 >= Stream.getBitcodeBytes().size())
return Modules;
return F;
BitstreamEntry Entry = Stream.advance();
switch (Entry.Kind) {
@ -5409,10 +5417,10 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
if (Stream.SkipBlock())
return error("Malformed block");
Modules.push_back({Stream.getBitcodeBytes().slice(
BCBegin, Stream.getCurrentByteNo() - BCBegin),
Buffer.getBufferIdentifier(), IdentificationBit,
ModuleBit});
F.Mods.push_back({Stream.getBitcodeBytes().slice(
BCBegin, Stream.getCurrentByteNo() - BCBegin),
Buffer.getBufferIdentifier(), IdentificationBit,
ModuleBit});
continue;
}
@ -5424,7 +5432,7 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
// not have its own string table. A bitcode file may have multiple
// string tables if it was created by binary concatenation, for example
// with "llvm-cat -b".
for (auto I = Modules.rbegin(), E = Modules.rend(); I != E; ++I) {
for (auto I = F.Mods.rbegin(), E = F.Mods.rend(); I != E; ++I) {
if (!I->Strtab.empty())
break;
I->Strtab = *Strtab;

View File

@ -147,16 +147,15 @@ Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
if (!BCOrErr)
return errorCodeToError(BCOrErr.getError());
Expected<std::vector<BitcodeModule>> BMsOrErr =
getBitcodeModuleList(*BCOrErr);
if (!BMsOrErr)
return BMsOrErr.takeError();
Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr);
if (!BFCOrErr)
return BFCOrErr.takeError();
Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BMsOrErr);
Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr);
if (!FCOrErr)
return FCOrErr.takeError();
F.Mods = std::move(*BMsOrErr);
F.Mods = std::move(BFCOrErr->Mods);
F.Symtab = std::move(FCOrErr->Symtab);
F.Strtab = std::move(FCOrErr->Strtab);
F.TheReader = std::move(FCOrErr->TheReader);

View File

@ -262,11 +262,10 @@ Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
return Builder(Symtab, Strtab).build(Mods);
}
Expected<FileContents> irsymtab::readBitcode(ArrayRef<BitcodeModule> BMs) {
// Upgrade a vector of bitcode modules created by an old version of LLVM by
// creating an irsymtab for them in the current format.
static Expected<FileContents> upgrade(ArrayRef<BitcodeModule> BMs) {
FileContents FC;
if (BMs.empty())
return make_error<StringError>("Bitcode file does not contain any modules",
inconvertibleErrorCode());
LLVMContext Ctx;
std::vector<Module *> Mods;
@ -293,3 +292,13 @@ Expected<FileContents> irsymtab::readBitcode(ArrayRef<BitcodeModule> BMs) {
{FC.Strtab.data(), FC.Strtab.size()}};
return std::move(FC);
}
Expected<FileContents> irsymtab::readBitcode(const BitcodeFileContents &BFC) {
if (BFC.Mods.empty())
return make_error<StringError>("Bitcode file does not contain any modules",
inconvertibleErrorCode());
// Right now we have no on-disk representation of symbol tables, so we always
// upgrade.
return upgrade(BFC.Mods);
}