[llvm] r216826 - Teach llvm-bcanalyzer to use one stream's BLOCKINFO to read another stream.

Jordan Rose jordan_rose at apple.com
Tue Sep 2 08:32:57 PDT 2014


Parts of Swift, but it seemed like something generally useful. If you're not using DEFINE_ABBREV in the BLOCKINFO blocks, they're effectively just debug info. With this patch you can get the names for a particular archive as long as you have a reference.

Jordan


On Sep 2, 2014, at 7:09 , Rafael EspĂ­ndola <rafael.espindola at gmail.com> wrote:

> 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