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