LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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