[llvm] r286207 - Bitcode: Decouple block info block state from reader.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 7 20:17:12 PST 2016


Author: pcc
Date: Mon Nov  7 22:17:11 2016
New Revision: 286207

URL: http://llvm.org/viewvc/llvm-project?rev=286207&view=rev
Log:
Bitcode: Decouple block info block state from reader.

As proposed on llvm-dev:
http://lists.llvm.org/pipermail/llvm-dev/2016-October/106630.html

Move block info block state to a new class, BitstreamBlockInfo.
Clients may set the block info for a particular cursor with the
BitstreamCursor::setBlockInfo() method.

At this point BitstreamReader is not much more than a container for an
ArrayRef<uint8_t>, so remove it and replace all uses with direct uses
of memory buffers.

Differential Revision: https://reviews.llvm.org/D26259

Modified:
    llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp
    llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
    llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp

Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=286207&r1=286206&r2=286207&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original)
+++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Nov  7 22:17:11 2016
@@ -35,11 +35,8 @@
 
 namespace llvm {
 
-/// This class is used to read from an LLVM bitcode stream, maintaining
-/// information that is global to decoding the entire file. While a file is
-/// being read, multiple cursors can be independently advanced or skipped around
-/// within the file.  These are represented by the BitstreamCursor class.
-class BitstreamReader {
+/// This class maintains the abbreviations read from a block info block.
+class BitstreamBlockInfo {
 public:
   /// This contains information emitted to BLOCKINFO_BLOCK blocks. These
   /// describe abbreviations that all blocks of the specified ID inherit.
@@ -51,39 +48,9 @@ public:
   };
 
 private:
-  ArrayRef<uint8_t> BitcodeBytes;
-
   std::vector<BlockInfo> BlockInfoRecords;
 
-  /// This is set to true if we don't care about the block/record name
-  /// information in the BlockInfo block. Only llvm-bcanalyzer uses this.
-  bool IgnoreBlockInfoNames = true;
-
 public:
-  BitstreamReader() = default;
-  BitstreamReader(ArrayRef<uint8_t> BitcodeBytes)
-      : BitcodeBytes(BitcodeBytes) {}
-  BitstreamReader(StringRef BitcodeBytes)
-      : BitcodeBytes(reinterpret_cast<const uint8_t *>(BitcodeBytes.data()),
-                     BitcodeBytes.size()) {}
-  BitstreamReader(MemoryBufferRef BitcodeBytes)
-      : BitstreamReader(BitcodeBytes.getBuffer()) {}
-
-  ArrayRef<uint8_t> getBitcodeBytes() { return BitcodeBytes; }
-
-  /// This is called by clients that want block/record name information.
-  void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
-  bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; }
-
-  //===--------------------------------------------------------------------===//
-  // Block Manipulation
-  //===--------------------------------------------------------------------===//
-
-  /// Return true if we've already read and processed the block info block for
-  /// this Bitstream. We only process it for the first cursor that walks over
-  /// it.
-  bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); }
-
   /// If there is block info for the specified ID, return it, otherwise return
   /// null.
   const BlockInfo *getBlockInfo(unsigned BlockID) const {
@@ -107,22 +74,13 @@ public:
     BlockInfoRecords.back().BlockID = BlockID;
     return BlockInfoRecords.back();
   }
