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