summaryrefslogtreecommitdiffstats
path: root/tools/llvm-bcanalyzer
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-03-27 23:17:54 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-03-27 23:17:54 +0000
commita73e509bf8d4be01f6b78d350a652b634aa31455 (patch)
tree21eae48701c9a21522f7a777b719597562a37d68 /tools/llvm-bcanalyzer
parent15b99e03690cee6cbd2b415ee4033799f753353f (diff)
Reapply ~"Bitcode: Collect all MDString records into a single blob"
Spiritually reapply commit r264409 (reverted in r264410), albeit with a bit of a redesign. Firstly, avoid splitting the big blob into multiple chunks of strings. r264409 imposed an arbitrary limit to avoid a massive allocation on the shared 'Record' SmallVector. The bug with that commit only reproduced when there were more than "chunk-size" strings. A test for this would have been useless long-term, since we're liable to adjust the chunk-size in the future. Thus, eliminate the motivation for chunk-ing by storing the string sizes in the blob. Here's the layout: vbr6: # of strings vbr6: offset-to-blob blob: [vbr6]: string lengths [char]: concatenated strings Secondly, make the output of llvm-bcanalyzer readable. I noticed when debugging r264409 that llvm-bcanalyzer was outputting a massive blob all in one line. Past a small number, the strings were impossible to split in my head, and the lines were way too long. This version adds support in llvm-bcanalyzer for pretty-printing. <STRINGS abbrevid=4 op0=3 op1=9/> num-strings = 3 { 'abc' 'def' 'ghi' } From the original commit: Inspired by Mehdi's similar patch, http://reviews.llvm.org/D18342, this should (a) slightly reduce bitcode size, since there is less record overhead, and (b) greatly improve reading speed, since blobs are super cheap to deserialize. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264551 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-bcanalyzer')
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp57
1 files changed, 55 insertions, 2 deletions
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 32179c168dea..6645045db8fa 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -312,7 +312,8 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::METADATA_BLOCK_ID:
switch(CodeID) {
default:return nullptr;
- STRINGIFY_CODE(METADATA, STRING)
+ STRINGIFY_CODE(METADATA, STRING_OLD)
+ STRINGIFY_CODE(METADATA, STRINGS)
STRINGIFY_CODE(METADATA, NAME)
STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK
STRINGIFY_CODE(METADATA, NODE)
@@ -404,6 +405,57 @@ static bool Error(const Twine &Err) {
return true;
}
+static bool decodeMetadataStringsBlob(BitstreamReader &Reader, StringRef Indent,
+ ArrayRef<uint64_t> Record,
+ StringRef Blob) {
+ if (Blob.empty())
+ return true;
+
+ if (Record.size() != 2)
+ return true;
+
+ unsigned NumStrings = Record[0];
+ unsigned StringsOffset = Record[1];
+ outs() << " num-strings = " << NumStrings << " {\n";
+
+ StringRef Lengths = Blob.slice(0, StringsOffset);
+ SimpleBitstreamCursor R(Reader);
+ R.jumpToPointer(Lengths.begin());
+
+ // Ensure that Blob doesn't get invalidated, even if this is reading from a
+ // StreamingMemoryObject with corrupt data.
+ R.setArtificialByteLimit(R.getCurrentByteNo() + StringsOffset);
+
+ StringRef Strings = Blob.drop_front(StringsOffset);
+ do {
+ if (R.AtEndOfStream())
+ return Error("bad length");
+
+ unsigned Size = R.ReadVBR(6);
+ if (Strings.size() < Size)
+ return Error("truncated chars");
+
+ outs() << Indent << " '";
+ outs().write_escaped(Strings.slice(0, Size), /*hex=*/true);
+ outs() << "'\n";
+ Strings = Strings.drop_front(Size);
+ } while (--NumStrings);
+
+ outs() << Indent << " }";
+ return false;
+}
+
+static bool decodeBlob(unsigned Code, unsigned BlockID, BitstreamReader &Reader,
+ StringRef Indent, ArrayRef<uint64_t> Record,
+ StringRef Blob) {
+ if (BlockID != bitc::METADATA_BLOCK_ID)
+ return true;
+ if (Code != bitc::METADATA_STRINGS)
+ return true;
+
+ return decodeMetadataStringsBlob(Reader, Indent, Record, Blob);
+}
+
/// ParseBlock - Read a block, updating statistics, etc.
static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
unsigned IndentLevel, CurStreamTypeType CurStreamType) {
@@ -557,7 +609,8 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
}
}
- if (Blob.data()) {
+ if (Blob.data() && decodeBlob(Code, BlockID, *Stream.getBitStreamReader(),
+ Indent, Record, Blob)) {
outs() << " blob data = ";
if (ShowBinaryBlobs) {
outs() << "'";