Index: llvm/include/llvm/Bitcode/BitstreamReader.h =================================================================== --- llvm/include/llvm/Bitcode/BitstreamReader.h +++ llvm/include/llvm/Bitcode/BitstreamReader.h @@ -39,36 +39,18 @@ /// being read, multiple cursors can be independently advanced or skipped around /// within the file. These are represented by the BitstreamCursor class. class BitstreamReader { -public: - /// This contains information emitted to BLOCKINFO_BLOCK blocks. These - /// describe abbreviations that all blocks of the specified ID inherit. - struct BlockInfo { - unsigned BlockID; - std::vector> Abbrevs; - std::string Name; - std::vector > RecordNames; - }; - private: std::unique_ptr BitcodeBytes; - std::vector 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; - public: - BitstreamReader() : IgnoreBlockInfoNames(true) { - } + BitstreamReader() {} - BitstreamReader(const unsigned char *Start, const unsigned char *End) - : IgnoreBlockInfoNames(true) { + BitstreamReader(const unsigned char *Start, const unsigned char *End) { init(Start, End); } BitstreamReader(std::unique_ptr BitcodeBytes) - : BitcodeBytes(std::move(BitcodeBytes)), IgnoreBlockInfoNames(true) {} + : BitcodeBytes(std::move(BitcodeBytes)) {} void init(const unsigned char *Start, const unsigned char *End) { assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); @@ -76,52 +58,6 @@ } MemoryObject &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 { - // Common case, the most recent entry matches BlockID. - if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) - return &BlockInfoRecords.back(); - - for (unsigned i = 0, e = static_cast(BlockInfoRecords.size()); - i != e; ++i) - if (BlockInfoRecords[i].BlockID == BlockID) - return &BlockInfoRecords[i]; - return nullptr; - } - - BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { - if (const BlockInfo *BI = getBlockInfo(BlockID)) - return *const_cast(BI); - - // Otherwise, add a new record. - BlockInfoRecords.emplace_back(); - 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 @@ -409,6 +345,33 @@ /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not /// be passed by value. class BitstreamCursor : SimpleBitstreamCursor { +public: + /// This contains information emitted to BLOCKINFO_BLOCK blocks. These + /// describe abbreviations that all blocks of the specified ID inherit. + struct BlockInfo { + unsigned BlockID; + std::vector> Abbrevs; + std::string Name; + std::vector > RecordNames; + }; + +private: + std::vector 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; + + BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { + if (const BlockInfo *BI = getBlockInfo(BlockID)) + return *const_cast(BI); + + // Otherwise, add a new record. + BlockInfoRecords.emplace_back(); + BlockInfoRecords.back().BlockID = BlockID; + return BlockInfoRecords.back(); + } + // This is the declared size of code values used for the current block, in // bits. unsigned CurCodeSize = 2; @@ -586,7 +549,39 @@ //===--------------------------------------------------------------------===// void ReadAbbrevRecord(); + //===--------------------------------------------------------------------===// + // Block Manipulation + //===--------------------------------------------------------------------===// + + /// Read abbreviations from a block info block. This function may only be + /// called once for each cursor. bool ReadBlockInfoBlock(); + + /// This is called by clients that want block/record name information. + void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } + + /// If there is block info for the specified ID, return it, otherwise return + /// null. + const BlockInfo *getBlockInfo(unsigned BlockID) const { + // Common case, the most recent entry matches BlockID. + if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) + return &BlockInfoRecords.back(); + + for (unsigned i = 0, e = static_cast(BlockInfoRecords.size()); + i != e; ++i) + if (BlockInfoRecords[i].BlockID == BlockID) + return &BlockInfoRecords[i]; + return nullptr; + } + + /// Takes block info from the other bitstream cursor. + /// + /// This is a "take" operation because BlockInfo records are non-trivial, and + /// indeed rather expensive. + void takeBlockInfo(BitstreamCursor &&Other) { + assert(BlockInfoRecords.empty()); + BlockInfoRecords = std::move(Other.BlockInfoRecords); + } }; } // end llvm namespace Index: llvm/lib/Bitcode/Reader/BitstreamReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitstreamReader.cpp +++ llvm/lib/Bitcode/Reader/BitstreamReader.cpp @@ -34,8 +34,7 @@ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); // Add the abbrevs specific to this block to the CurAbbrevs list. - if (const BitstreamReader::BlockInfo *Info = - getBitStreamReader()->getBlockInfo(BlockID)) { + if (const BlockInfo *Info = getBlockInfo(BlockID)) { CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(), Info->Abbrevs.end()); } @@ -320,13 +319,13 @@ bool BitstreamCursor::ReadBlockInfoBlock() { // We expect the client to read the block info block at most once. - if (getBitStreamReader()->hasBlockInfoRecords()) + if (!BlockInfoRecords.empty()) report_fatal_error("Duplicate read of block info block"); if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; SmallVector Record; - BitstreamReader::BlockInfo *CurBlockInfo = nullptr; + BlockInfo *CurBlockInfo = nullptr; // Read all the records for this module. while (true) { @@ -361,12 +360,11 @@ default: break; // Default behavior, ignore unknown content. case bitc::BLOCKINFO_CODE_SETBID: if (Record.size() < 1) return true; - CurBlockInfo = - &getBitStreamReader()->getOrCreateBlockInfo((unsigned)Record[0]); + CurBlockInfo = &getOrCreateBlockInfo((unsigned)Record[0]); break; case bitc::BLOCKINFO_CODE_BLOCKNAME: { if (!CurBlockInfo) return true; - if (getBitStreamReader()->isIgnoringBlockInfoNames()) + if (IgnoreBlockInfoNames) break; // Ignore name. std::string Name; for (unsigned i = 0, e = Record.size(); i != e; ++i) @@ -376,7 +374,7 @@ } case bitc::BLOCKINFO_CODE_SETRECORDNAME: { if (!CurBlockInfo) return true; - if (getBitStreamReader()->isIgnoringBlockInfoNames()) + if (IgnoreBlockInfoNames) break; // Ignore name. std::string Name; for (unsigned i = 1, e = Record.size(); i != e; ++i) Index: llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp =================================================================== --- llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -83,8 +83,7 @@ /// GetBlockName - Return a symbolic block name if known, otherwise return /// null. -static const char *GetBlockName(unsigned BlockID, - const BitstreamReader &StreamFile, +static const char *GetBlockName(unsigned BlockID, const BitstreamCursor &Stream, CurStreamTypeType CurStreamType) { // Standard blocks for all bitcode files. if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { @@ -94,8 +93,7 @@ } // 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 BitstreamCursor::BlockInfo *Info = Stream.getBlockInfo(BlockID)) { if (!Info->Name.empty()) return Info->Name.c_str(); } @@ -128,7 +126,7 @@ /// GetCodeName - Return a symbolic code name if known, otherwise return /// null. static const char *GetCodeName(unsigned CodeID, unsigned BlockID, - const BitstreamReader &StreamFile, + const BitstreamCursor &Stream, CurStreamTypeType CurStreamType) { // Standard blocks for all bitcode files. if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { @@ -144,8 +142,7 @@ } // 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 BitstreamCursor::BlockInfo *Info = Stream.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(); @@ -485,8 +482,9 @@ bool DumpRecords = Dump; if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { if (Dump) outs() << Indent << "\n"; - if (BitstreamCursor(Stream).ReadBlockInfoBlock()) + if (Stream.ReadBlockInfoBlock()) return ReportError("Malformed BlockInfoBlock"); + Stream.JumpToBit(BlockBitStart); // It's not really interesting to dump the contents of the blockinfo block. DumpRecords = false; } @@ -501,8 +499,7 @@ const char *BlockName = nullptr; if (DumpRecords) { outs() << Indent << "<"; - if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader(), - CurStreamType))) + if ((BlockName = GetBlockName(BlockID, Stream, CurStreamType))) outs() << BlockName; else outs() << "UnknownBlock" << BlockID; @@ -586,14 +583,11 @@ if (DumpRecords) { outs() << Indent << " <"; if (const char *CodeName = - GetCodeName(Code, BlockID, *Stream.getBitStreamReader(), - CurStreamType)) + GetCodeName(Code, BlockID, Stream, CurStreamType)) outs() << CodeName; else outs() << "UnknownCode" << Code; - if (NonSymbolic && - GetCodeName(Code, BlockID, *Stream.getBitStreamReader(), - CurStreamType)) + if (NonSymbolic && GetCodeName(Code, BlockID, Stream, CurStreamType)) outs() << " codeid=" << Code; const BitCodeAbbrev *Abbv = nullptr; if (Entry.ID != bitc::UNABBREV_RECORD) { @@ -737,7 +731,7 @@ StreamFile = BitstreamReader(BufPtr, EndBufPtr); Stream = BitstreamCursor(StreamFile); - StreamFile.CollectBlockInfoNames(); + Stream.CollectBlockInfoNames(); // Read the stream signature. char Signature[6]; @@ -794,7 +788,7 @@ BlockInfoCursor.SkipBlock(); } - StreamFile.takeBlockInfo(std::move(BlockInfoFile)); + Stream.takeBlockInfo(std::move(BlockInfoCursor)); } unsigned NumTopBlocks = 0; @@ -833,8 +827,7 @@ for (std::map::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, Stream, CurStreamType)) outs() << " (" << BlockName << ")"; outs() << ":\n"; @@ -898,9 +891,8 @@ outs() << " "; outs() << " "; - if (const char *CodeName = - GetCodeName(FreqPairs[i].second, I->first, StreamFile, - CurStreamType)) + if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first, + Stream, CurStreamType)) outs() << CodeName << "\n"; else outs() << "UnknownCode" << FreqPairs[i].second << "\n";