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