summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h21
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp41
2 files changed, 37 insertions, 25 deletions
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index fe51ade4cb..d64c0dc2ac 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<uint64_t> &Vals) {
+ unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &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<uint64_t> &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 2953e08afa..4832a4c0b2 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;