[llvm] r216826 - Teach llvm-bcanalyzer to use one stream's BLOCKINFO to read another stream.
Rafael EspĂndola
rafael.espindola at gmail.com
Tue Sep 2 07:09:06 PDT 2014
what produces these files?
On 30 August 2014 13:07, Jordan Rose <jordan_rose at apple.com> wrote:
> Author: jrose
> Date: Sat Aug 30 12:07:55 2014
> New Revision: 216826
>
> URL: http://llvm.org/viewvc/llvm-project?rev=216826&view=rev
> Log:
> 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.
>
> Added:
> llvm/trunk/test/Other/Inputs/block-info-only.bc (with props)
> llvm/trunk/test/Other/Inputs/has-block-info.bc
> llvm/trunk/test/Other/Inputs/no-block-info.bc (with props)
> llvm/trunk/test/Other/bcanalyzer-block-info.txt
> Modified:
> llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
> llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll
> llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
>
> Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=216826&r1=216825&r2=216826&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original)
> +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Sat Aug 30 12:07:55 2014
> @@ -58,15 +58,27 @@ public:
> BitstreamReader() : IgnoreBlockInfoNames(true) {
> }
>
> - BitstreamReader(const unsigned char *Start, const unsigned char *End) {
> - IgnoreBlockInfoNames = true;
> + BitstreamReader(const unsigned char *Start, const unsigned char *End)
> + : IgnoreBlockInfoNames(true) {
> init(Start, End);
> }
>
> - BitstreamReader(StreamableMemoryObject *bytes) {
> + BitstreamReader(StreamableMemoryObject *bytes) : IgnoreBlockInfoNames(true) {
> BitcodeBytes.reset(bytes);
> }
>
> + BitstreamReader(BitstreamReader &&Other) {
> + *this = std::move(Other);
> + }
> +
> + BitstreamReader &operator=(BitstreamReader &&Other) {
> + BitcodeBytes = std::move(Other.BitcodeBytes);
> + // Explicitly swap block info, so that nothing gets destroyed twice.
> + std::swap(BlockInfoRecords, Other.BlockInfoRecords);
> + IgnoreBlockInfoNames = Other.IgnoreBlockInfoNames;
> + return *this;
> + }
> +
> void init(const unsigned char *Start, const unsigned char *End) {
> assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
> BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
> @@ -123,6 +135,15 @@ public:
> BlockInfoRecords.back().BlockID = BlockID;
> return BlockInfoRecords.back();
> }
> +
> + /// Takes block info from the other bitstream reader.
> + ///
> + /// This is a "take" operation because BlockInfo records are non-trivial, and
> + /// indeed rather expensive.
> + void takeBlockInfo(BitstreamReader &&Other) {
> + assert(!hasBlockInfoRecords());
> + BlockInfoRecords = std::move(Other.BlockInfoRecords);
> + }
> };
>
>
>
> Modified: llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll?rev=216826&r1=216825&r2=216826&view=diff
> ==============================================================================
> --- llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll (original)
> +++ llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll Sat Aug 30 12:07:55 2014
> @@ -48,3 +48,5 @@ entry:
> %2 = icmp eq i32 %1, %a
> ret i1 %2
> }
> +
> +; CHECK: Stream type: LLVM IR
>
> Added: llvm/trunk/test/Other/Inputs/block-info-only.bc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/Inputs/block-info-only.bc?rev=216826&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/Other/Inputs/block-info-only.bc (added) and llvm/trunk/test/Other/Inputs/block-info-only.bc Sat Aug 30 12:07:55 2014 differ
>
> Propchange: llvm/trunk/test/Other/Inputs/block-info-only.bc
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Added: llvm/trunk/test/Other/Inputs/has-block-info.bc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/Inputs/has-block-info.bc?rev=216826&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/Other/Inputs/has-block-info.bc (added) and llvm/trunk/test/Other/Inputs/has-block-info.bc Sat Aug 30 12:07:55 2014 differ
>
> Added: llvm/trunk/test/Other/Inputs/no-block-info.bc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/Inputs/no-block-info.bc?rev=216826&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/Other/Inputs/no-block-info.bc (added) and llvm/trunk/test/Other/Inputs/no-block-info.bc Sat Aug 30 12:07:55 2014 differ
>
> Propchange: llvm/trunk/test/Other/Inputs/no-block-info.bc
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Added: llvm/trunk/test/Other/bcanalyzer-block-info.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/bcanalyzer-block-info.txt?rev=216826&view=auto
> ==============================================================================
> --- llvm/trunk/test/Other/bcanalyzer-block-info.txt (added)
> +++ llvm/trunk/test/Other/bcanalyzer-block-info.txt Sat Aug 30 12:07:55 2014
> @@ -0,0 +1,32 @@
> +RUN: llvm-bcanalyzer -dump %S/Inputs/has-block-info.bc | FileCheck -check-prefix=CHECK -check-prefix=DATA %s
> +RUN: llvm-bcanalyzer -dump %S/Inputs/no-block-info.bc | FileCheck -check-prefix=UNKNOWN -check-prefix=DATA %s
> +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
> +
> + CHECK: <ABC
> +UNKNOWN: <UnknownBlock8
> + DATA: NumWords=4 BlockCodeSize=2>
> + CHECK: <AAA
> +UNKNOWN: <UnknownCode0
> + DATA: op0=42 op1=43 op2=44/>
> + CHECK: <BBB
> +UNKNOWN: <UnknownCode1
> + DATA: op0=42/>
> + CHECK: <AAA
> +UNKNOWN: <UnknownCode0
> + DATA: op0=42/>
> + CHECK: </ABC>
> +UNKNOWN: </UnknownBlock8>
> + CHECK: <XYZ
> +UNKNOWN: <UnknownBlock9
> + DATA: NumWords=3 BlockCodeSize=3>
> + CHECK: <XXX
> +UNKNOWN: <UnknownCode0
> + DATA: abbrevid=4 op0=50 op1=4/>
> + CHECK: <YYY
> +UNKNOWN: <UnknownCode1
> + DATA: op0=42/>
> + CHECK: <XXX
> +UNKNOWN: <UnknownCode0
> + DATA: abbrevid=4 op0=50 op1=5/>
> + CHECK: </XYZ>
> +UNKNOWN: </UnknownBlock9>
>
> Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=216826&r1=216825&r2=216826&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
> +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Sat Aug 30 12:07:55 2014
> @@ -31,6 +31,7 @@
> #include "llvm/Bitcode/LLVMBitCodes.h"
> #include "llvm/Bitcode/ReaderWriter.h"
> #include "llvm/IR/Verifier.h"
> +#include "llvm/ADT/Optional.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/Format.h"
> #include "llvm/Support/ManagedStatic.h"
> @@ -61,6 +62,10 @@ NonSymbolic("non-symbolic",
> cl::desc("Emit numeric info in dump even if"
> " symbolic info is available"));
>
> +static cl::opt<std::string>
> + BlockInfoFilename("block-info",
> + cl::desc("Use the BLOCK_INFO from the given file"));
> +
> namespace {
>
> /// CurStreamTypeType - A type for CurStreamType
> @@ -71,15 +76,11 @@ enum CurStreamTypeType {
>
> }
>
> -/// CurStreamType - If we can sniff the flavor of this stream, we can produce
> -/// better dump info.
> -static CurStreamTypeType CurStreamType;
> -
> -
> /// GetBlockName - Return a symbolic block name if known, otherwise return
> /// null.
> static const char *GetBlockName(unsigned BlockID,
> - const BitstreamReader &StreamFile) {
> + const BitstreamReader &StreamFile,
> + CurStreamTypeType CurStreamType) {
> // Standard blocks for all bitcode files.
> if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
> if (BlockID == bitc::BLOCKINFO_BLOCK_ID)
> @@ -115,7 +116,8 @@ static const char *GetBlockName(unsigned
> /// GetCodeName - Return a symbolic code name if known, otherwise return
> /// null.
> static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
> - const BitstreamReader &StreamFile) {
> + const BitstreamReader &StreamFile,
> + CurStreamTypeType CurStreamType) {
> // Standard blocks for all bitcode files.
> if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
> if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
> @@ -316,14 +318,14 @@ static std::map<unsigned, PerBlockIDStat
>
> /// Error - All bitcode analysis errors go through this function, making this a
> /// good place to breakpoint if debugging.
> -static bool Error(const std::string &Err) {
> +static bool Error(const Twine &Err) {
> errs() << Err << "\n";
> return true;
> }
>
> /// ParseBlock - Read a block, updating statistics, etc.
> static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
> - unsigned IndentLevel) {
> + unsigned IndentLevel, CurStreamTypeType CurStreamType) {
> std::string Indent(IndentLevel*2, ' ');
> uint64_t BlockBitStart = Stream.GetCurrentBitNo();
>
> @@ -349,7 +351,8 @@ static bool ParseBlock(BitstreamCursor &
> const char *BlockName = nullptr;
> if (Dump) {
> outs() << Indent << "<";
> - if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader())))
> + if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader(),
> + CurStreamType)))
> outs() << BlockName;
> else
> outs() << "UnknownBlock" << BlockID;
> @@ -391,7 +394,7 @@ static bool ParseBlock(BitstreamCursor &
>
> case BitstreamEntry::SubBlock: {
> uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
> - if (ParseBlock(Stream, Entry.ID, IndentLevel+1))
> + if (ParseBlock(Stream, Entry.ID, IndentLevel+1, CurStreamType))
> return true;
> ++BlockStats.NumSubBlocks;
> uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
> @@ -432,12 +435,14 @@ static bool ParseBlock(BitstreamCursor &
> if (Dump) {
> outs() << Indent << " <";
> if (const char *CodeName =
> - GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
> + GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
> + CurStreamType))
> outs() << CodeName;
> else
> outs() << "UnknownCode" << Code;
> if (NonSymbolic &&
> - GetCodeName(Code, BlockID, *Stream.getBitStreamReader()))
> + GetCodeName(Code, BlockID, *Stream.getBitStreamReader(),
> + CurStreamType))
> outs() << " codeid=" << Code;
> if (Entry.ID != bitc::UNABBREV_RECORD)
> outs() << " abbrevid=" << Entry.ID;
> @@ -475,21 +480,23 @@ static void PrintSize(uint64_t Bits) {
> (double)Bits/8, (unsigned long)(Bits/32));
> }
>
> -
> -/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
> -static int AnalyzeBitcode() {
> +static bool openBitcodeFile(StringRef Path,
> + std::unique_ptr<MemoryBuffer> &MemBuf,
> + BitstreamReader &StreamFile,
> + BitstreamCursor &Stream,
> + CurStreamTypeType &CurStreamType) {
> // Read the input file.
> ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
> - MemoryBuffer::getFileOrSTDIN(InputFilename);
> + MemoryBuffer::getFileOrSTDIN(Path);
> if (std::error_code EC = MemBufOrErr.getError())
> - return Error("Error reading '" + InputFilename + "': " + EC.message());
> - MemoryBuffer &MemBuf = *MemBufOrErr.get();
> + return Error(Twine("Error reading '") + Path + "': " + EC.message());
> + MemBuf = std::move(MemBufOrErr.get());
>
> - if (MemBuf.getBufferSize() & 3)
> + if (MemBuf->getBufferSize() & 3)
> return Error("Bitcode stream should be a multiple of 4 bytes in length");
>
> - const unsigned char *BufPtr = (const unsigned char *)MemBuf.getBufferStart();
> - const unsigned char *EndBufPtr = BufPtr+MemBuf.getBufferSize();
> + const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
> + const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
>
> // If we have a wrapper header, parse it and ignore the non-bc file contents.
> // The magic number is 0x0B17C0DE stored in little endian.
> @@ -497,8 +504,8 @@ static int AnalyzeBitcode() {
> if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true))
> return Error("Invalid bitcode wrapper header");
>
> - BitstreamReader StreamFile(BufPtr, EndBufPtr);
> - BitstreamCursor Stream(StreamFile);
> + StreamFile = BitstreamReader(BufPtr, EndBufPtr);
> + Stream = BitstreamCursor(StreamFile);
> StreamFile.CollectBlockInfoNames();
>
> // Read the stream signature.
> @@ -517,6 +524,48 @@ static int AnalyzeBitcode() {
> Signature[4] == 0xE && Signature[5] == 0xD)
> CurStreamType = LLVMIRBitstream;
>
> + return false;
> +}
> +
> +/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
> +static int AnalyzeBitcode() {
> + std::unique_ptr<MemoryBuffer> StreamBuffer;
> + BitstreamReader StreamFile;
> + BitstreamCursor Stream;
> + CurStreamTypeType CurStreamType;
> + if (openBitcodeFile(InputFilename, StreamBuffer, StreamFile, Stream,
> + CurStreamType))
> + return true;
> +
> + // Read block info from BlockInfoFilename, if specified.
> + // The block info must be a top-level block.
> + if (!BlockInfoFilename.empty()) {
> + std::unique_ptr<MemoryBuffer> BlockInfoBuffer;
> + BitstreamReader BlockInfoFile;
> + BitstreamCursor BlockInfoCursor;
> + CurStreamTypeType BlockInfoStreamType;
> + if (openBitcodeFile(BlockInfoFilename, BlockInfoBuffer, BlockInfoFile,
> + BlockInfoCursor, BlockInfoStreamType))
> + return true;
> +
> + while (!BlockInfoCursor.AtEndOfStream()) {
> + unsigned Code = BlockInfoCursor.ReadCode();
> + if (Code != bitc::ENTER_SUBBLOCK)
> + return Error("Invalid record at top-level in block info file");
> +
> + unsigned BlockID = BlockInfoCursor.ReadSubBlockID();
> + if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
> + if (BlockInfoCursor.ReadBlockInfoBlock())
> + return Error("Malformed BlockInfoBlock in block info file");
> + break;
> + }
> +
> + BlockInfoCursor.SkipBlock();
> + }
> +
> + StreamFile.takeBlockInfo(std::move(BlockInfoFile));
> + }
> +
> unsigned NumTopBlocks = 0;
>
> // Parse the top-level structure. We only allow blocks at the top-level.
> @@ -527,14 +576,14 @@ static int AnalyzeBitcode() {
>
> unsigned BlockID = Stream.ReadSubBlockID();
>
> - if (ParseBlock(Stream, BlockID, 0))
> + if (ParseBlock(Stream, BlockID, 0, CurStreamType))
> return true;
> ++NumTopBlocks;
> }
>
> if (Dump) outs() << "\n\n";
>
> - uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
> + uint64_t BufferSizeBits = StreamFile.getBitcodeBytes().getExtent() * CHAR_BIT;
> // Print a summary of the read file.
> outs() << "Summary of " << InputFilename << ":\n";
> outs() << " Total size: ";
> @@ -553,7 +602,8 @@ static int AnalyzeBitcode() {
> for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
> E = BlockIDStats.end(); I != E; ++I) {
> outs() << " Block ID #" << I->first;
> - if (const char *BlockName = GetBlockName(I->first, StreamFile))
> + if (const char *BlockName = GetBlockName(I->first, StreamFile,
> + CurStreamType))
> outs() << " (" << BlockName << ")";
> outs() << ":\n";
>
> @@ -611,7 +661,8 @@ static int AnalyzeBitcode() {
> outs() << " ";
>
> if (const char *CodeName =
> - GetCodeName(FreqPairs[i].second, I->first, StreamFile))
> + GetCodeName(FreqPairs[i].second, I->first, StreamFile,
> + CurStreamType))
> outs() << CodeName << "\n";
> else
> outs() << "UnknownCode" << FreqPairs[i].second << "\n";
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list