-
-  /// Takes block info from the other bitstream reader.
-  ///
-  /// This is a "take" operation because BlockInfo records are non-trivial, and
-  /// indeed rather expensive.
-  void takeBlockInfo(BitstreamReader &&Other) {
-    assert(!hasBlockInfoRecords());
-    BlockInfoRecords = std::move(Other.BlockInfoRecords);
-  }
 };
 
 /// This represents a position within a bitstream. There may be multiple
 /// independent cursors reading within one bitstream, each maintaining their
 /// own local state.
 class SimpleBitstreamCursor {
-  BitstreamReader *R = nullptr;
+  ArrayRef<uint8_t> BitcodeBytes;
   size_t NextChar = 0;
 
 public:
@@ -144,17 +102,21 @@ public:
   static const size_t MaxChunkSize = sizeof(word_t) * 8;
 
   SimpleBitstreamCursor() = default;
-
-  explicit SimpleBitstreamCursor(BitstreamReader &R) : R(&R) {}
-  explicit SimpleBitstreamCursor(BitstreamReader *R) : R(R) {}
+  explicit SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
+      : BitcodeBytes(BitcodeBytes) {}
+  explicit SimpleBitstreamCursor(StringRef BitcodeBytes)
+      : BitcodeBytes(reinterpret_cast<const uint8_t *>(BitcodeBytes.data()),
+                     BitcodeBytes.size()) {}
+  explicit SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes)
+      : SimpleBitstreamCursor(BitcodeBytes.getBuffer()) {}
 
   bool canSkipToPos(size_t pos) const {
     // pos can be skipped to if it is a valid address or one byte past the end.
-    return pos <= R->getBitcodeBytes().size();
+    return pos <= BitcodeBytes.size();
   }
 
   bool AtEndOfStream() {
-    return BitsInCurWord == 0 && R->getBitcodeBytes().size() <= NextChar;
+    return BitsInCurWord == 0 && BitcodeBytes.size() <= NextChar;
   }
 
   /// Return the bit # of the bit we are reading.
@@ -165,8 +127,7 @@ public:
   // Return the byte # of the current bit.
   uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; }
 
-  BitstreamReader *getBitStreamReader() { return R; }
-  const BitstreamReader *getBitStreamReader() const { return R; }
+  ArrayRef<uint8_t> getBitcodeBytes() const { return BitcodeBytes; }
 
   /// Reset the stream to the specified bit number.
   void JumpToBit(uint64_t BitNo) {
@@ -183,27 +144,9 @@ public:
       Read(WordBitNo);
   }
 
-  /// Reset the stream to the bit pointed at by the specified pointer.
-  ///
-  /// The pointer must be a dereferenceable pointer into the bytes in the
-  /// underlying memory object.
-  void jumpToPointer(const uint8_t *Pointer) {
-    auto *Pointer0 = getPointerToByte(0, 1);
-    assert((intptr_t)Pointer0 <= (intptr_t)Pointer &&
-           "Expected pointer into bitstream");
-
-    JumpToBit(8 * (Pointer - Pointer0));
-    assert((intptr_t)getPointerToByte(getCurrentByteNo(), 1) ==
-               (intptr_t)Pointer &&
-           "Expected to reach pointer");
-  }
-  void jumpToPointer(const char *Pointer) {
-    jumpToPointer((const uint8_t *)Pointer);
-  }
-
   /// Get a pointer into the bitstream at the specified byte offset.
   const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) {
-    return R->getBitcodeBytes().data() + ByteNo;
+    return BitcodeBytes.data() + ByteNo;
   }
 
   /// Get a pointer into the bitstream at the specified bit offset.
