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