[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