@@ -215,21 +158,20 @@ public:
   }
 
   void fillCurWord() {
-    ArrayRef<uint8_t> Buf = R->getBitcodeBytes();
-    if (NextChar >= Buf.size())
+    if (NextChar >= BitcodeBytes.size())
       report_fatal_error("Unexpected end of file");
 
     // Read the next word from the stream.
-    const uint8_t *NextCharPtr = Buf.data() + NextChar;
+    const uint8_t *NextCharPtr = BitcodeBytes.data() + NextChar;
     unsigned BytesRead;
-    if (Buf.size() >= NextChar + sizeof(word_t)) {
+    if (BitcodeBytes.size() >= NextChar + sizeof(word_t)) {
       BytesRead = sizeof(word_t);
       CurWord =
           support::endian::read<word_t, support::little, support::unaligned>(
               NextCharPtr);
     } else {
       // Short read.
-      BytesRead = Buf.size() - NextChar;
+      BytesRead = BitcodeBytes.size() - NextChar;
       CurWord = 0;
       for (unsigned B = 0; B != BytesRead; ++B)
         CurWord |= uint64_t(NextCharPtr[B]) << (B * 8);
@@ -330,7 +272,7 @@ public:
   }
 
   /// Skip to the end of the file.
-  void skipToEnd() { NextChar = R->getBitcodeBytes().size(); }
+  void skipToEnd() { NextChar = BitcodeBytes.size(); }
 };
 
 /// When advancing through a bitstream cursor, each advance can discover a few
@@ -386,27 +328,25 @@ class BitstreamCursor : SimpleBitstreamC
   /// This tracks the codesize of parent blocks.
   SmallVector<Block, 8> BlockScope;
 
+  BitstreamBlockInfo *BlockInfo = nullptr;
+
 public:
   static const size_t MaxChunkSize = sizeof(word_t) * 8;
 
   BitstreamCursor() = default;
-
-  explicit BitstreamCursor(BitstreamReader &R) { init(&R); }
-
-  void init(BitstreamReader *R) {
-    freeState();
-    SimpleBitstreamCursor::operator=(SimpleBitstreamCursor(R));
-    CurCodeSize = 2;
-  }
-
-  void freeState();
+  explicit BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
+      : SimpleBitstreamCursor(BitcodeBytes) {}
+  explicit BitstreamCursor(StringRef BitcodeBytes)
+      : SimpleBitstreamCursor(BitcodeBytes) {}
+  explicit BitstreamCursor(MemoryBufferRef BitcodeBytes)
+      : SimpleBitstreamCursor(BitcodeBytes) {}
 
   using SimpleBitstreamCursor::canSkipToPos;
   using SimpleBitstreamCursor::AtEndOfStream;
+  using SimpleBitstreamCursor::getBitcodeBytes;
   using SimpleBitstreamCursor::GetCurrentBitNo;
   using SimpleBitstreamCursor::getCurrentByteNo;
   using SimpleBitstreamCursor::getPointerToByte;
-  using SimpleBitstreamCursor::getBitStreamReader;
   using SimpleBitstreamCursor::JumpToBit;
   using SimpleBitstreamCursor::fillCurWord;
   using SimpleBitstreamCursor::Read;
@@ -549,7 +489,17 @@ public:
   //===--------------------------------------------------------------------===//
   void ReadAbbrevRecord();
 
-  bool ReadBlockInfoBlock();
+  /// Read and return a block info block from the bitstream. If an error was
+  /// encountered, return None.
+  ///
+  /// \param ReadBlockInfoNames Whether to read block/record name information in
+  /// the BlockInfo block. Only llvm-bcanalyzer uses this.
+  Optional<BitstreamBlockInfo>
+  ReadBlockInfoBlock(bool ReadBlockInfoNames = false);
+
+  /// Set the block info to be used by this BitstreamCursor to interpret
+  /// abbreviated records.
+  void setBlockInfo(BitstreamBlockInfo *BI) { BlockInfo = BI; }
 };
 
 } // end llvm namespace

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=286207&r1=286206&r2=286207&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Nov  7 22:17:11 2016
@@ -233,7 +233,7 @@ protected:
   BitcodeReaderBase(MemoryBuffer *Buffer) : Buffer(Buffer) {}
 
   std::unique_ptr<MemoryBuffer> Buffer;
-  std::unique_ptr<BitstreamReader> StreamFile;
+  BitstreamBlockInfo BlockInfo;
   BitstreamCursor Stream;
 
   std::error_code initStream();
@@ -256,8 +256,8 @@ std::error_code BitcodeReaderBase::initS
     if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
       return error("Invalid bitcode wrapper header");
 
-  StreamFile.reset(new BitstreamReader(ArrayRef<uint8_t>(BufPtr, BufEnd)));
-  Stream.init(&*StreamFile);
+  Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, BufEnd));
+  Stream.setBlockInfo(&BlockInfo);
 
   return std::error_code();
 }
@@ -2211,8 +2211,7 @@ std::error_code BitcodeReader::parseMeta
     return error("Invalid record: metadata strings corrupt offset");
 
   StringRef Lengths = Blob.slice(0, StringsOffset);
