[llvm-commits] [llvm] r43973 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h lib/Bitcode/Reader/Deserialize.cpp
Ted Kremenek
kremenek at apple.com
Fri Nov 9 18:02:36 PST 2007
Author: kremenek
Date: Fri Nov 9 20:02:34 2007
New Revision: 43973
URL: http://llvm.org/viewvc/llvm-project?rev=43973&view=rev
Log:
Added "random access" to the Deserializer to allow a client to jump to any
serialized block in the bitstream, including a block in an entirely different
nesting than the current block. This is useful for deserializing objects from
a bitstream in an order different from the order that they were serialized.
Modified:
llvm/trunk/include/llvm/Bitcode/Deserialize.h
llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp
Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43973&r1=43972&r2=43973&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original)
+++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Fri Nov 9 20:02:34 2007
@@ -80,7 +80,36 @@
//===----------------------------------------------------------===//
public:
- typedef uint64_t Location;
+ struct Location {
+ uint64_t BitNo;
+ unsigned BlockID;
+ unsigned NumWords;
+
+ Location(uint64_t bit, unsigned bid, unsigned words)
+ : BitNo(bit), BlockID(bid), NumWords(words) {}
+
+ Location() : BitNo(0), BlockID(0), NumWords(0) {}
+
+ Location& operator=(Location& RHS) {
+ BitNo = RHS.BitNo;
+ BlockID = RHS.BlockID;
+ NumWords = RHS.NumWords;
+ return *this;
+ }
+
+ bool operator==(const Location& RHS) const { return BitNo == RHS.BitNo; }
+ bool operator!=(const Location& RHS) const { return BitNo != RHS.BitNo; }
+
+ bool contains(const Location& RHS) const {
+ if (RHS.BitNo < BitNo)
+ return false;
+
+ if ((RHS.BitNo - BitNo) >> 5 < NumWords)
+ return true;
+
+ return false;
+ }
+ };
//===----------------------------------------------------------===//
// Internal data members.
@@ -93,9 +122,10 @@
BumpPtrAllocator Allocator;
BPNode* FreeList;
MapTy BPatchMap;
- llvm::SmallVector<std::pair<Location,unsigned>,5> BlockStack;
+ llvm::SmallVector<Location,8> BlockStack;
unsigned AbbrevNo;
unsigned RecordCode;
+ Location StreamStart;
//===----------------------------------------------------------===//
// Public Interface.
@@ -238,13 +268,18 @@
unsigned getAbbrevNo();
bool FinishedBlock(Location BlockLoc);
+ bool JumpTo(const Location& BlockLoc);
+ void Rewind() { JumpTo(StreamStart); }
bool AtEnd();
bool inRecord();
void SkipBlock();
+ bool SkipToBlock(unsigned BlockID);
unsigned getRecordCode();
+ BitstreamReader& getStream() { return Stream; }
+
private:
bool AdvanceStream();
void ReadRecord();
Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43973&r1=43972&r2=43973&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Fri Nov 9 20:02:34 2007
@@ -21,6 +21,9 @@
Deserializer::Deserializer(BitstreamReader& stream)
: Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {
+
+ AdvanceStream();
+ if (!AtEnd()) StreamStart = BlockStack.back();
}
Deserializer::~Deserializer() {
@@ -60,12 +63,24 @@
while (!Stream.AtEndOfStream()) {
+ uint64_t Pos = Stream.GetCurrentBitNo();
AbbrevNo = Stream.ReadCode();
switch (AbbrevNo) {
case bitc::ENTER_SUBBLOCK: {
unsigned id = Stream.ReadSubBlockID();
- BlockStack.push_back(std::make_pair(Stream.GetCurrentBitNo(),id));
+
+ // Determine the extent of the block. This is useful for jumping around
+ // the stream. This is hack: we read the header of the block, save
+ // the length, and then revert the bitstream to a location just before
+ // the block is entered.
+ uint64_t BPos = Stream.GetCurrentBitNo();
+ Stream.ReadVBR(bitc::CodeLenWidth); // Skip the code size.
+ Stream.SkipToWord();
+ unsigned NumWords = Stream.Read(bitc::BlockSizeWidth);
+ Stream.JumpToBit(BPos);
+
+ BlockStack.push_back(Location(Pos,id,NumWords));
break;
}
@@ -91,10 +106,10 @@
}
void Deserializer::ReadRecord() {
-
+
while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) {
assert (!BlockStack.empty());
- Stream.EnterSubBlock(BlockStack.back().second);
+ Stream.EnterSubBlock(BlockStack.back().BlockID);
AbbrevNo = 0;
}
@@ -109,23 +124,116 @@
void Deserializer::SkipBlock() {
assert (!inRecord());
- assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+
+ if (AtEnd())
+ return;
+
+ AdvanceStream();
+
+ assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+ BlockStack.pop_back();
Stream.SkipBlock();
+
AbbrevNo = 0;
+ AdvanceStream();
+}
+
+bool Deserializer::SkipToBlock(unsigned BlockID) {
+ assert (!inRecord());
+
+ AdvanceStream();
+ assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+
+ unsigned BlockLevel = BlockStack.size();
+
+ while (!AtEnd() &&
+ BlockLevel == BlockStack.size() &&
+ getCurrentBlockID() != BlockID)
+ SkipBlock();
+
+ return !(AtEnd() || BlockLevel != BlockStack.size());
}
Deserializer::Location Deserializer::getCurrentBlockLocation() {
if (!inRecord())
AdvanceStream();
- return BlockStack.back().first;
+ return BlockStack.back();
+}
+
+bool Deserializer::JumpTo(const Location& Loc) {
+
+ assert (!inRecord());
+
+// AdvanceStream();
+
+// assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+ assert (!BlockStack.empty());
+
+ uint64_t LastBPos = StreamStart.BitNo;
+
+ while (!BlockStack.empty()) {
+
+ LastBPos = BlockStack.back().BitNo;
+
+ // Determine of the current block contains the location of the block
+ // we are looking for.
+ if (BlockStack.back().contains(Loc)) {
+ // We found the enclosing block. We must first POP it off to
+ // destroy any accumulated context within the block scope. We then
+ // jump to the position of the block and enter it.
+ Stream.JumpToBit(LastBPos);
+ BlockStack.pop_back();
+ Stream.PopBlockScope();
+
+ AbbrevNo = 0;
+ AdvanceStream();
+ assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+
+ Stream.EnterSubBlock(BlockStack.back().BlockID);
+ break;
+ }
+
+ // This block does not contain the block we are looking for. Pop it.
+ BlockStack.pop_back();
+ Stream.PopBlockScope();
+ }
+
+ // Check if we have popped our way to the outermost scope. If so,
+ // we need to adjust our position.
+ if (BlockStack.empty()) {
+ Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart.BitNo : LastBPos);
+ AbbrevNo = 0;
+ AdvanceStream();
+ }
+
+ assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+ assert (!BlockStack.empty());
+
+ while (!AtEnd() && BlockStack.back() != Loc) {
+ if (BlockStack.back().contains(Loc)) {
+ Stream.EnterSubBlock(BlockStack.back().BlockID);
+ AbbrevNo = 0;
+ AdvanceStream();
+ continue;
+ }
+ else
+ SkipBlock();
+ }
+
+ if (AtEnd())
+ return false;
+
+ assert (BlockStack.back() == Loc);
+
+ return true;
}
unsigned Deserializer::getCurrentBlockID() {
if (!inRecord())
AdvanceStream();
- return BlockStack.back().second;
+ return BlockStack.back().BlockID;
}
unsigned Deserializer::getRecordCode() {
@@ -142,9 +250,9 @@
if (!inRecord())
AdvanceStream();
- for (llvm::SmallVector<std::pair<Location,unsigned>,5>::reverse_iterator
+ for (llvm::SmallVector<Location,8>::reverse_iterator
I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I)
- if (I->first == BlockLoc)
+ if (*I == BlockLoc)
return false;
return true;
More information about the llvm-commits
mailing list