LLVM API Documentation

Analyzer.cpp

Go to the documentation of this file.
00001 //===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Reid Spencer and is distributed under the
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements the AnalyzerHandler class and PrintBytecodeAnalysis
00011 //  function which together comprise the basic functionality of the llmv-abcd
00012 //  tool. The AnalyzerHandler collects information about the bytecode file into
00013 //  the BytecodeAnalysis structure. The PrintBytecodeAnalysis function prints
00014 //  out the content of that structure.
00015 //  @see include/llvm/Bytecode/Analysis.h
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #include "Reader.h"
00020 #include "llvm/Constants.h"
00021 #include "llvm/DerivedTypes.h"
00022 #include "llvm/Module.h"
00023 #include "llvm/Analysis/Verifier.h"
00024 #include "llvm/Bytecode/BytecodeHandler.h"
00025 #include "llvm/Assembly/Writer.h"
00026 #include <iomanip>
00027 #include <sstream>
00028 #include <ios>
00029 
00030 using namespace llvm;
00031 
00032 namespace {
00033 
00034 /// @brief Bytecode reading handler for analyzing bytecode.
00035 class AnalyzerHandler : public BytecodeHandler {
00036   BytecodeAnalysis& bca;     ///< The structure in which data is recorded
00037   std::ostream* os;        ///< A convenience for osing data.
00038   /// @brief Keeps track of current function
00039   BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
00040   Module* M; ///< Keeps track of current module
00041 
00042 /// @name Constructor
00043 /// @{
00044 public:
00045   /// The only way to construct an AnalyzerHandler. All that is needed is a
00046   /// reference to the BytecodeAnalysis structure where the output will be
00047   /// placed.
00048   AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output)
00049     : bca(TheBca)
00050     , os(output)
00051     , currFunc(0)
00052     { }
00053 
00054 /// @}
00055 /// @name BytecodeHandler Implementations
00056 /// @{
00057 public:
00058   virtual void handleError(const std::string& str ) {
00059     if (os)
00060       *os << "ERROR: " << str << "\n";
00061   }
00062 
00063   virtual void handleStart( Module* Mod, unsigned theSize ) {
00064     M = Mod;
00065     if (os)
00066       *os << "Bytecode {\n";
00067     bca.byteSize = theSize;
00068     bca.ModuleId.clear();
00069     bca.numBlocks = 0;
00070     bca.numTypes = 0;
00071     bca.numValues = 0;
00072     bca.numFunctions = 0;
00073     bca.numConstants = 0;
00074     bca.numGlobalVars = 0;
00075     bca.numInstructions = 0;
00076     bca.numBasicBlocks = 0;
00077     bca.numOperands = 0;
00078     bca.numCmpctnTables = 0;
00079     bca.numSymTab = 0;
00080     bca.numLibraries = 0;
00081     bca.libSize = 0;
00082     bca.maxTypeSlot = 0;
00083     bca.maxValueSlot = 0;
00084     bca.numAlignment = 0;
00085     bca.fileDensity = 0.0;
00086     bca.globalsDensity = 0.0;
00087     bca.functionDensity = 0.0;
00088     bca.instructionSize = 0;
00089     bca.longInstructions = 0;
00090     bca.vbrCount32 = 0;
00091     bca.vbrCount64 = 0;
00092     bca.vbrCompBytes = 0;
00093     bca.vbrExpdBytes = 0;
00094     bca.FunctionInfo.clear();
00095     bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse] = 0;
00096     bca.BlockSizes[BytecodeFormat::ModuleBlockID] = theSize;
00097     bca.BlockSizes[BytecodeFormat::FunctionBlockID] = 0;
00098     bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID] = 0;
00099     bca.BlockSizes[BytecodeFormat::SymbolTableBlockID] = 0;
00100     bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID] = 0;
00101     bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID] = 0;
00102     bca.BlockSizes[BytecodeFormat::InstructionListBlockID] = 0;
00103     bca.BlockSizes[BytecodeFormat::CompactionTableBlockID] = 0;
00104   }
00105 
00106   virtual void handleFinish() {
00107     if (os)
00108       *os << "} End Bytecode\n";
00109 
00110     bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
00111     double globalSize = 0.0;
00112     globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]);
00113     globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]);
00114     globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]);
00115     bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
00116       bca.numGlobalVars );
00117     bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) /
00118       double(bca.numFunctions);
00119 
00120     if (bca.progressiveVerify) {
00121       std::string msg;
00122       if (verifyModule(*M, ReturnStatusAction, &msg))
00123         bca.VerifyInfo += "Verify@Finish: " + msg + "\n";
00124     }
00125   }
00126 
00127   virtual void handleModuleBegin(const std::string& id) {
00128     if (os)
00129       *os << "  Module " << id << " {\n";
00130     bca.ModuleId = id;
00131   }
00132 
00133   virtual void handleModuleEnd(const std::string& id) {
00134     if (os)
00135       *os << "  } End Module " << id << "\n";
00136     if (bca.progressiveVerify) {
00137       std::string msg;
00138       if (verifyModule(*M, ReturnStatusAction, &msg))
00139         bca.VerifyInfo += "Verify@EndModule: " + msg + "\n";
00140     }
00141   }
00142 
00143   virtual void handleVersionInfo(
00144     unsigned char RevisionNum,        ///< Byte code revision number
00145     Module::Endianness Endianness,    ///< Endianness indicator
00146     Module::PointerSize PointerSize   ///< PointerSize indicator
00147   ) {
00148     if (os)
00149       *os << "    RevisionNum: " << int(RevisionNum)
00150          << " Endianness: " << Endianness
00151          << " PointerSize: " << PointerSize << "\n";
00152     bca.version = RevisionNum;
00153   }
00154 
00155   virtual void handleModuleGlobalsBegin() {
00156     if (os)
00157       *os << "    BLOCK: ModuleGlobalInfo {\n";
00158   }
00159 
00160   virtual void handleGlobalVariable(
00161     const Type* ElemType,
00162     bool isConstant,
00163     GlobalValue::LinkageTypes Linkage,
00164     unsigned SlotNum,
00165     unsigned initSlot
00166   ) {
00167     if (os) {
00168       *os << "      GV: "
00169           << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, "
00170           << ( isConstant? "Constant, " : "Variable, ")
00171           << " Linkage=" << Linkage << " Type=";
00172       WriteTypeSymbolic(*os, ElemType, M);
00173       *os << " Slot=" << SlotNum << " InitSlot=" << initSlot
00174           << "\n";
00175     }
00176 
00177     bca.numGlobalVars++;
00178     bca.numValues++;
00179     if (SlotNum > bca.maxValueSlot)
00180       bca.maxValueSlot = SlotNum;
00181     if (initSlot > bca.maxValueSlot)
00182       bca.maxValueSlot = initSlot;
00183 
00184   }
00185 
00186   virtual void handleTypeList(unsigned numEntries) {
00187     bca.maxTypeSlot = numEntries - 1;
00188   }
00189 
00190   virtual void handleType( const Type* Ty ) {
00191     bca.numTypes++;
00192     if (os) {
00193       *os << "      Type: ";
00194       WriteTypeSymbolic(*os,Ty,M);
00195       *os << "\n";
00196     }
00197   }
00198 
00199   virtual void handleFunctionDeclaration(
00200     Function* Func            ///< The function
00201   ) {
00202     bca.numFunctions++;
00203     bca.numValues++;
00204     if (os) {
00205       *os << "      Function Decl: ";
00206       WriteTypeSymbolic(*os,Func->getType(),M);
00207       *os << "\n";
00208     }
00209   }
00210 
00211   virtual void handleGlobalInitializer(GlobalVariable* GV, Constant* CV) {
00212     if (os) {
00213       *os << "    Initializer: GV=";
00214       GV->print(*os);
00215       *os << "      CV=";
00216       CV->print(*os);
00217       *os << "\n";
00218     }
00219   }
00220 
00221   virtual void handleDependentLibrary(const std::string& libName) {
00222     bca.numLibraries++;
00223     bca.libSize += libName.size() + (libName.size() < 128 ? 1 : 2);
00224     if (os)
00225       *os << "      Library: '" << libName << "'\n";
00226   }
00227 
00228   virtual void handleModuleGlobalsEnd() {
00229     if (os)
00230       *os << "    } END BLOCK: ModuleGlobalInfo\n";
00231     if (bca.progressiveVerify) {
00232       std::string msg;
00233       if (verifyModule(*M, ReturnStatusAction, &msg))
00234         bca.VerifyInfo += "Verify@EndModuleGlobalInfo: " + msg + "\n";
00235     }
00236   }
00237 
00238   virtual void handleCompactionTableBegin() {
00239     if (os)
00240       *os << "      BLOCK: CompactionTable {\n";
00241     bca.numCmpctnTables++;
00242   }
00243 
00244   virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) {
00245     if (os)
00246       *os << "        Plane: Ty=" << Ty << " Size=" << NumEntries << "\n";
00247   }
00248 
00249   virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
00250       const Type* Ty ) {
00251     if (os) {
00252       *os << "          Type: " << i << " Slot:" << TypSlot << " is ";
00253       WriteTypeSymbolic(*os,Ty,M);
00254       *os << "\n";
00255     }
00256   }
00257 
00258   virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot,
00259                                           unsigned ValSlot) {
00260     if (os)
00261       *os << "          Value: " << i << " TypSlot: " << TypSlot
00262          << " ValSlot:" << ValSlot << "\n";
00263     if (ValSlot > bca.maxValueSlot)
00264       bca.maxValueSlot = ValSlot;
00265   }
00266 
00267   virtual void handleCompactionTableEnd() {
00268     if (os)
00269       *os << "      } END BLOCK: CompactionTable\n";
00270   }
00271 
00272   virtual void handleSymbolTableBegin(Function* CF, SymbolTable* ST) {
00273     bca.numSymTab++;
00274     if (os)
00275       *os << "    BLOCK: SymbolTable {\n";
00276   }
00277 
00278   virtual void handleSymbolTablePlane(unsigned Ty, unsigned NumEntries,
00279     const Type* Typ) {
00280     if (os) {
00281       *os << "      Plane: Ty=" << Ty << " Size=" << NumEntries << " Type: ";
00282       WriteTypeSymbolic(*os,Typ,M);
00283       *os << "\n";
00284     }
00285   }
00286 
00287   virtual void handleSymbolTableType(unsigned i, unsigned TypSlot,
00288     const std::string& name ) {
00289     if (os)
00290       *os << "        Type " << i << " Slot=" << TypSlot
00291          << " Name: " << name << "\n";
00292   }
00293 
00294   virtual void handleSymbolTableValue(unsigned i, unsigned ValSlot,
00295     const std::string& name ) {
00296     if (os)
00297       *os << "        Value " << i << " Slot=" << ValSlot
00298          << " Name: " << name << "\n";
00299     if (ValSlot > bca.maxValueSlot)
00300       bca.maxValueSlot = ValSlot;
00301   }
00302 
00303   virtual void handleSymbolTableEnd() {
00304     if (os)
00305       *os << "    } END BLOCK: SymbolTable\n";
00306   }
00307 
00308   virtual void handleFunctionBegin(Function* Func, unsigned Size) {
00309     if (os) {
00310       *os << "    BLOCK: Function {\n"
00311           << "      Linkage: " << Func->getLinkage() << "\n"
00312           << "      Type: ";
00313       WriteTypeSymbolic(*os,Func->getType(),M);
00314       *os << "\n";
00315     }
00316 
00317     currFunc = &bca.FunctionInfo[Func];
00318     std::ostringstream tmp;
00319     WriteTypeSymbolic(tmp,Func->getType(),M);
00320     currFunc->description = tmp.str();
00321     currFunc->name = Func->getName();
00322     currFunc->byteSize = Size;
00323     currFunc->numInstructions = 0;
00324     currFunc->numBasicBlocks = 0;
00325     currFunc->numPhis = 0;
00326     currFunc->numOperands = 0;
00327     currFunc->density = 0.0;
00328     currFunc->instructionSize = 0;
00329     currFunc->longInstructions = 0;
00330     currFunc->vbrCount32 = 0;
00331     currFunc->vbrCount64 = 0;
00332     currFunc->vbrCompBytes = 0;
00333     currFunc->vbrExpdBytes = 0;
00334 
00335   }
00336 
00337   virtual void handleFunctionEnd( Function* Func) {
00338     if (os)
00339       *os << "    } END BLOCK: Function\n";
00340     currFunc->density = double(currFunc->byteSize) /
00341       double(currFunc->numInstructions);
00342 
00343     if (bca.progressiveVerify) {
00344       std::string msg;
00345       if (verifyModule(*M, ReturnStatusAction, &msg))
00346         bca.VerifyInfo += "Verify@EndFunction: " + msg + "\n";
00347     }
00348   }
00349 
00350   virtual void handleBasicBlockBegin( unsigned blocknum) {
00351     if (os)
00352       *os << "      BLOCK: BasicBlock #" << blocknum << "{\n";
00353     bca.numBasicBlocks++;
00354     bca.numValues++;
00355     if ( currFunc ) currFunc->numBasicBlocks++;
00356   }
00357 
00358   virtual bool handleInstruction( unsigned Opcode, const Type* iType,
00359                                 std::vector<unsigned>& Operands, unsigned Size){
00360     if (os) {
00361       *os << "        INST: OpCode="
00362          << Instruction::getOpcodeName(Opcode) << " Type=\"";
00363       WriteTypeSymbolic(*os,iType,M);
00364       *os << "\"";
00365       for ( unsigned i = 0; i < Operands.size(); ++i )
00366         *os << " Op(" << i << ")=Slot(" << Operands[i] << ")";
00367       *os << "\n";
00368     }
00369 
00370     bca.numInstructions++;
00371     bca.numValues++;
00372     bca.instructionSize += Size;
00373     if (Size > 4 ) bca.longInstructions++;
00374     bca.numOperands += Operands.size();
00375     for (unsigned i = 0; i < Operands.size(); ++i )
00376       if (Operands[i] > bca.maxValueSlot)
00377         bca.maxValueSlot = Operands[i];
00378     if ( currFunc ) {
00379       currFunc->numInstructions++;
00380       currFunc->instructionSize += Size;
00381       if (Size > 4 ) currFunc->longInstructions++;
00382       if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
00383     }
00384     return Instruction::isTerminator(Opcode);
00385   }
00386 
00387   virtual void handleBasicBlockEnd(unsigned blocknum) {
00388     if (os)
00389       *os << "      } END BLOCK: BasicBlock #" << blocknum << "{\n";
00390   }
00391 
00392   virtual void handleGlobalConstantsBegin() {
00393     if (os)
00394       *os << "    BLOCK: GlobalConstants {\n";
00395   }
00396 
00397   virtual void handleConstantExpression( unsigned Opcode,
00398       std::vector<Constant*> ArgVec, Constant* C ) {
00399     if (os) {
00400       *os << "      EXPR: " << Instruction::getOpcodeName(Opcode) << "\n";
00401       for ( unsigned i = 0; i < ArgVec.size(); ++i ) {
00402         *os << "        Arg#" << i << " "; ArgVec[i]->print(*os);
00403         *os << "\n";
00404       }
00405       *os << "        Value=";
00406       C->print(*os);
00407       *os << "\n";
00408     }
00409     bca.numConstants++;
00410     bca.numValues++;
00411   }
00412 
00413   virtual void handleConstantValue( Constant * c ) {
00414     if (os) {
00415       *os << "      VALUE: ";
00416       c->print(*os);
00417       *os << "\n";
00418     }
00419     bca.numConstants++;
00420     bca.numValues++;
00421   }
00422 
00423   virtual void handleConstantArray( const ArrayType* AT,
00424           std::vector<Constant*>& Elements,
00425           unsigned TypeSlot,
00426           Constant* ArrayVal ) {
00427     if (os) {
00428       *os << "      ARRAY: ";
00429       WriteTypeSymbolic(*os,AT,M);
00430       *os << " TypeSlot=" << TypeSlot << "\n";
00431       for ( unsigned i = 0; i < Elements.size(); ++i ) {
00432         *os << "        #" << i;
00433         Elements[i]->print(*os);
00434         *os << "\n";
00435       }
00436       *os << "        Value=";
00437       ArrayVal->print(*os);
00438       *os << "\n";
00439     }
00440 
00441     bca.numConstants++;
00442     bca.numValues++;
00443   }
00444 
00445   virtual void handleConstantStruct(
00446         const StructType* ST,
00447         std::vector<Constant*>& Elements,
00448         Constant* StructVal)
00449   {
00450     if (os) {
00451       *os << "      STRUC: ";
00452       WriteTypeSymbolic(*os,ST,M);
00453       *os << "\n";
00454       for ( unsigned i = 0; i < Elements.size(); ++i ) {
00455         *os << "        #" << i << " "; Elements[i]->print(*os);
00456         *os << "\n";
00457       }
00458       *os << "        Value=";
00459       StructVal->print(*os);
00460       *os << "\n";
00461     }
00462     bca.numConstants++;
00463     bca.numValues++;
00464   }
00465 
00466   virtual void handleConstantPacked(
00467     const PackedType* PT,
00468     std::vector<Constant*>& Elements,
00469     unsigned TypeSlot,
00470     Constant* PackedVal)
00471   {
00472     if (os) {
00473       *os << "      PACKD: ";
00474       WriteTypeSymbolic(*os,PT,M);
00475       *os << " TypeSlot=" << TypeSlot << "\n";
00476       for ( unsigned i = 0; i < Elements.size(); ++i ) {
00477         *os << "        #" << i;
00478         Elements[i]->print(*os);
00479         *os << "\n";
00480       }
00481       *os << "        Value=";
00482       PackedVal->print(*os);
00483       *os << "\n";
00484     }
00485 
00486     bca.numConstants++;
00487     bca.numValues++;
00488   }
00489 
00490   virtual void handleConstantPointer( const PointerType* PT,
00491       unsigned Slot, GlobalValue* GV ) {
00492     if (os) {
00493       *os << "       PNTR: ";
00494       WriteTypeSymbolic(*os,PT,M);
00495       *os << " Slot=" << Slot << " GlobalValue=";
00496       GV->print(*os);
00497       *os << "\n";
00498     }
00499     bca.numConstants++;
00500     bca.numValues++;
00501   }
00502 
00503   virtual void handleConstantString( const ConstantArray* CA ) {
00504     if (os) {
00505       *os << "      STRNG: ";
00506       CA->print(*os);
00507       *os << "\n";
00508     }
00509     bca.numConstants++;
00510     bca.numValues++;
00511   }
00512 
00513   virtual void handleGlobalConstantsEnd() {
00514     if (os)
00515       *os << "    } END BLOCK: GlobalConstants\n";
00516 
00517     if (bca.progressiveVerify) {
00518       std::string msg;
00519       if (verifyModule(*M, ReturnStatusAction, &msg))
00520         bca.VerifyInfo += "Verify@EndGlobalConstants: " + msg + "\n";
00521     }
00522   }
00523 
00524   virtual void handleAlignment(unsigned numBytes) {
00525     bca.numAlignment += numBytes;
00526   }
00527 
00528   virtual void handleBlock(
00529     unsigned BType, const unsigned char* StartPtr, unsigned Size) {
00530     bca.numBlocks++;
00531     assert(BType >= BytecodeFormat::ModuleBlockID);
00532     assert(BType < BytecodeFormat::NumberOfBlockIDs);
00533     bca.BlockSizes[
00534       llvm::BytecodeFormat::CompressedBytecodeBlockIdentifiers(BType)] += Size;
00535 
00536     if (bca.version < 3) // Check for long block headers versions
00537       bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 8;
00538     else
00539       bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 4;
00540   }
00541 
00542   virtual void handleVBR32(unsigned Size ) {
00543     bca.vbrCount32++;
00544     bca.vbrCompBytes += Size;
00545     bca.vbrExpdBytes += sizeof(uint32_t);
00546     if (currFunc) {
00547       currFunc->vbrCount32++;
00548       currFunc->vbrCompBytes += Size;
00549       currFunc->vbrExpdBytes += sizeof(uint32_t);
00550     }
00551   }
00552 
00553   virtual void handleVBR64(unsigned Size ) {
00554     bca.vbrCount64++;
00555     bca.vbrCompBytes += Size;
00556     bca.vbrExpdBytes += sizeof(uint64_t);
00557     if ( currFunc ) {
00558       currFunc->vbrCount64++;
00559       currFunc->vbrCompBytes += Size;
00560       currFunc->vbrExpdBytes += sizeof(uint64_t);
00561     }
00562   }
00563 };
00564 
00565 
00566 /// @brief Utility for printing a titled unsigned value with
00567 /// an aligned colon.
00568 inline static void print(std::ostream& Out, const char*title,
00569   unsigned val, bool nl = true ) {
00570   Out << std::setw(30) << std::right << title
00571       << std::setw(0) << ": "
00572       << std::setw(9) << val << "\n";
00573 }
00574 
00575 /// @brief Utility for printing a titled double value with an
00576 /// aligned colon
00577 inline static void print(std::ostream&Out, const char*title,
00578   double val ) {
00579   Out << std::setw(30) << std::right << title
00580       << std::setw(0) << ": "
00581       << std::setw(9) << std::setprecision(6) << val << "\n" ;
00582 }
00583 
00584 /// @brief Utility for printing a titled double value with a
00585 /// percentage and aligned colon.
00586 inline static void print(std::ostream&Out, const char*title,
00587   double top, double bot ) {
00588   Out << std::setw(30) << std::right << title
00589       << std::setw(0) << ": "
00590       << std::setw(9) << std::setprecision(6) << top
00591       << " (" << std::left << std::setw(0) << std::setprecision(4)
00592       << (top/bot)*100.0 << "%)\n";
00593 }
00594 
00595 /// @brief Utility for printing a titled string value with
00596 /// an aligned colon.
00597 inline static void print(std::ostream&Out, const char*title,
00598   std::string val, bool nl = true) {
00599   Out << std::setw(30) << std::right << title
00600       << std::setw(0) << ": "
00601       << std::left << val << (nl ? "\n" : "");
00602 }
00603 
00604 }
00605 
00606 namespace llvm {
00607 
00608 /// This function prints the contents of rhe BytecodeAnalysis structure in
00609 /// a human legible form.
00610 /// @brief Print BytecodeAnalysis structure to an ostream
00611 void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
00612 {
00613   Out << "\nSummary Analysis Of " << bca.ModuleId << ": \n\n";
00614   print(Out, "Bytecode Analysis Of Module",     bca.ModuleId);
00615   print(Out, "Bytecode Version Number",         bca.version);
00616   print(Out, "File Size",                       bca.byteSize);
00617   print(Out, "Module Bytes",
00618         double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]),
00619         double(bca.byteSize));
00620   print(Out, "Function Bytes",
00621         double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]),
00622         double(bca.byteSize));
00623   print(Out, "Global Types Bytes",
00624         double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]),
00625         double(bca.byteSize));
00626   print(Out, "Constant Pool Bytes",
00627         double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]),
00628         double(bca.byteSize));
00629   print(Out, "Module Globals Bytes",
00630         double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]),
00631         double(bca.byteSize));
00632   print(Out, "Instruction List Bytes",
00633         double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]),
00634         double(bca.byteSize));
00635   print(Out, "Compaction Table Bytes",
00636         double(bca.BlockSizes[BytecodeFormat::CompactionTableBlockID]),
00637         double(bca.byteSize));
00638   print(Out, "Symbol Table Bytes",
00639         double(bca.BlockSizes[BytecodeFormat::SymbolTableBlockID]),
00640         double(bca.byteSize));
00641   print(Out, "Alignment Bytes",
00642         double(bca.numAlignment), double(bca.byteSize));
00643   print(Out, "Block Header Bytes",
00644         double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]),
00645         double(bca.byteSize));
00646   print(Out, "Dependent Libraries Bytes", double(bca.libSize),
00647         double(bca.byteSize));
00648   print(Out, "Number Of Bytecode Blocks",       bca.numBlocks);
00649   print(Out, "Number Of Functions",             bca.numFunctions);
00650   print(Out, "Number Of Types",                 bca.numTypes);
00651   print(Out, "Number Of Constants",             bca.numConstants);
00652   print(Out, "Number Of Global Variables",      bca.numGlobalVars);
00653   print(Out, "Number Of Values",                bca.numValues);
00654   print(Out, "Number Of Basic Blocks",          bca.numBasicBlocks);
00655   print(Out, "Number Of Instructions",          bca.numInstructions);
00656   print(Out, "Number Of Long Instructions",     bca.longInstructions);
00657   print(Out, "Number Of Operands",              bca.numOperands);
00658   print(Out, "Number Of Compaction Tables",     bca.numCmpctnTables);
00659   print(Out, "Number Of Symbol Tables",         bca.numSymTab);
00660   print(Out, "Number Of Dependent Libs",        bca.numLibraries);
00661   print(Out, "Total Instruction Size",          bca.instructionSize);
00662   print(Out, "Average Instruction Size",
00663         double(bca.instructionSize)/double(bca.numInstructions));
00664 
00665   print(Out, "Maximum Type Slot Number",        bca.maxTypeSlot);
00666   print(Out, "Maximum Value Slot Number",       bca.maxValueSlot);
00667   print(Out, "Bytes Per Value ",                bca.fileDensity);
00668   print(Out, "Bytes Per Global",                bca.globalsDensity);
00669   print(Out, "Bytes Per Function",              bca.functionDensity);
00670   print(Out, "# of VBR 32-bit Integers",   bca.vbrCount32);
00671   print(Out, "# of VBR 64-bit Integers",   bca.vbrCount64);
00672   print(Out, "# of VBR Compressed Bytes",  bca.vbrCompBytes);
00673   print(Out, "# of VBR Expanded Bytes",    bca.vbrExpdBytes);
00674   print(Out, "Bytes Saved With VBR",
00675         double(bca.vbrExpdBytes)-double(bca.vbrCompBytes),
00676         double(bca.vbrExpdBytes));
00677 
00678   if (bca.detailedResults) {
00679     Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n";
00680 
00681     std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
00682       bca.FunctionInfo.begin();
00683     std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
00684       bca.FunctionInfo.end();
00685 
00686     while ( I != E ) {
00687       Out << std::left << std::setw(0) << "\n";
00688       if (I->second.numBasicBlocks == 0) Out << "External ";
00689       Out << "Function: " << I->second.name << "\n";
00690       print(Out, "Type:", I->second.description);
00691       print(Out, "Byte Size", I->second.byteSize);
00692       if (I->second.numBasicBlocks) {
00693         print(Out, "Basic Blocks", I->second.numBasicBlocks);
00694         print(Out, "Instructions", I->second.numInstructions);
00695         print(Out, "Long Instructions", I->second.longInstructions);
00696         print(Out, "Operands", I->second.numOperands);
00697         print(Out, "Instruction Size", I->second.instructionSize);
00698         print(Out, "Average Instruction Size",
00699               double(I->second.instructionSize) / I->second.numInstructions);
00700         print(Out, "Bytes Per Instruction", I->second.density);
00701         print(Out, "# of VBR 32-bit Integers",   I->second.vbrCount32);
00702         print(Out, "# of VBR 64-bit Integers",   I->second.vbrCount64);
00703         print(Out, "# of VBR Compressed Bytes",  I->second.vbrCompBytes);
00704         print(Out, "# of VBR Expanded Bytes",    I->second.vbrExpdBytes);
00705         print(Out, "Bytes Saved With VBR",
00706               double(I->second.vbrExpdBytes) - I->second.vbrCompBytes),
00707               double(I->second.vbrExpdBytes);
00708       }
00709       ++I;
00710     }
00711   }
00712 
00713   if ( bca.progressiveVerify )
00714     Out << bca.VerifyInfo;
00715 }
00716 
00717 BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca,
00718                                                std::ostream* output)
00719 {
00720   return new AnalyzerHandler(bca,output);
00721 }
00722 
00723 }
00724