-  SimpleBitstreamCursor R(*StreamFile);
-  R.jumpToPointer(Lengths.begin());
+  SimpleBitstreamCursor R(Lengths);
 
   StringRef Strings = Blob.drop_front(StringsOffset);
   do {
@@ -3759,9 +3758,12 @@ std::error_code BitcodeReader::parseBitc
   }
 }
 
-
 bool BitcodeReaderBase::readBlockInfo() {
-  return Stream.ReadBlockInfoBlock();
+  Optional<BitstreamBlockInfo> NewBlockInfo = Stream.ReadBlockInfoBlock();
+  if (!NewBlockInfo)
+    return true;
+  BlockInfo = std::move(*NewBlockInfo);
+  return false;
 }
 
 std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,

Modified: llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp?rev=286207&r1=286206&r2=286207&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp Mon Nov  7 22:17:11 2016
@@ -18,14 +18,6 @@ using namespace llvm;
 //  BitstreamCursor implementation
 //===----------------------------------------------------------------------===//
 
-void BitstreamCursor::freeState() {
-  // Free all the Abbrevs.
-  CurAbbrevs.clear();
-
-  // Free all the Abbrevs in the block scope.
-  BlockScope.clear();
-}
-
 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
 /// the block, and return true if the block has an error.
 bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
@@ -34,10 +26,12 @@ bool BitstreamCursor::EnterSubBlock(unsi
   BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
 
   // Add the abbrevs specific to this block to the CurAbbrevs list.
-  if (const BitstreamReader::BlockInfo *Info =
-          getBitStreamReader()->getBlockInfo(BlockID)) {
-    CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
-                      Info->Abbrevs.end());
+  if (BlockInfo) {
+    if (const BitstreamBlockInfo::BlockInfo *Info =
+            BlockInfo->getBlockInfo(BlockID)) {
+      CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
+                        Info->Abbrevs.end());
+    }
   }
 
   // Get the codesize of this block.
@@ -318,15 +312,14 @@ void BitstreamCursor::ReadAbbrevRecord()
   CurAbbrevs.push_back(Abbv);
 }
 
