For PR411:
[oota-llvm.git] / lib / Bytecode / Reader / Analyzer.cpp
1 //===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements the AnalyzerHandler class and PrintBytecodeAnalysis
11 //  function which together comprise the basic functionality of the llmv-abcd
12 //  tool. The AnalyzerHandler collects information about the bytecode file into
13 //  the BytecodeAnalysis structure. The PrintBytecodeAnalysis function prints
14 //  out the content of that structure.
15 //  @see include/llvm/Bytecode/Analysis.h
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "Reader.h"
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Module.h"
23 #include "llvm/Analysis/Verifier.h"
24 #include "llvm/Bytecode/BytecodeHandler.h"
25 #include "llvm/Assembly/Writer.h"
26 #include <iomanip>
27 #include <sstream>
28 #include <ios>
29
30 using namespace llvm;
31
32 namespace {
33
34 /// @brief Bytecode reading handler for analyzing bytecode.
35 class AnalyzerHandler : public BytecodeHandler {
36   BytecodeAnalysis& bca;     ///< The structure in which data is recorded
37   std::ostream* os;        ///< A convenience for osing data.
38   /// @brief Keeps track of current function
39   BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
40   Module* M; ///< Keeps track of current module
41
42 /// @name Constructor
43 /// @{
44 public:
45   /// The only way to construct an AnalyzerHandler. All that is needed is a
46   /// reference to the BytecodeAnalysis structure where the output will be
47   /// placed.
48   AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output)
49     : bca(TheBca)
50     , os(output)
51     , currFunc(0)
52     { }
53
54 /// @}
55 /// @name BytecodeHandler Implementations
56 /// @{
57 public:
58   virtual void handleError(const std::string& str ) {
59     if (os)
60       *os << "ERROR: " << str << "\n";
61   }
62
63   virtual void handleStart( Module* Mod, unsigned theSize ) {
64     M = Mod;
65     if (os)
66       *os << "Bytecode {\n";
67     bca.byteSize = theSize;
68     bca.ModuleId.clear();
69     bca.numBlocks = 0;
70     bca.numTypes = 0;
71     bca.numValues = 0;
72     bca.numFunctions = 0;
73     bca.numConstants = 0;
74     bca.numGlobalVars = 0;
75     bca.numInstructions = 0;
76     bca.numBasicBlocks = 0;
77     bca.numOperands = 0;
78     bca.numCmpctnTables = 0;
79     bca.numSymTab = 0;
80     bca.numLibraries = 0;
81     bca.libSize = 0;
82     bca.maxTypeSlot = 0;
83     bca.maxValueSlot = 0;
84     bca.numAlignment = 0;
85     bca.fileDensity = 0.0;
86     bca.globalsDensity = 0.0;
87     bca.functionDensity = 0.0;
88     bca.instructionSize = 0;
89     bca.longInstructions = 0;
90     bca.vbrCount32 = 0;
91     bca.vbrCount64 = 0;
92     bca.vbrCompBytes = 0;
93     bca.vbrExpdBytes = 0;
94     bca.FunctionInfo.clear();
95     bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse] = 0;
96     bca.BlockSizes[BytecodeFormat::ModuleBlockID] = theSize;
97     bca.BlockSizes[BytecodeFormat::FunctionBlockID] = 0;
98     bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID] = 0;
99     bca.BlockSizes[BytecodeFormat::ValueSymbolTableBlockID] = 0;
100     bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID] = 0;
101     bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID] = 0;
102     bca.BlockSizes[BytecodeFormat::InstructionListBlockID] = 0;
103     bca.BlockSizes[BytecodeFormat::TypeSymbolTableBlockID] = 0;
104   }
105
106   virtual void handleFinish() {
107     if (os)
108       *os << "} End Bytecode\n";
109
110     bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
111     double globalSize = 0.0;
112     globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]);
113     globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]);
114     globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]);
115     bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
116       bca.numGlobalVars );
117     bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) /
118       double(bca.numFunctions);
119
120     if (bca.progressiveVerify) {
121       std::string msg;
122       if (verifyModule(*M, ReturnStatusAction, &msg))
123         bca.VerifyInfo += "Verify@Finish: " + msg + "\n";
124     }
125   }
126
127   virtual void handleModuleBegin(const std::string& id) {
128     if (os)
129       *os << "  Module " << id << " {\n";
130     bca.ModuleId = id;
131   }
132
133   virtual void handleModuleEnd(const std::string& id) {
134     if (os)
135       *os << "  } End Module " << id << "\n";
136     if (bca.progressiveVerify) {
137       std::string msg;
138       if (verifyModule(*M, ReturnStatusAction, &msg))
139         bca.VerifyInfo += "Verify@EndModule: " + msg + "\n";
140     }
141   }
142
143   virtual void handleVersionInfo(
144     unsigned char RevisionNum        ///< Byte code revision number
145   ) {
146     if (os)
147       *os << "    RevisionNum: " << int(RevisionNum) << "\n";
148     bca.version = RevisionNum;
149   }
150
151   virtual void handleModuleGlobalsBegin() {
152     if (os)
153       *os << "    BLOCK: ModuleGlobalInfo {\n";
154   }
155
156   virtual void handleGlobalVariable(
157     const Type* ElemType,
158     bool isConstant,
159     GlobalValue::LinkageTypes Linkage,
160     GlobalValue::VisibilityTypes Visibility,
161     unsigned SlotNum,
162     unsigned initSlot
163   ) {
164     if (os) {
165       *os << "      GV: "
166           << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, "
167           << ( isConstant? "Constant, " : "Variable, ")
168           << " Linkage=" << Linkage
169           << " Visibility="<< Visibility
170           << " Type=";
171       WriteTypeSymbolic(*os, ElemType, M);
172       *os << " Slot=" << SlotNum << " InitSlot=" << initSlot
173           << "\n";
174     }
175
176     bca.numGlobalVars++;
177     bca.numValues++;
178     if (SlotNum > bca.maxValueSlot)
179       bca.maxValueSlot = SlotNum;
180     if (initSlot > bca.maxValueSlot)
181       bca.maxValueSlot = initSlot;
182
183   }
184
185   virtual void handleTypeList(unsigned numEntries) {
186     bca.maxTypeSlot = numEntries - 1;
187   }
188
189   virtual void handleType( const Type* Ty ) {
190     bca.numTypes++;
191     if (os) {
192       *os << "      Type: ";
193       WriteTypeSymbolic(*os,Ty,M);
194       *os << "\n";
195     }
196   }
197
198   virtual void handleFunctionDeclaration(
199     Function* Func            ///< The function
200   ) {
201     bca.numFunctions++;
202     bca.numValues++;
203     if (os) {
204       *os << "      Function Decl: ";
205       WriteTypeSymbolic(*os,Func->getType(),M);
206       *os <<", Linkage=" << Func->getLinkage();
207       *os <<", Visibility=" << Func->getVisibility();
208       *os << "\n";
209     }
210   }
211
212   virtual void handleGlobalInitializer(GlobalVariable* GV, Constant* CV) {
213     if (os) {
214       *os << "    Initializer: GV=";
215       GV->print(*os);
216       *os << "      CV=";
217       CV->print(*os);
218       *os << "\n";
219     }
220   }
221
222   virtual void handleDependentLibrary(const std::string& libName) {
223     bca.numLibraries++;
224     bca.libSize += libName.size() + (libName.size() < 128 ? 1 : 2);
225     if (os)
226       *os << "      Library: '" << libName << "'\n";
227   }
228
229   virtual void handleModuleGlobalsEnd() {
230     if (os)
231       *os << "    } END BLOCK: ModuleGlobalInfo\n";
232     if (bca.progressiveVerify) {
233       std::string msg;
234       if (verifyModule(*M, ReturnStatusAction, &msg))
235         bca.VerifyInfo += "Verify@EndModuleGlobalInfo: " + msg + "\n";
236     }
237   }
238
239   virtual void handleCompactionTableBegin() {
240     if (os)
241       *os << "      BLOCK: CompactionTable {\n";
242     bca.numCmpctnTables++;
243   }
244
245   virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) {
246     if (os)
247       *os << "        Plane: Ty=" << Ty << " Size=" << NumEntries << "\n";
248   }
249
250   virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
251       const Type* Ty ) {
252     if (os) {
253       *os << "          Type: " << i << " Slot:" << TypSlot << " is ";
254       WriteTypeSymbolic(*os,Ty,M);
255       *os << "\n";
256     }
257   }
258
259   virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot,
260                                           unsigned ValSlot) {
261     if (os)
262       *os << "          Value: " << i << " TypSlot: " << TypSlot
263          << " ValSlot:" << ValSlot << "\n";
264     if (ValSlot > bca.maxValueSlot)
265       bca.maxValueSlot = ValSlot;
266   }
267
268   virtual void handleCompactionTableEnd() {
269     if (os)
270       *os << "      } END BLOCK: CompactionTable\n";
271   }
272
273   virtual void handleTypeSymbolTableBegin(TypeSymbolTable* ST) {
274     bca.numSymTab++;
275     if (os)
276       *os << "    BLOCK: TypeSymbolTable {\n";
277   }
278   virtual void handleValueSymbolTableBegin(Function* CF, ValueSymbolTable* ST) {
279     bca.numSymTab++;
280     if (os)
281       *os << "    BLOCK: ValueSymbolTable {\n";
282   }
283
284   virtual void handleSymbolTableType(unsigned i, unsigned TypSlot,
285     const std::string& name ) {
286     if (os)
287       *os << "        Type " << i << " Slot=" << TypSlot
288          << " Name: " << name << "\n";
289   }
290
291   virtual void handleSymbolTableValue(unsigned TySlot, unsigned ValSlot, 
292                                       const std::string& name) {
293     if (os)
294       *os << "        Value " << TySlot << " Slot=" << ValSlot
295          << " Name: " << name << "\n";
296     if (ValSlot > bca.maxValueSlot)
297       bca.maxValueSlot = ValSlot;
298   }
299
300   virtual void handleValueSymbolTableEnd() {
301     if (os)
302       *os << "    } END BLOCK: ValueSymbolTable\n";
303   }
304
305   virtual void handleTypeSymbolTableEnd() {
306     if (os)
307       *os << "    } END BLOCK: TypeSymbolTable\n";
308   }
309
310   virtual void handleFunctionBegin(Function* Func, unsigned Size) {
311     if (os) {
312       *os << "    BLOCK: Function {\n"
313           << "      Linkage: " << Func->getLinkage() << "\n"
314           << "      Visibility: " << Func->getVisibility() << "\n"
315           << "      Type: ";
316       WriteTypeSymbolic(*os,Func->getType(),M);
317       *os << "\n";
318     }
319
320     currFunc = &bca.FunctionInfo[Func];
321     std::ostringstream tmp;
322     WriteTypeSymbolic(tmp,Func->getType(),M);
323     currFunc->description = tmp.str();
324     currFunc->name = Func->getName();
325     currFunc->byteSize = Size;
326     currFunc->numInstructions = 0;
327     currFunc->numBasicBlocks = 0;
328     currFunc->numPhis = 0;
329     currFunc->numOperands = 0;
330     currFunc->density = 0.0;
331     currFunc->instructionSize = 0;
332     currFunc->longInstructions = 0;
333     currFunc->vbrCount32 = 0;
334     currFunc->vbrCount64 = 0;
335     currFunc->vbrCompBytes = 0;
336     currFunc->vbrExpdBytes = 0;
337
338   }
339
340   virtual void handleFunctionEnd( Function* Func) {
341     if (os)
342       *os << "    } END BLOCK: Function\n";
343     currFunc->density = double(currFunc->byteSize) /
344       double(currFunc->numInstructions);
345
346     if (bca.progressiveVerify) {
347       std::string msg;
348       if (verifyModule(*M, ReturnStatusAction, &msg))
349         bca.VerifyInfo += "Verify@EndFunction: " + msg + "\n";
350     }
351   }
352
353   virtual void handleBasicBlockBegin( unsigned blocknum) {
354     if (os)
355       *os << "      BLOCK: BasicBlock #" << blocknum << "{\n";
356     bca.numBasicBlocks++;
357     bca.numValues++;
358     if ( currFunc ) currFunc->numBasicBlocks++;
359   }
360
361   virtual bool handleInstruction( unsigned Opcode, const Type* iType,
362                                 std::vector<unsigned>& Operands, 
363                                 Instruction *Inst,
364                                 unsigned Size){
365     if (os) {
366       *os << "        INST: OpCode="
367          << Instruction::getOpcodeName(Opcode);
368       for ( unsigned i = 0; i < Operands.size(); ++i )
369         *os << " Op(" << Operands[i] << ")";
370       *os << *Inst;
371     }
372
373     bca.numInstructions++;
374     bca.numValues++;
375     bca.instructionSize += Size;
376     if (Size > 4 ) bca.longInstructions++;
377     bca.numOperands += Operands.size();
378     for (unsigned i = 0; i < Operands.size(); ++i )
379       if (Operands[i] > bca.maxValueSlot)
380         bca.maxValueSlot = Operands[i];
381     if ( currFunc ) {
382       currFunc->numInstructions++;
383       currFunc->instructionSize += Size;
384       if (Size > 4 ) currFunc->longInstructions++;
385       if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
386     }
387     return Instruction::isTerminator(Opcode);
388   }
389
390   virtual void handleBasicBlockEnd(unsigned blocknum) {
391     if (os)
392       *os << "      } END BLOCK: BasicBlock #" << blocknum << "\n";
393   }
394
395   virtual void handleGlobalConstantsBegin() {
396     if (os)
397       *os << "    BLOCK: GlobalConstants {\n";
398   }
399
400   virtual void handleConstantExpression( unsigned Opcode,
401       std::vector<Constant*> ArgVec, Constant* C ) {
402     if (os) {
403       *os << "      EXPR: " << Instruction::getOpcodeName(Opcode) << "\n";
404       for ( unsigned i = 0; i < ArgVec.size(); ++i ) {
405         *os << "        Arg#" << i << " "; ArgVec[i]->print(*os);
406         *os << "\n";
407       }
408       *os << "        Value=";
409       C->print(*os);
410       *os << "\n";
411     }
412     bca.numConstants++;
413     bca.numValues++;
414   }
415
416   virtual void handleConstantValue( Constant * c ) {
417     if (os) {
418       *os << "      VALUE: ";
419       c->print(*os);
420       *os << "\n";
421     }
422     bca.numConstants++;
423     bca.numValues++;
424   }
425
426   virtual void handleConstantArray( const ArrayType* AT,
427           std::vector<Constant*>& Elements,
428           unsigned TypeSlot,
429           Constant* ArrayVal ) {
430     if (os) {
431       *os << "      ARRAY: ";
432       WriteTypeSymbolic(*os,AT,M);
433       *os << " TypeSlot=" << TypeSlot << "\n";
434       for ( unsigned i = 0; i < Elements.size(); ++i ) {
435         *os << "        #" << i;
436         Elements[i]->print(*os);
437         *os << "\n";
438       }
439       *os << "        Value=";
440       ArrayVal->print(*os);
441       *os << "\n";
442     }
443
444     bca.numConstants++;
445     bca.numValues++;
446   }
447
448   virtual void handleConstantStruct(
449         const StructType* ST,
450         std::vector<Constant*>& Elements,
451         Constant* StructVal)
452   {
453     if (os) {
454       *os << "      STRUC: ";
455       WriteTypeSymbolic(*os,ST,M);
456       *os << "\n";
457       for ( unsigned i = 0; i < Elements.size(); ++i ) {
458         *os << "        #" << i << " "; Elements[i]->print(*os);
459         *os << "\n";
460       }
461       *os << "        Value=";
462       StructVal->print(*os);
463       *os << "\n";
464     }
465     bca.numConstants++;
466     bca.numValues++;
467   }
468
469   virtual void handleConstantPacked(
470     const PackedType* PT,
471     std::vector<Constant*>& Elements,
472     unsigned TypeSlot,
473     Constant* PackedVal)
474   {
475     if (os) {
476       *os << "      PACKD: ";
477       WriteTypeSymbolic(*os,PT,M);
478       *os << " TypeSlot=" << TypeSlot << "\n";
479       for ( unsigned i = 0; i < Elements.size(); ++i ) {
480         *os << "        #" << i;
481         Elements[i]->print(*os);
482         *os << "\n";
483       }
484       *os << "        Value=";
485       PackedVal->print(*os);
486       *os << "\n";
487     }
488
489     bca.numConstants++;
490     bca.numValues++;
491   }
492
493   virtual void handleConstantPointer( const PointerType* PT,
494       unsigned Slot, GlobalValue* GV ) {
495     if (os) {
496       *os << "       PNTR: ";
497       WriteTypeSymbolic(*os,PT,M);
498       *os << " Slot=" << Slot << " GlobalValue=";
499       GV->print(*os);
500       *os << "\n";
501     }
502     bca.numConstants++;
503     bca.numValues++;
504   }
505
506   virtual void handleConstantString( const ConstantArray* CA ) {
507     if (os) {
508       *os << "      STRNG: ";
509       CA->print(*os);
510       *os << "\n";
511     }
512     bca.numConstants++;
513     bca.numValues++;
514   }
515
516   virtual void handleGlobalConstantsEnd() {
517     if (os)
518       *os << "    } END BLOCK: GlobalConstants\n";
519
520     if (bca.progressiveVerify) {
521       std::string msg;
522       if (verifyModule(*M, ReturnStatusAction, &msg))
523         bca.VerifyInfo += "Verify@EndGlobalConstants: " + msg + "\n";
524     }
525   }
526
527   virtual void handleAlignment(unsigned numBytes) {
528     bca.numAlignment += numBytes;
529   }
530
531   virtual void handleBlock(
532     unsigned BType, const unsigned char* StartPtr, unsigned Size) {
533     bca.numBlocks++;
534     assert(BType >= BytecodeFormat::ModuleBlockID);
535     assert(BType < BytecodeFormat::NumberOfBlockIDs);
536     bca.BlockSizes[
537       llvm::BytecodeFormat::BytecodeBlockIdentifiers(BType)] += Size;
538
539     if (bca.version < 3) // Check for long block headers versions
540       bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 8;
541     else
542       bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 4;
543   }
544
545   virtual void handleVBR32(unsigned Size ) {
546     bca.vbrCount32++;
547     bca.vbrCompBytes += Size;
548     bca.vbrExpdBytes += sizeof(uint32_t);
549     if (currFunc) {
550       currFunc->vbrCount32++;
551       currFunc->vbrCompBytes += Size;
552       currFunc->vbrExpdBytes += sizeof(uint32_t);
553     }
554   }
555
556   virtual void handleVBR64(unsigned Size ) {
557     bca.vbrCount64++;
558     bca.vbrCompBytes += Size;
559     bca.vbrExpdBytes += sizeof(uint64_t);
560     if ( currFunc ) {
561       currFunc->vbrCount64++;
562       currFunc->vbrCompBytes += Size;
563       currFunc->vbrExpdBytes += sizeof(uint64_t);
564     }
565   }
566 };
567
568
569 /// @brief Utility for printing a titled unsigned value with
570 /// an aligned colon.
571 inline static void print(std::ostream& Out, const char*title,
572   unsigned val, bool nl = true ) {
573   Out << std::setw(30) << std::right << title
574       << std::setw(0) << ": "
575       << std::setw(9) << val << "\n";
576 }
577
578 /// @brief Utility for printing a titled double value with an
579 /// aligned colon
580 inline static void print(std::ostream&Out, const char*title,
581   double val ) {
582   Out << std::setw(30) << std::right << title
583       << std::setw(0) << ": "
584       << std::setw(9) << std::setprecision(6) << val << "\n" ;
585 }
586
587 /// @brief Utility for printing a titled double value with a
588 /// percentage and aligned colon.
589 inline static void print(std::ostream&Out, const char*title,
590   double top, double bot ) {
591   Out << std::setw(30) << std::right << title
592       << std::setw(0) << ": "
593       << std::setw(9) << std::setprecision(6) << top
594       << " (" << std::left << std::setw(0) << std::setprecision(4)
595       << (top/bot)*100.0 << "%)\n";
596 }
597
598 /// @brief Utility for printing a titled string value with
599 /// an aligned colon.
600 inline static void print(std::ostream&Out, const char*title,
601   std::string val, bool nl = true) {
602   Out << std::setw(30) << std::right << title
603       << std::setw(0) << ": "
604       << std::left << val << (nl ? "\n" : "");
605 }
606
607 }
608
609 namespace llvm {
610
611 /// This function prints the contents of rhe BytecodeAnalysis structure in
612 /// a human legible form.
613 /// @brief Print BytecodeAnalysis structure to an ostream
614 void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
615 {
616   Out << "\nSummary Analysis Of " << bca.ModuleId << ": \n\n";
617   print(Out, "Bytecode Analysis Of Module",     bca.ModuleId);
618   print(Out, "Bytecode Version Number",         bca.version);
619   print(Out, "File Size",                       bca.byteSize);
620   print(Out, "Module Bytes",
621         double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]),
622         double(bca.byteSize));
623   print(Out, "Function Bytes",
624         double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]),
625         double(bca.byteSize));
626   print(Out, "Global Types Bytes",
627         double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]),
628         double(bca.byteSize));
629   print(Out, "Constant Pool Bytes",
630         double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]),
631         double(bca.byteSize));
632   print(Out, "Module Globals Bytes",
633         double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]),
634         double(bca.byteSize));
635   print(Out, "Instruction List Bytes",
636         double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]),
637         double(bca.byteSize));
638   print(Out, "Value Symbol Table Bytes",
639         double(bca.BlockSizes[BytecodeFormat::ValueSymbolTableBlockID]),
640         double(bca.byteSize));
641   print(Out, "Type Symbol Table Bytes",
642         double(bca.BlockSizes[BytecodeFormat::TypeSymbolTableBlockID]),
643         double(bca.byteSize));
644   print(Out, "Alignment Bytes",
645         double(bca.numAlignment), double(bca.byteSize));
646   print(Out, "Block Header Bytes",
647         double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]),
648         double(bca.byteSize));
649   print(Out, "Dependent Libraries Bytes", double(bca.libSize),
650         double(bca.byteSize));
651   print(Out, "Number Of Bytecode Blocks",       bca.numBlocks);
652   print(Out, "Number Of Functions",             bca.numFunctions);
653   print(Out, "Number Of Types",                 bca.numTypes);
654   print(Out, "Number Of Constants",             bca.numConstants);
655   print(Out, "Number Of Global Variables",      bca.numGlobalVars);
656   print(Out, "Number Of Values",                bca.numValues);
657   print(Out, "Number Of Basic Blocks",          bca.numBasicBlocks);
658   print(Out, "Number Of Instructions",          bca.numInstructions);
659   print(Out, "Number Of Long Instructions",     bca.longInstructions);
660   print(Out, "Number Of Operands",              bca.numOperands);
661   print(Out, "Number Of Compaction Tables",     bca.numCmpctnTables);
662   print(Out, "Number Of Symbol Tables",         bca.numSymTab);
663   print(Out, "Number Of Dependent Libs",        bca.numLibraries);
664   print(Out, "Total Instruction Size",          bca.instructionSize);
665   print(Out, "Average Instruction Size",
666         double(bca.instructionSize)/double(bca.numInstructions));
667
668   print(Out, "Maximum Type Slot Number",        bca.maxTypeSlot);
669   print(Out, "Maximum Value Slot Number",       bca.maxValueSlot);
670   print(Out, "Bytes Per Value ",                bca.fileDensity);
671   print(Out, "Bytes Per Global",                bca.globalsDensity);
672   print(Out, "Bytes Per Function",              bca.functionDensity);
673   print(Out, "# of VBR 32-bit Integers",   bca.vbrCount32);
674   print(Out, "# of VBR 64-bit Integers",   bca.vbrCount64);
675   print(Out, "# of VBR Compressed Bytes",  bca.vbrCompBytes);
676   print(Out, "# of VBR Expanded Bytes",    bca.vbrExpdBytes);
677   print(Out, "Bytes Saved With VBR",
678         double(bca.vbrExpdBytes)-double(bca.vbrCompBytes),
679         double(bca.vbrExpdBytes));
680
681   if (bca.detailedResults) {
682     Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n";
683
684     std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
685       bca.FunctionInfo.begin();
686     std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
687       bca.FunctionInfo.end();
688
689     while ( I != E ) {
690       Out << std::left << std::setw(0) << "\n";
691       if (I->second.numBasicBlocks == 0) Out << "External ";
692       Out << "Function: " << I->second.name << "\n";
693       print(Out, "Type:", I->second.description);
694       print(Out, "Byte Size", I->second.byteSize);
695       if (I->second.numBasicBlocks) {
696         print(Out, "Basic Blocks", I->second.numBasicBlocks);
697         print(Out, "Instructions", I->second.numInstructions);
698         print(Out, "Long Instructions", I->second.longInstructions);
699         print(Out, "Operands", I->second.numOperands);
700         print(Out, "Instruction Size", I->second.instructionSize);
701         print(Out, "Average Instruction Size",
702               double(I->second.instructionSize) / I->second.numInstructions);
703         print(Out, "Bytes Per Instruction", I->second.density);
704         print(Out, "# of VBR 32-bit Integers",   I->second.vbrCount32);
705         print(Out, "# of VBR 64-bit Integers",   I->second.vbrCount64);
706         print(Out, "# of VBR Compressed Bytes",  I->second.vbrCompBytes);
707         print(Out, "# of VBR Expanded Bytes",    I->second.vbrExpdBytes);
708         print(Out, "Bytes Saved With VBR",
709               double(I->second.vbrExpdBytes) - I->second.vbrCompBytes);
710       }
711       ++I;
712     }
713   }
714
715   if ( bca.progressiveVerify )
716     Out << bca.VerifyInfo;
717 }
718
719 BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca,
720                                                std::ostream* output)
721 {
722   return new AnalyzerHandler(bca,output);
723 }
724
725 }
726