[llvm-commits] [llvm] r172919 - in /llvm/trunk: include/llvm/Bitcode/BitstreamReader.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Reader/BitstreamReader.cpp
Chris Lattner
sabre at nondot.org
Sat Jan 19 13:35:24 PST 2013
Author: lattner
Date: Sat Jan 19 15:35:24 2013
New Revision: 172919
URL: http://llvm.org/viewvc/llvm-project?rev=172919&view=rev
Log:
Add a new BitstreamEntry concept, and add two helper methods for walking
through a BitstreamCursor that produce it: advance() and
advanceSkippingSubblocks(), representing the two most common ways clients
want to walk through bitcode.
Modified:
llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp
Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=172919&r1=172918&r2=172919&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original)
+++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Sat Jan 19 15:35:24 2013
@@ -27,6 +27,11 @@
class Deserializer;
+/// BitstreamReader - 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 {
public:
/// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
@@ -119,9 +124,48 @@
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}
+};
+
+
+/// BitstreamEntry - When advancing through a bitstream cursor, each advance can
+/// discover a few different kinds of entries:
+/// Error - Malformed bitcode was found.
+/// EndBlock - We've reached the end of the current block, (or the end of the
+/// file, which is treated like a series of EndBlock records.
+/// SubBlock - This is the start of a new subblock of a specific ID.
+/// Record - This is a record with a specific AbbrevID.
+///
+struct BitstreamEntry {
+ enum {
+ Error,
+ EndBlock,
+ SubBlock,
+ Record
+ } Kind;
+
+ unsigned ID;
+ static BitstreamEntry getError() {
+ BitstreamEntry E; E.Kind = Error; return E;
+ }
+ static BitstreamEntry getEndBlock() {
+ BitstreamEntry E; E.Kind = EndBlock; return E;
+ }
+ static BitstreamEntry getSubBlock(unsigned ID) {
+ BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
+ }
+ static BitstreamEntry getRecord(unsigned AbbrevID) {
+ BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
+ }
};
+
+/// BitstreamCursor - This represents a position within a bitcode file. There
+/// may be multiple independent cursors reading within one bitstream, each
+/// maintaining their own local state.
+///
+/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not
+/// be passed by value.
class BitstreamCursor {
friend class Deserializer;
BitstreamReader *BitStream;
@@ -151,6 +195,7 @@
/// BlockScope - This tracks the codesize of parent blocks.
SmallVector<Block, 8> BlockScope;
+
public:
BitstreamCursor() : BitStream(0), NextChar(0) {
}
@@ -183,9 +228,6 @@
void freeState();
- /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
- unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
-
bool isEndPos(size_t pos) {
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
}
@@ -212,6 +254,9 @@
return isEndPos(NextChar) && BitsInCurWord == 0;
}
+ /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
+ unsigned getAbbrevIDWidth() const { return CurCodeSize; }
+
/// GetCurrentBitNo - Return the bit # of the bit we are reading.
uint64_t GetCurrentBitNo() const {
return NextChar*CHAR_BIT - BitsInCurWord;
@@ -224,6 +269,46 @@
return BitStream;
}
+
+ /// advance - Advance the current bitstream, returning the next entry in the
+ /// stream.
+ BitstreamEntry advance() {
+ while (1) {
+ unsigned Code = ReadCode();
+ if (Code == bitc::END_BLOCK) {
+ if (ReadBlockEnd())
+ return BitstreamEntry::getError();
+ return BitstreamEntry::getEndBlock();
+ }
+
+ if (Code == bitc::ENTER_SUBBLOCK)
+ return BitstreamEntry::getSubBlock(ReadSubBlockID());
+
+ if (Code == bitc::DEFINE_ABBREV) {
+ // We read and accumulate abbrev's, the client can't do anything with
+ // them anyway.
+ ReadAbbrevRecord();
+ continue;
+ }
+
+ return BitstreamEntry::getRecord(Code);
+ }
+ }
+
+ /// advanceSkippingSubblocks - This is a convenience function for clients that
+ /// don't expect any subblocks. This just skips over them automatically.
+ BitstreamEntry advanceSkippingSubblocks() {
+ while (1) {
+ // If we found a normal entry, return it.
+ BitstreamEntry Entry = advance();
+ if (Entry.Kind != BitstreamEntry::SubBlock)
+ return Entry;
+
+ // If we found a sub-block, just skip over it and check the next entry.
+ if (SkipBlock())
+ return BitstreamEntry::getError();
+ }
+ }
/// JumpToBit - Reset the stream to the specified bit number.
void JumpToBit(uint64_t BitNo) {
@@ -375,12 +460,13 @@
// [END_BLOCK, <align4bytes>]
SkipToWord();
- PopBlockScope();
+ popBlockScope();
return false;
}
private:
- void PopBlockScope() {
+
+ void popBlockScope() {
CurCodeSize = BlockScope.back().PrevCodeSize;
// Delete abbrevs from popped scope.
@@ -443,7 +529,6 @@
//===--------------------------------------------------------------------===//
// Abbrev Processing
//===--------------------------------------------------------------------===//
-
void ReadAbbrevRecord();
bool ReadBlockInfoBlock();
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=172919&r1=172918&r2=172919&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sat Jan 19 15:35:24 2013
@@ -1737,7 +1737,7 @@
// The ranlib in xcode 4 will align archive members by appending newlines
// to the end of them. If this file size is a multiple of 4 but not 8, we
// have to read and ignore these final 4 bytes :-(
- if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 &&
+ if (Stream.getAbbrevIDWidth() == 2 && Code == 2 &&
Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
Stream.AtEndOfStream())
return false;
Modified: llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp?rev=172919&r1=172918&r2=172919&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitstreamReader.cpp Sat Jan 19 15:35:24 2013
@@ -150,7 +150,7 @@
// the data, do so to avoid copying it.
if (BlobStart) {
*BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer(
- NextChar, NumElts);
+ NextChar, NumElts);
*BlobLen = NumElts;
} else {
for (; NumElts; ++NextChar, --NumElts)
More information about the llvm-commits
mailing list