diff options
Diffstat (limited to 'lib/Bytecode/Reader/Analyzer.cpp')
-rw-r--r-- | lib/Bytecode/Reader/Analyzer.cpp | 733 |
1 files changed, 733 insertions, 0 deletions
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp new file mode 100644 index 0000000000..4990761673 --- /dev/null +++ b/lib/Bytecode/Reader/Analyzer.cpp @@ -0,0 +1,733 @@ +//===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AnalyzerHandler class and PrintBytecodeAnalysis +// function which together comprise the basic functionality of the llmv-abcd +// tool. The AnalyzerHandler collects information about the bytecode file into +// the BytecodeAnalysis structure. The PrintBytecodeAnalysis function prints +// out the content of that structure. +// @see include/llvm/Bytecode/Analysis.h +// +//===----------------------------------------------------------------------===// + +#include "Reader.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Bytecode/BytecodeHandler.h" +#include "llvm/Assembly/Writer.h" +#include <iomanip> +#include <sstream> + +using namespace llvm; + +namespace { + +/// @brief Bytecode reading handler for analyzing bytecode. +class AnalyzerHandler : public BytecodeHandler { + BytecodeAnalysis& bca; ///< The structure in which data is recorded + std::ostream* os; ///< A convenience for osing data. + /// @brief Keeps track of current function + BytecodeAnalysis::BytecodeFunctionInfo* currFunc; + Module* M; ///< Keeps track of current module + +/// @name Constructor +/// @{ +public: + /// The only way to construct an AnalyzerHandler. All that is needed is a + /// reference to the BytecodeAnalysis structure where the output will be + /// placed. + AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output) + : bca(TheBca) + , os(output) + , currFunc(0) + { } + +/// @} +/// @name BytecodeHandler Implementations +/// @{ +public: + virtual void handleError(const std::string& str ) { + if (os) + *os << "ERROR: " << str << "\n"; + } + + virtual void handleStart( Module* Mod, unsigned theSize ) { + M = Mod; + if (os) + *os << "Bytecode {\n"; + bca.byteSize = theSize; + bca.ModuleId.clear(); + bca.numBlocks = 0; + bca.numTypes = 0; + bca.numValues = 0; + bca.numFunctions = 0; + bca.numConstants = 0; + bca.numGlobalVars = 0; + bca.numInstructions = 0; + bca.numBasicBlocks = 0; + bca.numOperands = 0; + bca.numCmpctnTables = 0; + bca.numSymTab = 0; + bca.numLibraries = 0; + bca.libSize = 0; + bca.maxTypeSlot = 0; + bca.maxValueSlot = 0; + bca.numAlignment = 0; + bca.fileDensity = 0.0; + bca.globalsDensity = 0.0; + bca.functionDensity = 0.0; + bca.instructionSize = 0; + bca.longInstructions = 0; + bca.vbrCount32 = 0; + bca.vbrCount64 = 0; + bca.vbrCompBytes = 0; + bca.vbrExpdBytes = 0; + bca.FunctionInfo.clear(); + bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse] = 0; + bca.BlockSizes[BytecodeFormat::ModuleBlockID] = theSize; + bca.BlockSizes[BytecodeFormat::FunctionBlockID] = 0; + bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID] = 0; + bca.BlockSizes[BytecodeFormat::SymbolTableBlockID] = 0; + bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID] = 0; + bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID] = 0; + bca.BlockSizes[BytecodeFormat::InstructionListBlockID] = 0; + bca.BlockSizes[BytecodeFormat::CompactionTableBlockID] = 0; + } + + virtual void handleFinish() { + if (os) + *os << "} End Bytecode\n"; + + bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues ); + double globalSize = 0.0; + globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]); + globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]); + globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]); + bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants + + bca.numGlobalVars ); + bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) / + double(bca.numFunctions); + + if ( bca.progressiveVerify ) { + try { + verifyModule(*M, ThrowExceptionAction); + } catch ( std::string& msg ) { + bca.VerifyInfo += "Verify@Finish: " + msg + "\n"; + } + } + } + + virtual void handleModuleBegin(const std::string& id) { + if (os) + *os << " Module " << id << " {\n"; + bca.ModuleId = id; + } + + virtual void handleModuleEnd(const std::string& id) { + if (os) + *os << " } End Module " << id << "\n"; + if ( bca.progressiveVerify ) { + try { + verifyModule(*M, ThrowExceptionAction); + } catch ( std::string& msg ) { + bca.VerifyInfo += "Verify@EndModule: " + msg + "\n"; + } + } + } + + virtual void handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ) { + if (os) + *os << " RevisionNum: " << int(RevisionNum) + << " Endianness: " << Endianness + << " PointerSize: " << PointerSize << "\n"; + bca.version = RevisionNum; + } + + virtual void handleModuleGlobalsBegin() { + if (os) + *os << " BLOCK: ModuleGlobalInfo {\n"; + } + + virtual void handleGlobalVariable( + const Type* ElemType, + bool isConstant, + GlobalValue::LinkageTypes Linkage, + unsigned SlotNum, + unsigned initSlot + ) { + if (os) { + *os << " GV: " + << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, " + << ( isConstant? "Constant, " : "Variable, ") + << " Linkage=" << Linkage << " Type="; + WriteTypeSymbolic(*os, ElemType, M); + *os << " Slot=" << SlotNum << " InitSlot=" << initSlot + << "\n"; + } + + bca.numGlobalVars++; + bca.numValues++; + if (SlotNum > bca.maxValueSlot) + bca.maxValueSlot = SlotNum; + if (initSlot > bca.maxValueSlot) + bca.maxValueSlot = initSlot; + + } + + virtual void handleTypeList(unsigned numEntries) { + bca.maxTypeSlot = numEntries - 1; + } + + virtual void handleType( const Type* Ty ) { + bca.numTypes++; + if (os) { + *os << " Type: "; + WriteTypeSymbolic(*os,Ty,M); + *os << "\n"; + } + } + + virtual void handleFunctionDeclaration( + Function* Func ///< The function + ) { + bca.numFunctions++; + bca.numValues++; + if (os) { + *os << " Function Decl: "; + WriteTypeSymbolic(*os,Func->getType(),M); + *os << "\n"; + } + } + + virtual void handleGlobalInitializer(GlobalVariable* GV, Constant* CV) { + if (os) { + *os << " Initializer: GV="; + GV->print(*os); + *os << " CV="; + CV->print(*os); + *os << "\n"; + } + } + + virtual void handleDependentLibrary(const std::string& libName) { + bca.numLibraries++; + bca.libSize += libName.size() + (libName.size() < 128 ? 1 : 2); + if (os) + *os << " Library: '" << libName << "'\n"; + } + + virtual void handleModuleGlobalsEnd() { + if (os) + *os << " } END BLOCK: ModuleGlobalInfo\n"; + if ( bca.progressiveVerify ) { + try { + verifyModule(*M, ThrowExceptionAction); + } catch ( std::string& msg ) { + bca.VerifyInfo += "Verify@EndModuleGlobalInfo: " + msg + "\n"; + } + } + } + + virtual void handleCompactionTableBegin() { + if (os) + *os << " BLOCK: CompactionTable {\n"; + bca.numCmpctnTables++; + } + + virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) { + if (os) + *os << " Plane: Ty=" << Ty << " Size=" << NumEntries << "\n"; + } + + virtual void handleCompactionTableType( unsigned i, unsigned TypSlot, + const Type* Ty ) { + if (os) { + *os << " Type: " << i << " Slot:" << TypSlot << " is "; + WriteTypeSymbolic(*os,Ty,M); + *os << "\n"; + } + } + + virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot, + unsigned ValSlot) { + if (os) + *os << " Value: " << i << " TypSlot: " << TypSlot + << " ValSlot:" << ValSlot << "\n"; + if (ValSlot > bca.maxValueSlot) + bca.maxValueSlot = ValSlot; + } + + virtual void handleCompactionTableEnd() { + if (os) + *os << " } END BLOCK: CompactionTable\n"; + } + + virtual void handleSymbolTableBegin(Function* CF, SymbolTable* ST) { + bca.numSymTab++; + if (os) + *os << " BLOCK: SymbolTable {\n"; + } + + virtual void handleSymbolTablePlane(unsigned Ty, unsigned NumEntries, + const Type* Typ) { + if (os) { + *os << " Plane: Ty=" << Ty << " Size=" << NumEntries << " Type: "; + WriteTypeSymbolic(*os,Typ,M); + *os << "\n"; + } + } + + virtual void handleSymbolTableType(unsigned i, unsigned TypSlot, + const std::string& name ) { + if (os) + *os << " Type " << i << " Slot=" << TypSlot + << " Name: " << name << "\n"; + } + + virtual void handleSymbolTableValue(unsigned i, unsigned ValSlot, + const std::string& name ) { + if (os) + *os << " Value " << i << " Slot=" << ValSlot + << " Name: " << name << "\n"; + if (ValSlot > bca.maxValueSlot) + bca.maxValueSlot = ValSlot; + } + + virtual void handleSymbolTableEnd() { + if (os) + *os << " } END BLOCK: SymbolTable\n"; + } + + virtual void handleFunctionBegin(Function* Func, unsigned Size) { + if (os) { + *os << " BLOCK: Function {\n" + << " Linkage: " << Func->getLinkage() << "\n" + << " Type: "; + WriteTypeSymbolic(*os,Func->getType(),M); + *os << "\n"; + } + + currFunc = &bca.FunctionInfo[Func]; + std::ostringstream tmp; + WriteTypeSymbolic(tmp,Func->getType(),M); + currFunc->description = tmp.str(); + currFunc->name = Func->getName(); + currFunc->byteSize = Size; + currFunc->numInstructions = 0; + currFunc->numBasicBlocks = 0; + currFunc->numPhis = 0; + currFunc->numOperands = 0; + currFunc->density = 0.0; + currFunc->instructionSize = 0; + currFunc->longInstructions = 0; + currFunc->vbrCount32 = 0; + currFunc->vbrCount64 = 0; + currFunc->vbrCompBytes = 0; + currFunc->vbrExpdBytes = 0; + + } + + virtual void handleFunctionEnd( Function* Func) { + if (os) + *os << " } END BLOCK: Function\n"; + currFunc->density = double(currFunc->byteSize) / + double(currFunc->numInstructions); + + if ( bca.progressiveVerify ) { + try { + verifyModule(*M, ThrowExceptionAction); + } catch ( std::string& msg ) { + bca.VerifyInfo += "Verify@EndFunction: " + msg + "\n"; + } + } + } + + virtual void handleBasicBlockBegin( unsigned blocknum) { + if (os) + *os << " BLOCK: BasicBlock #" << blocknum << "{\n"; + bca.numBasicBlocks++; + bca.numValues++; + if ( currFunc ) currFunc->numBasicBlocks++; + } + + virtual bool handleInstruction( unsigned Opcode, const Type* iType, + std::vector<unsigned>& Operands, unsigned Size){ + if (os) { + *os << " INST: OpCode=" + << Instruction::getOpcodeName(Opcode) << " Type=\""; + WriteTypeSymbolic(*os,iType,M); + *os << "\""; + for ( unsigned i = 0; i < Operands.size(); ++i ) + *os << " Op(" << i << ")=Slot(" << Operands[i] << ")"; + *os << "\n"; + } + + bca.numInstructions++; + bca.numValues++; + bca.instructionSize += Size; + if (Size > 4 ) bca.longInstructions++; + bca.numOperands += Operands.size(); + for (unsigned i = 0; i < Operands.size(); ++i ) + if (Operands[i] > bca.maxValueSlot) + bca.maxValueSlot = Operands[i]; + if ( currFunc ) { + currFunc->numInstructions++; + currFunc->instructionSize += Size; + if (Size > 4 ) currFunc->longInstructions++; + if ( Opcode == Instruction::PHI ) currFunc->numPhis++; + } + return Instruction::isTerminator(Opcode); + } + + virtual void handleBasicBlockEnd(unsigned blocknum) { + if (os) + *os << " } END BLOCK: BasicBlock #" << blocknum << "{\n"; + } + + virtual void handleGlobalConstantsBegin() { + if (os) + *os << " BLOCK: GlobalConstants {\n"; + } + + virtual void handleConstantExpression( unsigned Opcode, + std::vector<Constant*> ArgVec, Constant* C ) { + if (os) { + *os << " EXPR: " << Instruction::getOpcodeName(Opcode) << "\n"; + for ( unsigned i = 0; i < ArgVec.size(); ++i ) { + *os << " Arg#" << i << " "; ArgVec[i]->print(*os); + *os << "\n"; + } + *os << " Value="; + C->print(*os); + *os << "\n"; + } + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantValue( Constant * c ) { + if (os) { + *os << " VALUE: "; + c->print(*os); + *os << "\n"; + } + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantArray( const ArrayType* AT, + std::vector<Constant*>& Elements, + unsigned TypeSlot, + Constant* ArrayVal ) { + if (os) { + *os << " ARRAY: "; + WriteTypeSymbolic(*os,AT,M); + *os << " TypeSlot=" << TypeSlot << "\n"; + for ( unsigned i = 0; i < Elements.size(); ++i ) { + *os << " #" << i; + Elements[i]->print(*os); + *os << "\n"; + } + *os << " Value="; + ArrayVal->print(*os); + *os << "\n"; + } + + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantStruct( + const StructType* ST, + std::vector<Constant*>& Elements, + Constant* StructVal) + { + if (os) { + *os << " STRUC: "; + WriteTypeSymbolic(*os,ST,M); + *os << "\n"; + for ( unsigned i = 0; i < Elements.size(); ++i ) { + *os << " #" << i << " "; Elements[i]->print(*os); + *os << "\n"; + } + *os << " Value="; + StructVal->print(*os); + *os << "\n"; + } + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantPacked( + const PackedType* PT, + std::vector<Constant*>& Elements, + unsigned TypeSlot, + Constant* PackedVal) + { + if (os) { + *os << " PACKD: "; + WriteTypeSymbolic(*os,PT,M); + *os << " TypeSlot=" << TypeSlot << "\n"; + for ( unsigned i = 0; i < Elements.size(); ++i ) { + *os << " #" << i; + Elements[i]->print(*os); + *os << "\n"; + } + *os << " Value="; + PackedVal->print(*os); + *os << "\n"; + } + + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantPointer( const PointerType* PT, + unsigned Slot, GlobalValue* GV ) { + if (os) { + *os << " PNTR: "; + WriteTypeSymbolic(*os,PT,M); + *os << " Slot=" << Slot << " GlobalValue="; + GV->print(*os); + *os << "\n"; + } + bca.numConstants++; + bca.numValues++; + } + + virtual void handleConstantString( const ConstantArray* CA ) { + if (os) { + *os << " STRNG: "; + CA->print(*os); + *os << "\n"; + } + bca.numConstants++; + bca.numValues++; + } + + virtual void handleGlobalConstantsEnd() { + if (os) + *os << " } END BLOCK: GlobalConstants\n"; + + if ( bca.progressiveVerify ) { + try { + verifyModule(*M, ThrowExceptionAction); + } catch ( std::string& msg ) { + bca.VerifyInfo += "Verify@EndGlobalConstants: " + msg + "\n"; + } + } + } + + virtual void handleAlignment(unsigned numBytes) { + bca.numAlignment += numBytes; + } + + virtual void handleBlock( + unsigned BType, const unsigned char* StartPtr, unsigned Size) { + bca.numBlocks++; + assert(BType >= BytecodeFormat::ModuleBlockID); + assert(BType < BytecodeFormat::NumberOfBlockIDs); + bca.BlockSizes[ + llvm::BytecodeFormat::CompressedBytecodeBlockIdentifiers(BType)] += Size; + + if (bca.version < 3) // Check for long block headers versions + bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 8; + else + bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 4; + } + + virtual void handleVBR32(unsigned Size ) { + bca.vbrCount32++; + bca.vbrCompBytes += Size; + bca.vbrExpdBytes += sizeof(uint32_t); + if (currFunc) { + currFunc->vbrCount32++; + currFunc->vbrCompBytes += Size; + currFunc->vbrExpdBytes += sizeof(uint32_t); + } + } + + virtual void handleVBR64(unsigned Size ) { + bca.vbrCount64++; + bca.vbrCompBytes += Size; + bca.vbrExpdBytes += sizeof(uint64_t); + if ( currFunc ) { + currFunc->vbrCount64++; + currFunc->vbrCompBytes += Size; + currFunc->vbrExpdBytes += sizeof(uint64_t); + } + } +}; + + +/// @brief Utility for printing a titled unsigned value with +/// an aligned colon. +inline static void print(std::ostream& Out, const char*title, + unsigned val, bool nl = true ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << val << "\n"; +} + +/// @brief Utility for printing a titled double value with an +/// aligned colon +inline static void print(std::ostream&Out, const char*title, + double val ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << std::setprecision(6) << val << "\n" ; +} + +/// @brief Utility for printing a titled double value with a +/// percentage and aligned colon. +inline static void print(std::ostream&Out, const char*title, + double top, double bot ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << std::setprecision(6) << top + << " (" << std::left << std::setw(0) << std::setprecision(4) + << (top/bot)*100.0 << "%)\n"; +} + +/// @brief Utility for printing a titled string value with +/// an aligned colon. +inline static void print(std::ostream&Out, const char*title, + std::string val, bool nl = true) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::left << val << (nl ? "\n" : ""); +} + +} + +namespace llvm { + +/// This function prints the contents of rhe BytecodeAnalysis structure in +/// a human legible form. +/// @brief Print BytecodeAnalysis structure to an ostream +void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ) +{ + Out << "\nSummary Analysis Of " << bca.ModuleId << ": \n\n"; + print(Out, "Bytecode Analysis Of Module", bca.ModuleId); + print(Out, "Bytecode Version Number", bca.version); + print(Out, "File Size", bca.byteSize); + print(Out, "Module Bytes", + double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]), + double(bca.byteSize)); + print(Out, "Function Bytes", + double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]), + double(bca.byteSize)); + print(Out, "Global Types Bytes", + double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]), + double(bca.byteSize)); + print(Out, "Constant Pool Bytes", + double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]), + double(bca.byteSize)); + print(Out, "Module Globals Bytes", + double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]), + double(bca.byteSize)); + print(Out, "Instruction List Bytes", + double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]), + double(bca.byteSize)); + print(Out, "Compaction Table Bytes", + double(bca.BlockSizes[BytecodeFormat::CompactionTableBlockID]), + double(bca.byteSize)); + print(Out, "Symbol Table Bytes", + double(bca.BlockSizes[BytecodeFormat::SymbolTableBlockID]), + double(bca.byteSize)); + print(Out, "Alignment Bytes", + double(bca.numAlignment), double(bca.byteSize)); + print(Out, "Block Header Bytes", + double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]), + double(bca.byteSize)); + print(Out, "Dependent Libraries Bytes", double(bca.libSize), + double(bca.byteSize)); + print(Out, "Number Of Bytecode Blocks", bca.numBlocks); + print(Out, "Number Of Functions", bca.numFunctions); + print(Out, "Number Of Types", bca.numTypes); + print(Out, "Number Of Constants", bca.numConstants); + print(Out, "Number Of Global Variables", bca.numGlobalVars); + print(Out, "Number Of Values", bca.numValues); + print(Out, "Number Of Basic Blocks", bca.numBasicBlocks); + print(Out, "Number Of Instructions", bca.numInstructions); + print(Out, "Number Of Long Instructions", bca.longInstructions); + print(Out, "Number Of Operands", bca.numOperands); + print(Out, "Number Of Compaction Tables", bca.numCmpctnTables); + print(Out, "Number Of Symbol Tables", bca.numSymTab); + print(Out, "Number Of Dependent Libs", bca.numLibraries); + print(Out, "Total Instruction Size", bca.instructionSize); + print(Out, "Average Instruction Size", + double(bca.instructionSize)/double(bca.numInstructions)); + + print(Out, "Maximum Type Slot Number", bca.maxTypeSlot); + print(Out, "Maximum Value Slot Number", bca.maxValueSlot); + print(Out, "Bytes Per Value ", bca.fileDensity); + print(Out, "Bytes Per Global", bca.globalsDensity); + print(Out, "Bytes Per Function", bca.functionDensity); + print(Out, "# of VBR 32-bit Integers", bca.vbrCount32); + print(Out, "# of VBR 64-bit Integers", bca.vbrCount64); + print(Out, "# of VBR Compressed Bytes", bca.vbrCompBytes); + print(Out, "# of VBR Expanded Bytes", bca.vbrExpdBytes); + print(Out, "Bytes Saved With VBR", + double(bca.vbrExpdBytes)-double(bca.vbrCompBytes), + double(bca.vbrExpdBytes)); + + if (bca.detailedResults) { + Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n"; + + std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I = + bca.FunctionInfo.begin(); + std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E = + bca.FunctionInfo.end(); + + while ( I != E ) { + Out << std::left << std::setw(0) << "\n"; + if (I->second.numBasicBlocks == 0) Out << "External "; + Out << "Function: " << I->second.name << "\n"; + print(Out, "Type:", I->second.description); + print(Out, "Byte Size", I->second.byteSize); + if (I->second.numBasicBlocks) { + print(Out, "Basic Blocks", I->second.numBasicBlocks); + print(Out, "Instructions", I->second.numInstructions); + print(Out, "Long Instructions", I->second.longInstructions); + print(Out, "Operands", I->second.numOperands); + print(Out, "Instruction Size", I->second.instructionSize); + print(Out, "Average Instruction Size", + double(I->second.instructionSize) / I->second.numInstructions); + print(Out, "Bytes Per Instruction", I->second.density); + print(Out, "# of VBR 32-bit Integers", I->second.vbrCount32); + print(Out, "# of VBR 64-bit Integers", I->second.vbrCount64); + print(Out, "# of VBR Compressed Bytes", I->second.vbrCompBytes); + print(Out, "# of VBR Expanded Bytes", I->second.vbrExpdBytes); + print(Out, "Bytes Saved With VBR", + double(I->second.vbrExpdBytes) - I->second.vbrCompBytes), + double(I->second.vbrExpdBytes); + } + ++I; + } + } + + if ( bca.progressiveVerify ) + Out << bca.VerifyInfo; +} + +BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca, + std::ostream* output) +{ + return new AnalyzerHandler(bca,output); +} + +} + |