llvm.org GIT mirror llvm / d421075
Teach llvm-bcanalyzer to use one stream's BLOCKINFO to read another stream. This allows streams that only use BLOCKINFO for debugging purposes to omit the block entirely. As long as another stream is available with the correct BLOCKINFO, the first stream can still be analyzed and dumped. As part of this commit, BitstreamReader gets a move constructor and move assignment operator, as well as a takeBlockInfo method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216826 91177308-0d34-0410-b5e6-96231b3b80d8 Jordan Rose 6 years ago
7 changed file(s) with 138 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
5757 BitstreamReader() : IgnoreBlockInfoNames(true) {
5858 }
5959
60 BitstreamReader(const unsigned char *Start, const unsigned char *End) {
61 IgnoreBlockInfoNames = true;
60 BitstreamReader(const unsigned char *Start, const unsigned char *End)
61 : IgnoreBlockInfoNames(true) {
6262 init(Start, End);
6363 }
6464
65 BitstreamReader(StreamableMemoryObject *bytes) {
65 BitstreamReader(StreamableMemoryObject *bytes) : IgnoreBlockInfoNames(true) {
6666 BitcodeBytes.reset(bytes);
67 }
68
69 BitstreamReader(BitstreamReader &&Other) {
70 *this = std::move(Other);
71 }
72
73 BitstreamReader &operator=(BitstreamReader &&Other) {
74 BitcodeBytes = std::move(Other.BitcodeBytes);
75 // Explicitly swap block info, so that nothing gets destroyed twice.
76 std::swap(BlockInfoRecords, Other.BlockInfoRecords);
77 IgnoreBlockInfoNames = Other.IgnoreBlockInfoNames;
78 return *this;
6779 }
6880
6981 void init(const unsigned char *Start, const unsigned char *End) {
121133 BlockInfoRecords.push_back(BlockInfo());
122134 BlockInfoRecords.back().BlockID = BlockID;
123135 return BlockInfoRecords.back();
136 }
137
138 /// Takes block info from the other bitstream reader.
139 ///
140 /// This is a "take" operation because BlockInfo records are non-trivial, and
141 /// indeed rather expensive.
142 void takeBlockInfo(BitstreamReader &&Other) {
143 assert(!hasBlockInfoRecords());
144 BlockInfoRecords = std::move(Other.BlockInfoRecords);
124145 }
125146 };
126147
4747 %2 = icmp eq i32 %1, %a
4848 ret i1 %2
4949 }
50
51 ; CHECK: Stream type: LLVM IR
0 RUN: llvm-bcanalyzer -dump %S/Inputs/has-block-info.bc | FileCheck -check-prefix=CHECK -check-prefix=DATA %s
1 RUN: llvm-bcanalyzer -dump %S/Inputs/no-block-info.bc | FileCheck -check-prefix=UNKNOWN -check-prefix=DATA %s
2 RUN: llvm-bcanalyzer -dump %S/Inputs/no-block-info.bc -block-info %S/Inputs/block-info-only.bc | FileCheck -check-prefix=CHECK -check-prefix=DATA %s
3
4 CHECK:
5 UNKNOWN:
6 DATA: NumWords=4 BlockCodeSize=2>
7 CHECK:
8 UNKNOWN:
9 DATA: op0=42 op1=43 op2=44/>
10 CHECK:
11 UNKNOWN:
12 DATA: op0=42/>
13 CHECK:
14 UNKNOWN:
15 DATA: op0=42/>
16 CHECK:
17 UNKNOWN:
18 CHECK:
19 UNKNOWN:
20 DATA: NumWords=3 BlockCodeSize=3>
21 CHECK:
22 UNKNOWN:
23 DATA: abbrevid=4 op0=50 op1=4/>
24 CHECK:
25 UNKNOWN:
26 DATA: op0=42/>
27 CHECK:
28 UNKNOWN:
29 DATA: abbrevid=4 op0=50 op1=5/>
30 CHECK:
31 UNKNOWN:
3030 #include "llvm/Bitcode/LLVMBitCodes.h"
3131 #include "llvm/Bitcode/ReaderWriter.h"
3232 #include "llvm/IR/Verifier.h"
33 #include "llvm/ADT/Optional.h"
3334 #include "llvm/Support/CommandLine.h"
3435 #include "llvm/Support/Format.h"
3536 #include "llvm/Support/ManagedStatic.h"
6061 cl::desc("Emit numeric info in dump even if"
6162 " symbolic info is available"));
6263
64 static cl::opt
65 BlockInfoFilename("block-info",
66 cl::desc("Use the BLOCK_INFO from the given file"));
67
6368 namespace {
6469
6570 /// CurStreamTypeType - A type for CurStreamType
7075
7176 }
7277
73 /// CurStreamType - If we can sniff the flavor of this stream, we can produce
74 /// better dump info.
75 static CurStreamTypeType CurStreamType;
76
77
7878 /// GetBlockName - Return a symbolic block name if known, otherwise return
7979 /// null.
8080 static const char *GetBlockName(unsigned BlockID,
81 const BitstreamReader &StreamFile) {
81 const BitstreamReader &StreamFile,
82 CurStreamTypeType CurStreamType) {
8283 // Standard blocks for all bitcode files.
8384 if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
8485 if (BlockID == bitc::BLOCKINFO_BLOCK_ID)
114115 /// GetCodeName - Return a symbolic code name if known, otherwise return
115116 /// null.
116117 static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
117 const BitstreamReader &StreamFile) {
118 const BitstreamReader &StreamFile,
119 CurStreamTypeType CurStreamType) {
118120 // Standard blocks for all bitcode files.
119121 if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
120122 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
315317
316318 /// Error - All bitcode analysis errors go through this function, making this a
317319 /// good place to breakpoint if debugging.
318 static bool Error(const std::string &Err) {
320 static bool Error(const Twine &Err) {
319321 errs() << Err << "\n";
320322 return true;
321323 }
322324
323325 /// ParseBlock - Read a block, updating statistics, etc.
324326 static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
325 unsigned IndentLevel) {
327 unsigned IndentLevel, CurStreamTypeType CurStreamType) {
326328 std::string Indent(IndentLevel*2, ' ');
327329 uint64_t BlockBitStart = Stream.GetCurrentBitNo();
328330
348350 const char *BlockName = nullptr;
349351 if (Dump) {
350352 outs() << Indent << "<";
351 if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader())))
353 if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader(),
354 CurStreamType)))
352355 outs() << BlockName;
353356 else
354357 outs() << "UnknownBlock" << BlockID;
390393
391394 case BitstreamEntry::SubBlock: {
392395 uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
393 if (ParseBlock(Stream, Entry.ID, IndentLevel+1))
396 if (ParseBlock(Stream, Entry.ID, IndentLevel+1, CurStreamType))
394397 return true;
395398 ++BlockStats.NumSubBlocks;
396399 uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
431434 if (Dump) {
432435 outs() << Indent << " <";
433436 if (const char *CodeName =
434 GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
437 GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
438 CurStreamType))
435439 outs() << CodeName;
436440 else
437441 outs() << "UnknownCode" << Code;
438442 if (NonSymbolic &&
439 GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
443 GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
444 CurStreamType))
440445 outs() << " codeid=" << Code;
441446 if (Entry.ID != bitc::UNABBREV_RECORD)
442447 outs() << " abbrevid=" << Entry.ID;
474479 (double)Bits/8, (unsigned long)(Bits/32));
475480 }
476481
477
478 /// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
479 static int AnalyzeBitcode() {
482 static bool openBitcodeFile(StringRef Path,
483 std::unique_ptr &MemBuf,
484 BitstreamReader &StreamFile,
485 BitstreamCursor &Stream,
486 CurStreamTypeType &CurStreamType) {
480487 // Read the input file.
481488 ErrorOr> MemBufOrErr =
482 MemoryBuffer::getFileOrSTDIN(InputFilename);
489 MemoryBuffer::getFileOrSTDIN(Path);
483490 if (std::error_code EC = MemBufOrErr.getError())
484 return Error("Error reading '" + InputFilename + "': " + EC.message());
485 MemoryBuffer &MemBuf = *MemBufOrErr.get();
486
487 if (MemBuf.getBufferSize() & 3)
491 return Error(Twine("Error reading '") + Path + "': " + EC.message());
492 MemBuf = std::move(MemBufOrErr.get());
493
494 if (MemBuf->getBufferSize() & 3)
488495 return Error("Bitcode stream should be a multiple of 4 bytes in length");
489496
490 const unsigned char *BufPtr = (const unsigned char *)MemBuf.getBufferStart();
491 const unsigned char *EndBufPtr = BufPtr+MemBuf.getBufferSize();
497 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
498 const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
492499
493500 // If we have a wrapper header, parse it and ignore the non-bc file contents.
494501 // The magic number is 0x0B17C0DE stored in little endian.
496503 if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true))
497504 return Error("Invalid bitcode wrapper header");
498505
499 BitstreamReader StreamFile(BufPtr, EndBufPtr);
500 BitstreamCursor Stream(StreamFile);
506 StreamFile = BitstreamReader(BufPtr, EndBufPtr);
507 Stream = BitstreamCursor(StreamFile);
501508 StreamFile.CollectBlockInfoNames();
502509
503510 // Read the stream signature.
516523 Signature[4] == 0xE && Signature[5] == 0xD)
517524 CurStreamType = LLVMIRBitstream;
518525
526 return false;
527 }
528
529 /// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
530 static int AnalyzeBitcode() {
531 std::unique_ptr StreamBuffer;
532 BitstreamReader StreamFile;
533 BitstreamCursor Stream;
534 CurStreamTypeType CurStreamType;
535 if (openBitcodeFile(InputFilename, StreamBuffer, StreamFile, Stream,
536 CurStreamType))
537 return true;
538
539 // Read block info from BlockInfoFilename, if specified.
540 // The block info must be a top-level block.
541 if (!BlockInfoFilename.empty()) {
542 std::unique_ptr BlockInfoBuffer;
543 BitstreamReader BlockInfoFile;
544 BitstreamCursor BlockInfoCursor;
545 CurStreamTypeType BlockInfoStreamType;
546 if (openBitcodeFile(BlockInfoFilename, BlockInfoBuffer, BlockInfoFile,
547 BlockInfoCursor, BlockInfoStreamType))
548 return true;
549
550 while (!BlockInfoCursor.AtEndOfStream()) {
551 unsigned Code = BlockInfoCursor.ReadCode();
552 if (Code != bitc::ENTER_SUBBLOCK)
553 return Error("Invalid record at top-level in block info file");
554
555 unsigned BlockID = BlockInfoCursor.ReadSubBlockID();
556 if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
557 if (BlockInfoCursor.ReadBlockInfoBlock())
558 return Error("Malformed BlockInfoBlock in block info file");
559 break;
560 }
561
562 BlockInfoCursor.SkipBlock();
563 }
564
565 StreamFile.takeBlockInfo(std::move(BlockInfoFile));
566 }
567
519568 unsigned NumTopBlocks = 0;
520569
521570 // Parse the top-level structure. We only allow blocks at the top-level.
526575
527576 unsigned BlockID = Stream.ReadSubBlockID();
528577
529 if (ParseBlock(Stream, BlockID, 0))
578 if (ParseBlock(Stream, BlockID, 0, CurStreamType))
530579 return true;
531580 ++NumTopBlocks;
532581 }
533582
534583 if (Dump) outs() << "\n\n";
535584
536 uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
585 uint64_t BufferSizeBits = StreamFile.getBitcodeBytes().getExtent() * CHAR_BIT;
537586 // Print a summary of the read file.
538587 outs() << "Summary of " << InputFilename << ":\n";
539588 outs() << " Total size: ";
552601 for (std::map::iterator I = BlockIDStats.begin(),
553602 E = BlockIDStats.end(); I != E; ++I) {
554603 outs() << " Block ID #" << I->first;
555 if (const char *BlockName = GetBlockName(I->first, StreamFile))
604 if (const char *BlockName = GetBlockName(I->first, StreamFile,
605 CurStreamType))
556606 outs() << " (" << BlockName << ")";
557607 outs() << ":\n";
558608
610660 outs() << " ";
611661
612662 if (const char *CodeName =
613 GetCodeName(FreqPairs[i].second, I->first, StreamFile))
663 GetCodeName(FreqPairs[i].second, I->first, StreamFile,
664 CurStreamType))
614665 outs() << CodeName << "\n";
615666 else
616667 outs() << "UnknownCode" << FreqPairs[i].second << "\n";