Add a method to the BitcodeReader to parse only the identification block
authorMehdi Amini <mehdi.amini@apple.com>
Mon, 9 Nov 2015 02:46:41 +0000 (02:46 +0000)
committerMehdi Amini <mehdi.amini@apple.com>
Mon, 9 Nov 2015 02:46:41 +0000 (02:46 +0000)
Summary: Mimic parseTriple(); and exposes it to LTOModule.cpp

Reviewers: dexonsmith, rafael

Subscribers: llvm-commits

From: Mehdi Amini <mehdi.amini@apple.com>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252442 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/ReaderWriter.h
include/llvm/LTO/LTOModule.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/LTO/LTOModule.cpp

index 5f1c7200468c5818175f9af229154314b14aa7f2..dc039557ae30729da873ce2d40e44f879f124591 100644 (file)
@@ -54,6 +54,13 @@ namespace llvm {
   getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
                          DiagnosticHandlerFunction DiagnosticHandler = nullptr);
 
   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<std::unique_ptr<Module>>
   parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
   /// Read the specified bitcode file, returning the module.
   ErrorOr<std::unique_ptr<Module>>
   parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
index eda5a3a09ce0ca4466faf493713cfc2626390fa9..c3e86afe1d82b3ea8a42038fe8e119054f525126 100644 (file)
@@ -74,6 +74,11 @@ public:
   static bool isBitcodeForTarget(MemoryBuffer *memBuffer,
                                  StringRef triplePrefix);
 
   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<MemoryBuffer>
   makeBuffer(const void *mem, size_t length, StringRef name = "");
   /// Create a MemoryBuffer from a memory range with an optional name.
   static std::unique_ptr<MemoryBuffer>
   makeBuffer(const void *mem, size_t length, StringRef name = "");
index 8920b6ed4607fcfa6dca7c47ed7008c7799e497e..7e760e2578491759141ab883f201187cf45670c9 100644 (file)
@@ -271,6 +271,9 @@ public:
   /// \returns true if an error occurred.
   ErrorOr<std::string> parseTriple();
 
   /// \returns true if an error occurred.
   ErrorOr<std::string> parseTriple();
 
+  /// Cheap mechanism to just extract the identification block out of bitcode.
+  ErrorOr<std::string> parseIdentificationBlock();
+
   static uint64_t decodeSignRotatedValue(uint64_t V);
 
   /// Materialize any deferred Metadata block.
   static uint64_t decodeSignRotatedValue(uint64_t V);
 
   /// Materialize any deferred Metadata block.
@@ -3729,6 +3732,41 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
   }
 }
 
   }
 }
 
+ErrorOr<std::string> 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))
 /// 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();
 }
 
   return Triple.get();
 }
 
+std::string
+llvm::getBitcodeProducerString(MemoryBufferRef Buffer, LLVMContext &Context,
+                               DiagnosticHandlerFunction DiagnosticHandler) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
+  BitcodeReader R(Buf.release(), Context, DiagnosticHandler);
+  ErrorOr<std::string> 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
 // 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
index ec8991ed236531e5dfd3b2f641d904a2fd2f8c38..d28563c23b806224cb0932374fffd66ec775ca89 100644 (file)
@@ -91,6 +91,15 @@ bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer,
   return StringRef(Triple).startswith(TriplePrefix);
 }
 
   return StringRef(Triple).startswith(TriplePrefix);
 }
 
+std::string LTOModule::getProducerString(MemoryBuffer *Buffer) {
+  ErrorOr<MemoryBufferRef> 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<std::unique_ptr<MemoryBuffer>> BufferOrErr =
 LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options,
                                      std::string &errMsg) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =