From ae7dd8004eb286039ee1eb1a35ddb1ff4eafe460 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 7 Apr 2009 02:56:46 +0000 Subject: [PATCH] Add an API for the bitstream reader to read blobs and return them by reference, instead of packing each byte into a smallvector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68486 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/BitstreamReader.h | 21 +++++++++--- tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 41 +++++++++++------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index fe51ade4cb3..d64c0dc2ac6 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -371,7 +371,8 @@ public: return CurAbbrevs[AbbrevNo]; } - unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl &Vals) { + unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl &Vals, + const char **BlobStart = 0, unsigned *BlobLen = 0) { if (AbbrevID == bitc::UNABBREV_RECORD) { unsigned Code = ReadVBR(6); unsigned NumElts = ReadVBR(6); @@ -413,9 +414,15 @@ public: break; } - // Otherwise, read the number of bytes. - for (; NumElts; ++NextChar, --NumElts) - Vals.push_back(*NextChar); + // Otherwise, read the number of bytes. If we can return a reference to + // the data, do so to avoid copying it. + if (BlobStart) { + *BlobStart = (const char*)NextChar; + *BlobLen = NumElts; + } else { + for (; NumElts; ++NextChar, --NumElts) + Vals.push_back(*NextChar); + } // Skip over tail padding. NextChar = NewEnd; } else { @@ -428,6 +435,12 @@ public: return Code; } + unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl &Vals, + const char *&BlobStart, unsigned &BlobLen) { + return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen); + } + + //===--------------------------------------------------------------------===// // Abbrev Processing //===--------------------------------------------------------------------===// diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index 2953e08afa5..4832a4c0b21 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -342,32 +342,14 @@ static bool ParseBlock(BitstreamReader &Stream, unsigned IndentLevel) { break; default: Record.clear(); - bool HasBlob = false; ++BlockStats.NumRecords; - if (AbbrevID != bitc::UNABBREV_RECORD) { + if (AbbrevID != bitc::UNABBREV_RECORD) ++BlockStats.NumAbbreviatedRecords; - const BitCodeAbbrev *Abbv = Stream.getAbbrev(AbbrevID); - if (Abbv->getNumOperandInfos() != 0) { - const BitCodeAbbrevOp &LastOp = - Abbv->getOperandInfo(Abbv->getNumOperandInfos()-1); - // If the last operand is a blob, then this record has blob data. - if (LastOp.isEncoding() && - LastOp.getEncoding() == BitCodeAbbrevOp::Blob) - HasBlob = true; - } - } - unsigned Code; const char *BlobStart = 0; unsigned BlobLen = 0; - if (!HasBlob) - Code = Stream.ReadRecord(AbbrevID, Record); - else { - Code = Stream.ReadRecord(AbbrevID, Record); - BlobStart = BlobStart; - BlobLen = BlobLen; - } + unsigned Code = Stream.ReadRecord(AbbrevID, Record, BlobStart, BlobLen); // Increment the # occurrences of this code. if (BlockStats.CodeFreq.size() <= Code) @@ -388,7 +370,24 @@ static bool ParseBlock(BitstreamReader &Stream, unsigned IndentLevel) { for (unsigned i = 0, e = Record.size(); i != e; ++i) std::cerr << " op" << i << "=" << (int64_t)Record[i]; - std::cerr << "/>\n"; + std::cerr << "/>"; + + if (BlobStart) { + std::cerr << " blob data = "; + bool BlobIsPrintable = true; + for (unsigned i = 0; i != BlobLen; ++i) + if (!isprint(BlobStart[i])) { + BlobIsPrintable = false; + break; + } + + if (BlobIsPrintable) + std::cerr << "'" << std::string(BlobStart, BlobStart+BlobLen) <<"'"; + else + std::cerr << "unprintable, " << BlobLen << " bytes."; + } + + std::cerr << "\n"; } break; -- 2.34.1