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 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