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