LLVM API Documentation
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