diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2014-09-18 21:28:49 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2014-09-18 21:28:49 +0000 |
commit | 10039c02ea1d34d39fb3b66f522c53bb50751da5 (patch) | |
tree | d0fcaa82f000b5ef6f140be711ae02155192c4fd /llvm/lib | |
parent | 6bf091c656f319e36721364fe50c456efca36df6 (diff) | |
download | bcm5719-llvm-10039c02ea1d34d39fb3b66f522c53bb50751da5.tar.gz bcm5719-llvm-10039c02ea1d34d39fb3b66f522c53bb50751da5.zip |
LTO: introduce object file-based on-disk module format.
This format is simply a regular object file with the bitcode stored in a
section named ".llvmbc", plus any number of other (non-allocated) sections.
One immediate use case for this is to accommodate compilation processes
which expect the object file to contain metadata in non-allocated sections,
such as the ".go_export" section used by some Go compilers [1], although I
imagine that in the future we could consider compiling parts of the module
(such as large non-inlinable functions) directly into the object file to
improve LTO efficiency.
[1] http://golang.org/doc/install/gccgo#Imports
Differential Revision: http://reviews.llvm.org/D4371
llvm-svn: 218078
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/LTO/LTOModule.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/Object/Error.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Object/IRObjectFile.cpp | 42 | ||||
-rw-r--r-- | llvm/lib/Object/SymbolicFile.cpp | 20 |
4 files changed, 90 insertions, 17 deletions
diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp index 88f82f0722a..b9320d24cc3 100644 --- a/llvm/lib/LTO/LTOModule.cpp +++ b/llvm/lib/LTO/LTOModule.cpp @@ -29,6 +29,8 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -44,6 +46,7 @@ #include "llvm/Transforms/Utils/GlobalStatus.h" #include <system_error> using namespace llvm; +using namespace llvm::object; LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj, llvm::TargetMachine *TM) @@ -51,23 +54,31 @@ LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj, /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM /// bitcode. -bool LTOModule::isBitcodeFile(const void *mem, size_t length) { - return sys::fs::identify_magic(StringRef((const char *)mem, length)) == - sys::fs::file_magic::bitcode; +bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) { + ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer( + MemoryBufferRef(StringRef((const char *)Mem, Length), "<mem>")); + return bool(BCData); } -bool LTOModule::isBitcodeFile(const char *path) { - sys::fs::file_magic type; - if (sys::fs::identify_magic(path, type)) +bool LTOModule::isBitcodeFile(const char *Path) { + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = + MemoryBuffer::getFile(Path); + if (!BufferOrErr) return false; - return type == sys::fs::file_magic::bitcode; + + ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer( + BufferOrErr.get()->getMemBufferRef()); + return bool(BCData); } -bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer, - StringRef triplePrefix) { - std::string Triple = - getBitcodeTargetTriple(buffer->getMemBufferRef(), getGlobalContext()); - return StringRef(Triple).startswith(triplePrefix); +bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, + StringRef TriplePrefix) { + ErrorOr<MemoryBufferRef> BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); + if (!BCOrErr) + return false; + std::string Triple = getBitcodeTargetTriple(*BCOrErr, getGlobalContext()); + return StringRef(Triple).startswith(TriplePrefix); } LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, @@ -113,7 +124,13 @@ LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, std::string &errMsg) { - ErrorOr<Module *> MOrErr = parseBitcodeFile(Buffer, getGlobalContext()); + ErrorOr<MemoryBufferRef> MBOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer); + if (std::error_code EC = MBOrErr.getError()) { + errMsg = EC.message(); + return nullptr; + } + ErrorOr<Module *> MOrErr = parseBitcodeFile(*MBOrErr, getGlobalContext()); if (std::error_code EC = MOrErr.getError()) { errMsg = EC.message(); return nullptr; diff --git a/llvm/lib/Object/Error.cpp b/llvm/lib/Object/Error.cpp index e7431d78074..44667c247b1 100644 --- a/llvm/lib/Object/Error.cpp +++ b/llvm/lib/Object/Error.cpp @@ -41,6 +41,8 @@ std::string _object_error_category::message(int EV) const { return "Invalid data was encountered while parsing the file"; case object_error::unexpected_eof: return "The end of the file was unexpectedly encountered"; + case object_error::bitcode_section_not_found: + return "Bitcode section not found in object file"; } llvm_unreachable("An enumerator of object_error does not have a message " "defined."); diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp index 856f4c6c278..f3bea51be97 100644 --- a/llvm/lib/Object/IRObjectFile.cpp +++ b/llvm/lib/Object/IRObjectFile.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" @@ -264,11 +265,50 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const { return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } +ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { + for (const SectionRef &Sec : Obj.sections()) { + StringRef SecName; + if (std::error_code EC = Sec.getName(SecName)) + return EC; + if (SecName == ".llvmbc") { + StringRef SecContents; + if (std::error_code EC = Sec.getContents(SecContents)) + return EC; + return MemoryBufferRef(SecContents, Obj.getFileName()); + } + } + + return object_error::bitcode_section_not_found; +} + +ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { + sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); + switch (Type) { + case sys::fs::file_magic::bitcode: + return Object; + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::coff_object: { + ErrorOr<std::unique_ptr<ObjectFile>> ObjFile = + ObjectFile::createObjectFile(Object, Type); + if (!ObjFile) + return ObjFile.getError(); + return findBitcodeInObject(*ObjFile->get()); + } + default: + return object_error::invalid_file_type; + } +} + ErrorOr<std::unique_ptr<IRObjectFile>> llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, LLVMContext &Context) { + ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); + if (!BCOrErr) + return BCOrErr.getError(); - std::unique_ptr<MemoryBuffer> Buff(MemoryBuffer::getMemBuffer(Object, false)); + std::unique_ptr<MemoryBuffer> Buff( + MemoryBuffer::getMemBuffer(BCOrErr.get(), false)); ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context); if (std::error_code EC = MOrErr.getError()) diff --git a/llvm/lib/Object/SymbolicFile.cpp b/llvm/lib/Object/SymbolicFile.cpp index f8dd4b33a39..9dfb09dbeca 100644 --- a/llvm/lib/Object/SymbolicFile.cpp +++ b/llvm/lib/Object/SymbolicFile.cpp @@ -40,11 +40,9 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( case sys::fs::file_magic::macho_universal_binary: case sys::fs::file_magic::windows_resource: return object_error::invalid_file_type; - case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::elf_executable: case sys::fs::file_magic::elf_shared_object: case sys::fs::file_magic::elf_core: - case sys::fs::file_magic::macho_object: case sys::fs::file_magic::macho_executable: case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: case sys::fs::file_magic::macho_core: @@ -54,10 +52,26 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( case sys::fs::file_magic::macho_bundle: case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: case sys::fs::file_magic::macho_dsym_companion: - case sys::fs::file_magic::coff_object: case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::pecoff_executable: return ObjectFile::createObjectFile(Object, Type); + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::coff_object: { + ErrorOr<std::unique_ptr<ObjectFile>> Obj = + ObjectFile::createObjectFile(Object, Type); + if (!Obj || !Context) + return std::move(Obj); + + ErrorOr<MemoryBufferRef> BCData = + IRObjectFile::findBitcodeInObject(*Obj->get()); + if (!BCData) + return std::move(Obj); + + return IRObjectFile::createIRObjectFile( + MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()), + *Context); + } } llvm_unreachable("Unexpected Binary File Type"); } |