Skip to content

Commit

Permalink
Object: Factor out the code for creating the irsymtab for an arbitrar…
Browse files Browse the repository at this point in the history
…y 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
  • Loading branch information
pcc committed Jun 8, 2017
1 parent 643c0a4 commit f040d16
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 45 deletions.
14 changes: 14 additions & 0 deletions include/llvm/Object/IRObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -61,7 +62,20 @@ class IRObjectFile : public SymbolicFile {
static Expected<std::unique_ptr<IRObjectFile>> 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<BitcodeModule> Mods;
SmallVector<char, 0> Symtab, Strtab;
irsymtab::Reader TheReader;
};

/// Reads a bitcode file, creating its irsymtab if necessary.
Expected<IRSymtabFile> readIRSymtab(MemoryBufferRef MBRef);

}

}

#endif
13 changes: 13 additions & 0 deletions include/llvm/Object/IRSymtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#include <vector>

namespace llvm {

class BitcodeModule;

namespace irsymtab {

namespace storage {
Expand Down Expand Up @@ -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<char, 0> Symtab, Strtab;
Reader TheReader;
};

/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
Expected<FileContents> readBitcode(ArrayRef<BitcodeModule> Mods);

} // end namespace irsymtab
} // end namespace llvm

Expand Down
57 changes: 12 additions & 45 deletions lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,61 +315,28 @@ InputFile::~InputFile() = default;
Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {
std::unique_ptr<InputFile> File(new InputFile);

ErrorOr<MemoryBufferRef> BCOrErr =
IRObjectFile::findBitcodeInMemBuffer(Object);
if (!BCOrErr)
return errorCodeToError(BCOrErr.getError());

Expected<std::vector<BitcodeModule>> BMsOrErr =
getBitcodeModuleList(*BCOrErr);
if (!BMsOrErr)
return BMsOrErr.takeError();

if (BMsOrErr->empty())
return make_error<StringError>("Bitcode file does not contain any modules",
inconvertibleErrorCode());

File->Mods = *BMsOrErr;

LLVMContext Ctx;
std::vector<Module *> Mods;
std::vector<std::unique_ptr<Module>> OwnedMods;
for (auto BM : *BMsOrErr) {
Expected<std::unique_ptr<Module>> MOrErr =
BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true,
/*IsImporting*/ false);
if (!MOrErr)
return MOrErr.takeError();

if ((*MOrErr)->getDataLayoutStr().empty())
return make_error<StringError>("input module has no datalayout",
inconvertibleErrorCode());

Mods.push_back(MOrErr->get());
OwnedMods.push_back(std::move(*MOrErr));
}

SmallVector<char, 0> Symtab;
if (Error E = irsymtab::build(Mods, Symtab, File->Strtab))
return std::move(E);
Expected<IRSymtabFile> 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())
File->Symbols.push_back(Sym);
File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
}

File->Mods = FOrErr->Mods;
File->Strtab = std::move(FOrErr->Strtab);
return std::move(File);
}

Expand Down
23 changes: 23 additions & 0 deletions lib/Object/IRObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,26 @@ IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
return std::unique_ptr<IRObjectFile>(
new IRObjectFile(*BCOrErr, std::move(Mods)));
}

Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
IRSymtabFile F;
ErrorOr<MemoryBufferRef> BCOrErr =
IRObjectFile::findBitcodeInMemBuffer(MBRef);
if (!BCOrErr)
return errorCodeToError(BCOrErr.getError());

Expected<std::vector<BitcodeModule>> BMsOrErr =
getBitcodeModuleList(*BCOrErr);
if (!BMsOrErr)
return BMsOrErr.takeError();

Expected<irsymtab::FileContents> 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);
}
34 changes: 34 additions & 0 deletions lib/Object/IRSymtab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -259,3 +261,35 @@ Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
SmallVector<char, 0> &Strtab) {
return Builder(Symtab, Strtab).build(Mods);
}

Expected<FileContents> irsymtab::readBitcode(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;
std::vector<std::unique_ptr<Module>> OwnedMods;
for (auto BM : BMs) {
Expected<std::unique_ptr<Module>> MOrErr =
BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true,
/*IsImporting*/ false);
if (!MOrErr)
return MOrErr.takeError();

if ((*MOrErr)->getDataLayoutStr().empty())
return make_error<StringError>("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);
}

0 comments on commit f040d16

Please sign in to comment.