Skip to content

Commit

Permalink
Bitcode: Introduce a BitcodeFileContents data type. NFCI.
Browse files Browse the repository at this point in the history
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305019 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pcc committed Jun 8, 2017
1 parent e99f33a commit b9fc96d
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 21 deletions.
13 changes: 11 additions & 2 deletions include/llvm/Bitcode/BitcodeReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions include/llvm/Object/IRObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/Object/SymbolicFile.h"

namespace llvm {
class BitcodeModule;
class Mangler;
class Module;
class GlobalValue;
Expand Down
4 changes: 2 additions & 2 deletions include/llvm/Object/IRSymtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

namespace llvm {

class BitcodeModule;
struct BitcodeFileContents;

namespace irsymtab {

Expand Down Expand Up @@ -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
Expand Down
22 changes: 15 additions & 7 deletions lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5370,20 +5370,28 @@ 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();

// We may be consuming bitcode from a client that leaves garbage at the end
// 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) {
Expand All @@ -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;
}

Expand All @@ -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;
Expand Down
11 changes: 5 additions & 6 deletions lib/Object/IRObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 13 additions & 4 deletions lib/Object/IRSymtab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

0 comments on commit b9fc96d

Please sign in to comment.