summaryrefslogtreecommitdiff
path: root/tools/llvm-bcanalyzer
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-04-29 20:00:02 +0000
committerChris Lattner <sabre@nondot.org>2007-04-29 20:00:02 +0000
commit4238d474b4f8443371a52a4f1fca278170ff2c0e (patch)
tree643cc842139ece0089d2ed6e06ec52da6e023513 /tools/llvm-bcanalyzer
parenta2d0ad4fe26df1e32610ccd99d084a98daeb5c67 (diff)
downloadllvm-4238d474b4f8443371a52a4f1fca278170ff2c0e.tar.gz
llvm-4238d474b4f8443371a52a4f1fca278170ff2c0e.tar.bz2
llvm-4238d474b4f8443371a52a4f1fca278170ff2c0e.tar.xz
add some simple per-block statistics
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36576 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-bcanalyzer')
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp112
1 files changed, 104 insertions, 8 deletions
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 04d8dc4110..3f6f3d86ce 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -32,6 +32,7 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bytecode/Analyzer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compressor.h"
@@ -65,6 +66,50 @@ static enum {
LLVMIRBitstream
} CurStreamType;
+
+/// GetBlockName - Return a symbolic block name if known, otherwise return
+/// empty.
+static const char *GetBlockName(unsigned BlockID) {
+ if (CurStreamType != LLVMIRBitstream) return "";
+
+ switch (BlockID) {
+ default: return "<unknown LLVM IR block ID>";
+ case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
+ case bitc::TYPE_BLOCK_ID: return "TYPE_BLOCK";
+ case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK";
+ case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK";
+ case bitc::TYPE_SYMTAB_BLOCK_ID: return "TYPE_SYMTAB";
+ case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
+ }
+}
+
+
+struct PerBlockIDStats {
+ /// NumInstances - This the number of times this block ID has been seen.
+ unsigned NumInstances;
+
+ /// NumBits - The total size in bits of all of these blocks.
+ uint64_t NumBits;
+
+ /// NumSubBlocks - The total number of blocks these blocks contain.
+ unsigned NumSubBlocks;
+
+ /// NumAbbrevs - The total number of abbreviations.
+ unsigned NumAbbrevs;
+
+ /// NumRecords - The total number of records these blocks contain, and the
+ /// number that are abbreviated.
+ unsigned NumRecords, NumAbbreviatedRecords;
+
+ PerBlockIDStats()
+ : NumInstances(0), NumBits(0),
+ NumSubBlocks(0), NumAbbrevs(0), NumRecords(0), NumAbbreviatedRecords(0) {}
+};
+
+static std::map<unsigned, PerBlockIDStats> BlockIDStats;
+
+
+
/// 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) {
@@ -74,10 +119,14 @@ static bool Error(const std::string &Err) {
/// ParseBlock - Read a block, updating statistics, etc.
static bool ParseBlock(BitstreamReader &Stream) {
+ uint64_t BlockBitStart = Stream.GetCurrentBitNo();
+
unsigned BlockID = Stream.ReadSubBlockID();
- // TODO: Compute per-block-id stats.
- BlockID = BlockID;
+ // Get the statistics for this BlockID.
+ PerBlockIDStats &BlockStats = BlockIDStats[BlockID];
+
+ BlockStats.NumInstances++;
if (Stream.EnterSubBlock())
return Error("Malformed block record");
@@ -92,18 +141,27 @@ static bool ParseBlock(BitstreamReader &Stream) {
// Read the code for this record.
unsigned AbbrevID = Stream.ReadCode();
switch (AbbrevID) {
- case bitc::END_BLOCK:
+ case bitc::END_BLOCK: {
if (Stream.ReadBlockEnd())
return Error("Error at end of block");
+ uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
+ BlockStats.NumBits += BlockBitEnd-BlockBitStart;
return false;
+ }
case bitc::ENTER_SUBBLOCK:
if (ParseBlock(Stream))
return true;
+ ++BlockStats.NumSubBlocks;
break;
case bitc::DEFINE_ABBREV:
Stream.ReadAbbrevRecord();
+ ++BlockStats.NumAbbrevs;
break;
default:
+ ++BlockStats.NumRecords;
+ if (AbbrevID != bitc::UNABBREV_RECORD)
+ ++BlockStats.NumAbbreviatedRecords;
+
Record.clear();
unsigned Code = Stream.ReadRecord(AbbrevID, Record);
// TODO: Compute per-blockid/code stats.
@@ -113,6 +171,11 @@ static bool ParseBlock(BitstreamReader &Stream) {
}
}
+static void PrintSize(double Bits) {
+ std::cerr << Bits << "b/" << Bits/8 << "B/" << Bits/32 << "W";
+}
+
+
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
// Read the input file.
@@ -148,6 +211,8 @@ static int AnalyzeBitcode() {
Signature[4] == 0xE && Signature[5] == 0xD)
CurStreamType = LLVMIRBitstream;
+ unsigned NumTopBlocks = 0;
+
// Parse the top-level structure. We only allow blocks at the top-level.
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
@@ -156,20 +221,51 @@ static int AnalyzeBitcode() {
if (ParseBlock(Stream))
return true;
+ ++NumTopBlocks;
}
// Print a summary of the read file.
-
std::cerr << "Summary of " << InputFilename << ":\n";
- std::cerr << " Stream type: ";
+ std::cerr << " Total size: ";
+ PrintSize(Buffer->getBufferSize()*8);
+ std::cerr << "\n";
+ std::cerr << " Stream type: ";
switch (CurStreamType) {
default: assert(0 && "Unknown bitstream type");
case UnknownBitstream: std::cerr << "unknown\n"; break;
case LLVMIRBitstream: std::cerr << "LLVM IR\n"; break;
}
-
- // TODO: Stats!
-
+ std::cerr << " # Toplevel Blocks: " << NumTopBlocks << "\n";
+ std::cerr << "\n";
+
+ // Emit per-block stats.
+ std::cerr << "Per-block Summary:\n";
+ for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
+ E = BlockIDStats.end(); I != E; ++I) {
+ std::cerr << " Block ID #" << I->first;
+ const char *BlockName = GetBlockName(I->first);
+ if (BlockName[0])
+ std::cerr << " (" << BlockName << ")";
+ std::cerr << ":\n";
+
+ const PerBlockIDStats &Stats = I->second;
+ std::cerr << " Num Instances: " << Stats.NumInstances << "\n";
+ std::cerr << " Total Size: ";
+ PrintSize(Stats.NumBits);
+ std::cerr << "\n";
+ std::cerr << " Average Size: ";
+ PrintSize(Stats.NumBits/(double)Stats.NumInstances);
+ std::cerr << "\n";
+ std::cerr << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
+ << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
+ std::cerr << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
+ << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
+ std::cerr << " Tot/Avg Records: " << Stats.NumRecords << "/"
+ << Stats.NumRecords/(double)Stats.NumInstances << "\n";
+ std::cerr << " % Abbrev Recs: " << (Stats.NumAbbreviatedRecords/
+ (double)Stats.NumRecords)*100 << "\n";
+ std::cerr << "\n";
+ }
return 0;
}