[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