From: Mehdi Amini Date: Mon, 9 Nov 2015 02:46:41 +0000 (+0000) Subject: Add a method to the BitcodeReader to parse only the identification block X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=dd77c4496e00dee0cbc5a270e83095dca7853fff Add a method to the BitcodeReader to parse only the identification block Summary: Mimic parseTriple(); and exposes it to LTOModule.cpp Reviewers: dexonsmith, rafael Subscribers: llvm-commits From: Mehdi Amini git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252442 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 5f1c7200468..dc039557ae3 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -54,6 +54,13 @@ namespace llvm { getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler = nullptr); + /// Read the header of the specified bitcode buffer and extract just the + /// producer string information. If successful, this returns a string. On + /// error, this returns "". + std::string getBitcodeProducerString( + MemoryBufferRef Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler = nullptr); + /// Read the specified bitcode file, returning the module. ErrorOr> parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h index eda5a3a09ce..c3e86afe1d8 100644 --- a/include/llvm/LTO/LTOModule.h +++ b/include/llvm/LTO/LTOModule.h @@ -74,6 +74,11 @@ public: static bool isBitcodeForTarget(MemoryBuffer *memBuffer, StringRef triplePrefix); + /// Returns a string representing the producer identification stored in the + /// bitcode, or "" if the bitcode does not contains any. + /// + static std::string getProducerString(MemoryBuffer *Buffer); + /// Create a MemoryBuffer from a memory range with an optional name. static std::unique_ptr makeBuffer(const void *mem, size_t length, StringRef name = ""); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 8920b6ed460..7e760e25784 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -271,6 +271,9 @@ public: /// \returns true if an error occurred. ErrorOr parseTriple(); + /// Cheap mechanism to just extract the identification block out of bitcode. + ErrorOr parseIdentificationBlock(); + static uint64_t decodeSignRotatedValue(uint64_t V); /// Materialize any deferred Metadata block. @@ -3729,6 +3732,41 @@ ErrorOr BitcodeReader::parseTriple() { } } +ErrorOr BitcodeReader::parseIdentificationBlock() { + if (std::error_code EC = initStream(nullptr)) + return EC; + + // Sniff for the signature. + if (!hasValidBitcodeHeader(Stream)) + return error("Invalid bitcode signature"); + + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (1) { + BitstreamEntry Entry = Stream.advance(); + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { + if (std::error_code EC = parseBitcodeVersion()) + return EC; + return ProducerIdentification; + } + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + /// Parse metadata attachments. std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) @@ -5835,6 +5873,17 @@ llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context, return Triple.get(); } +std::string +llvm::getBitcodeProducerString(MemoryBufferRef Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler) { + std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Buffer, false); + BitcodeReader R(Buf.release(), Context, DiagnosticHandler); + ErrorOr ProducerString = R.parseIdentificationBlock(); + if (ProducerString.getError()) + return ""; + return ProducerString.get(); +} + // Parse the specified bitcode buffer, returning the function info index. // If IsLazy is false, parse the entire function summary into // the index. Otherwise skip the function summary section, and only create diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index ec8991ed236..d28563c23b8 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -91,6 +91,15 @@ bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, return StringRef(Triple).startswith(TriplePrefix); } +std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { + ErrorOr BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); + if (!BCOrErr) + return ""; + LLVMContext Context; + return getBitcodeProducerString(*BCOrErr, Context); +} + LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, std::string &errMsg) { ErrorOr> BufferOrErr =