-bool BitstreamCursor::ReadBlockInfoBlock() {
-  // We expect the client to read the block info block at most once.
-  if (getBitStreamReader()->hasBlockInfoRecords())
-    report_fatal_error("Duplicate read of block info block");
+Optional<BitstreamBlockInfo>
+BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
+  if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return None;
 
-  if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
+  BitstreamBlockInfo NewBlockInfo;
 
   SmallVector<uint64_t, 64> Record;
-  BitstreamReader::BlockInfo *CurBlockInfo = nullptr;
+  BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
 
   // Read all the records for this module.
   while (true) {
@@ -335,9 +328,9 @@ bool BitstreamCursor::ReadBlockInfoBlock
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
-      return true;
+      return None;
     case llvm::BitstreamEntry::EndBlock:
-      return false;
+      return std::move(NewBlockInfo);
     case llvm::BitstreamEntry::Record:
       // The interesting case.
       break;
@@ -345,7 +338,7 @@ bool BitstreamCursor::ReadBlockInfoBlock
 
     // Read abbrev records, associate them with CurBID.
     if (Entry.ID == bitc::DEFINE_ABBREV) {
-      if (!CurBlockInfo) return true;
+      if (!CurBlockInfo) return None;
       ReadAbbrevRecord();
 
       // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
@@ -360,13 +353,12 @@ bool BitstreamCursor::ReadBlockInfoBlock
     switch (readRecord(Entry.ID, Record)) {
       default: break;  // Default behavior, ignore unknown content.
       case bitc::BLOCKINFO_CODE_SETBID:
-        if (Record.size() < 1) return true;
-        CurBlockInfo =
-            &getBitStreamReader()->getOrCreateBlockInfo((unsigned)Record[0]);
+        if (Record.size() < 1) return None;
+        CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
         break;
       case bitc::BLOCKINFO_CODE_BLOCKNAME: {
-        if (!CurBlockInfo) return true;
-        if (getBitStreamReader()->isIgnoringBlockInfoNames())
+        if (!CurBlockInfo) return None;
+        if (!ReadBlockInfoNames)
           break; // Ignore name.
         std::string Name;
         for (unsigned i = 0, e = Record.size(); i != e; ++i)
@@ -375,8 +367,8 @@ bool BitstreamCursor::ReadBlockInfoBlock
         break;
       }
       case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
-        if (!CurBlockInfo) return true;
-        if (getBitStreamReader()->isIgnoringBlockInfoNames())
+        if (!CurBlockInfo) return None;
+        if (!ReadBlockInfoNames)
           break; // Ignore name.
         std::string Name;
         for (unsigned i = 1, e = Record.size(); i != e; ++i)

Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=286207&r1=286206&r2=286207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
+++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Nov  7 22:17:11 2016
@@ -84,7 +84,7 @@ enum CurStreamTypeType {
 /// GetBlockName - Return a symbolic block name if known, otherwise return
 /// null.
 static const char *GetBlockName(unsigned BlockID,
-                                const BitstreamReader &StreamFile,
+                                const BitstreamBlockInfo &BlockInfo,
                                 CurStreamTypeType CurStreamType) {
   // Standard blocks for all bitcode files.
   if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
@@ -94,8 +94,8 @@ static const char *GetBlockName(unsigned
   }
 
   // Check to see if we have a blockinfo record for this block, with a name.
-  if (const BitstreamReader::BlockInfo *Info =
-        StreamFile.getBlockInfo(BlockID)) {
+  if (const BitstreamBlockInfo::BlockInfo *Info =
+          BlockInfo.getBlockInfo(BlockID)) {
     if (!Info->Name.empty())
       return Info->Name.c_str();
   }
@@ -128,7 +128,7 @@ static const char *GetBlockName(unsigned
 /// GetCodeName - Return a symbolic code name if known, otherwise return
 /// null.
 static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
-                               const BitstreamReader &StreamFile,
+                               const BitstreamBlockInfo &BlockInfo,
                                CurStreamTypeType CurStreamType) {
   // Standard blocks for all bitcode files.
   if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
@@ -144,8 +144,8 @@ static const char *GetCodeName(unsigned
   }
 
   // Check to see if we have a blockinfo record for this record, with a name.
-  if (const BitstreamReader::BlockInfo *Info =
-        StreamFile.getBlockInfo(BlockID)) {
+  if (const BitstreamBlockInfo::BlockInfo *Info =
+        BlockInfo.getBlockInfo(BlockID)) {
     for (unsigned i = 0, e = Info->RecordNames.size(); i != e; ++i)
       if (Info->RecordNames[i].first == CodeID)
         return Info->RecordNames[i].second.c_str();
@@ -419,7 +419,7 @@ static bool ReportError(const Twine &Err
   return true;
 }
 
-static bool decodeMetadataStringsBlob(BitstreamReader &Reader, StringRef Indent,
+static bool decodeMetadataStringsBlob(StringRef Indent,
                                       ArrayRef<uint64_t> Record,
                                       StringRef Blob) {
   if (Blob.empty())
@@ -433,9 +433,7 @@ static bool decodeMetadataStringsBlob(Bi
   outs() << " num-strings = " << NumStrings << " {\n";
 
   StringRef Lengths = Blob.slice(0, StringsOffset);
-  SimpleBitstreamCursor R(Reader);
-  R.jumpToPointer(Lengths.begin());
-
+  SimpleBitstreamCursor R(Lengths);
   StringRef Strings = Blob.drop_front(StringsOffset);
   do {
     if (R.AtEndOfStream())
@@ -455,20 +453,20 @@ static bool decodeMetadataStringsBlob(Bi
   return false;
 }
 
-static bool decodeBlob(unsigned Code, unsigned BlockID, BitstreamReader &Reader,
-                       StringRef Indent, ArrayRef<uint64_t> Record,
-                       StringRef Blob) {
+static bool decodeBlob(unsigned Code, unsigned BlockID, StringRef Indent,
+                       ArrayRef<uint64_t> Record, StringRef Blob) {
   if (BlockID != bitc::METADATA_BLOCK_ID)
     return true;
   if (Code != bitc::METADATA_STRINGS)
     return true;
 
-  return decodeMetadataStringsBlob(Reader, Indent, Record, Blob);
+  return decodeMetadataStringsBlob(Indent, Record, Blob);
 }
 
 /// ParseBlock - Read a block, updating statistics, etc.
-static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
-                       unsigned IndentLevel, CurStreamTypeType CurStreamType) {
+static bool ParseBlock(BitstreamCursor &Stream, BitstreamBlockInfo &BlockInfo,
+                       unsigned BlockID, unsigned IndentLevel,
+                       CurStreamTypeType CurStreamType) {
   std::string Indent(IndentLevel*2, ' ');
   uint64_t BlockBitStart = Stream.GetCurrentBitNo();
 
@@ -481,8 +479,12 @@ static bool ParseBlock(BitstreamCursor &
   bool DumpRecords = Dump;
   if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
     if (Dump) outs() << Indent << "<BLOCKINFO_BLOCK/>\n";
-    if (BitstreamCursor(Stream).ReadBlockInfoBlock())
+    Optional<BitstreamBlockInfo> NewBlockInfo =
+        Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true);
+    if (!NewBlockInfo)
       return ReportError("Malformed BlockInfoBlock");
+    BlockInfo = std::move(*NewBlockInfo);
+    Stream.JumpToBit(BlockBitStart);
     // It's not really interesting to dump the contents of the blockinfo block.
     DumpRecords = false;
   }
@@ -497,8 +499,7 @@ static bool ParseBlock(BitstreamCursor &
   const char *BlockName = nullptr;
   if (DumpRecords) {
     outs() << Indent << "<";
-    if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader(),
-                                  CurStreamType)))
+    if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType)))
       outs() << BlockName;
     else
       outs() << "UnknownBlock" << BlockID;
@@ -540,7 +541,8 @@ static bool ParseBlock(BitstreamCursor &
         
     case BitstreamEntry::SubBlock: {
       uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
-      if (ParseBlock(Stream, Entry.ID, IndentLevel+1, CurStreamType))
+      if (ParseBlock(Stream, BlockInfo, Entry.ID, IndentLevel + 1,
+                     CurStreamType))
         return true;
       ++BlockStats.NumSubBlocks;
       uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
@@ -582,14 +584,11 @@ static bool ParseBlock(BitstreamCursor &
     if (DumpRecords) {
       outs() << Indent << "  <";
       if (const char *CodeName =
-            GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
-                        CurStreamType))
+              GetCodeName(Code, BlockID, BlockInfo, CurStreamType))
         outs() << CodeName;
       else
         outs() << "UnknownCode" << Code;
-      if (NonSymbolic &&
-          GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
-                      CurStreamType))
+      if (NonSymbolic && GetCodeName(Code, BlockID, BlockInfo, CurStreamType))
         outs() << " codeid=" << Code;
       const BitCodeAbbrev *Abbv = nullptr;
       if (Entry.ID != bitc::UNABBREV_RECORD) {
@@ -654,8 +653,7 @@ static bool ParseBlock(BitstreamCursor &
         }
       }
 
-      if (Blob.data() && decodeBlob(Code, BlockID, *Stream.getBitStreamReader(),
-                                    Indent, Record, Blob)) {
+      if (Blob.data() && decodeBlob(Code, BlockID, Indent, Record, Blob)) {
         outs() << " blob data = ";
         if (ShowBinaryBlobs) {
           outs() << "'";
@@ -690,7 +688,6 @@ static void PrintSize(uint64_t Bits) {
 
 static bool openBitcodeFile(StringRef Path,
                             std::unique_ptr<MemoryBuffer> &MemBuf,
-                            BitstreamReader &StreamFile,
                             BitstreamCursor &Stream,
                             CurStreamTypeType &CurStreamType) {
   // Read the input file.
@@ -731,9 +728,7 @@ static bool openBitcodeFile(StringRef Pa
       return ReportError("Invalid bitcode wrapper header");
   }
 
-  StreamFile = BitstreamReader(ArrayRef<uint8_t>(BufPtr, EndBufPtr));
-  Stream = BitstreamCursor(StreamFile);
-  StreamFile.CollectBlockInfoNames();
+  Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr));
 
   // Read the stream signature.
   char Signature[6];
@@ -757,22 +752,21 @@ static bool openBitcodeFile(StringRef Pa
 /// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
 static int AnalyzeBitcode() {
   std::unique_ptr<MemoryBuffer> StreamBuffer;
-  BitstreamReader StreamFile;
   BitstreamCursor Stream;
+  BitstreamBlockInfo BlockInfo;
   CurStreamTypeType CurStreamType;
-  if (openBitcodeFile(InputFilename, StreamBuffer, StreamFile, Stream,
-                      CurStreamType))
+  if (openBitcodeFile(InputFilename, StreamBuffer, Stream, CurStreamType))
     return true;
+  Stream.setBlockInfo(&BlockInfo);
 
   // Read block info from BlockInfoFilename, if specified.
   // The block info must be a top-level block.
   if (!BlockInfoFilename.empty()) {
     std::unique_ptr<MemoryBuffer> BlockInfoBuffer;
-    BitstreamReader BlockInfoFile;
     BitstreamCursor BlockInfoCursor;
     CurStreamTypeType BlockInfoStreamType;
-    if (openBitcodeFile(BlockInfoFilename, BlockInfoBuffer, BlockInfoFile,
-                        BlockInfoCursor, BlockInfoStreamType))
+    if (openBitcodeFile(BlockInfoFilename, BlockInfoBuffer, BlockInfoCursor,
+                        BlockInfoStreamType))
       return true;
 
     while (!BlockInfoCursor.AtEndOfStream()) {
@@ -782,15 +776,16 @@ static int AnalyzeBitcode() {
 
       unsigned BlockID = BlockInfoCursor.ReadSubBlockID();
       if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
-        if (BlockInfoCursor.ReadBlockInfoBlock())
+        Optional<BitstreamBlockInfo> NewBlockInfo =
+            BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true);
+        if (!NewBlockInfo)
           return ReportError("Malformed BlockInfoBlock in block info file");
+        BlockInfo = std::move(*NewBlockInfo);
         break;
       }
 
       BlockInfoCursor.SkipBlock();
     }
-
-    StreamFile.takeBlockInfo(std::move(BlockInfoFile));
   }
 
   unsigned NumTopBlocks = 0;
@@ -803,14 +798,14 @@ static int AnalyzeBitcode() {
 
     unsigned BlockID = Stream.ReadSubBlockID();
 
-    if (ParseBlock(Stream, BlockID, 0, CurStreamType))
+    if (ParseBlock(Stream, BlockInfo, BlockID, 0, CurStreamType))
       return true;
     ++NumTopBlocks;
   }
 
   if (Dump) outs() << "\n\n";
 
-  uint64_t BufferSizeBits = StreamFile.getBitcodeBytes().size() * CHAR_BIT;
+  uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT;
   // Print a summary of the read file.
   outs() << "Summary of " << InputFilename << ":\n";
   outs() << "         Total size: ";
@@ -829,8 +824,8 @@ static int AnalyzeBitcode() {
   for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
        E = BlockIDStats.end(); I != E; ++I) {
     outs() << "  Block ID #" << I->first;
-    if (const char *BlockName = GetBlockName(I->first, StreamFile,
-                                             CurStreamType))
+    if (const char *BlockName =
+            GetBlockName(I->first, BlockInfo, CurStreamType))
       outs() << " (" << BlockName << ")";
     outs() << ":\n";
 
@@ -894,9 +889,8 @@ static int AnalyzeBitcode() {
           outs() << "        ";
 
         outs() << "  ";
-        if (const char *CodeName =
-              GetCodeName(FreqPairs[i].second, I->first, StreamFile,
-                          CurStreamType))
+        if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first,
+                                               BlockInfo, CurStreamType))
           outs() << CodeName << "\n";
         else
           outs() << "UnknownCode" << FreqPairs[i].second << "\n";

Modified: llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp?rev=286207&r1=286206&r2=286207&view=diff
==============================================================================
--- llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp (original)
+++ llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp Mon Nov  7 22:17:11 2016
@@ -20,8 +20,7 @@ TEST(BitstreamReaderTest, AtEndOfStream)
   uint8_t Bytes[4] = {
     0x00, 0x01, 0x02, 0x03
   };
-  BitstreamReader Reader(Bytes);
-  BitstreamCursor Cursor(Reader);
+  BitstreamCursor Cursor(Bytes);
 
   EXPECT_FALSE(Cursor.AtEndOfStream());
   (void)Cursor.Read(8);
@@ -40,24 +39,21 @@ TEST(BitstreamReaderTest, AtEndOfStreamJ
   uint8_t Bytes[4] = {
     0x00, 0x01, 0x02, 0x03
   };
-  BitstreamReader Reader(Bytes);
-  BitstreamCursor Cursor(Reader);
+  BitstreamCursor Cursor(Bytes);
 
   Cursor.JumpToBit(32);
   EXPECT_TRUE(Cursor.AtEndOfStream());
 }
 
 TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
-  BitstreamReader Reader(ArrayRef<uint8_t>{});
-  BitstreamCursor Cursor(Reader);
+  BitstreamCursor Cursor(ArrayRef<uint8_t>{});
 
   EXPECT_TRUE(Cursor.AtEndOfStream());
 }
 
 TEST(BitstreamReaderTest, getCurrentByteNo) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
-  BitstreamReader Reader(Bytes);
-  SimpleBitstreamCursor Cursor(Reader);
+  SimpleBitstreamCursor Cursor(Bytes);
 
   for (unsigned I = 0, E = 32; I != E; ++I) {
     EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
@@ -68,8 +64,7 @@ TEST(BitstreamReaderTest, getCurrentByte
 
 TEST(BitstreamReaderTest, getPointerToByte) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(Bytes);
-  SimpleBitstreamCursor Cursor(Reader);
+  SimpleBitstreamCursor Cursor(Bytes);
 
   for (unsigned I = 0, E = 8; I != E; ++I) {
     EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
@@ -78,25 +73,13 @@ TEST(BitstreamReaderTest, getPointerToBy
 
 TEST(BitstreamReaderTest, getPointerToBit) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(Bytes);
-  SimpleBitstreamCursor Cursor(Reader);
+  SimpleBitstreamCursor Cursor(Bytes);
 
   for (unsigned I = 0, E = 8; I != E; ++I) {
     EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
   }
 }
 
-TEST(BitstreamReaderTest, jumpToPointer) {
-  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(Bytes);
-  SimpleBitstreamCursor Cursor(Reader);
-
-  for (unsigned I : {0, 6, 2, 7}) {
-    Cursor.jumpToPointer(Bytes + I);
-    EXPECT_EQ(I, Cursor.getCurrentByteNo());
-  }
-}
-
 TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
   SmallVector<uint8_t, 1> BlobData;
   for (unsigned I = 0, E = 1024; I != E; ++I)
@@ -129,9 +112,8 @@ TEST(BitstreamReaderTest, readRecordWith
     }
 
     // Stream the buffer into the reader.
-    BitstreamReader R(
+    BitstreamCursor Stream(
         ArrayRef<uint8_t>((const uint8_t *)Buffer.begin(), Buffer.size()));
-    BitstreamCursor Stream(R);
 
     // Header.  Included in test so that we can run llvm-bcanalyzer to debug
     // when there are problems.
@@ -161,8 +143,7 @@ TEST(BitstreamReaderTest, readRecordWith
 TEST(BitstreamReaderTest, shortRead) {
   uint8_t Bytes[] = {8, 7, 6, 5, 4, 3, 2, 1};
   for (unsigned I = 1; I != 8; ++I) {
-    BitstreamReader Reader(ArrayRef<uint8_t>(Bytes, I));
-    SimpleBitstreamCursor Cursor(Reader);
+    SimpleBitstreamCursor Cursor(ArrayRef<uint8_t>(Bytes, I));
     EXPECT_EQ(8ull, Cursor.Read(8));
   }
 }




More information about the llvm-commits mailing list