1 //===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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
17 //===----------------------------------------------------------------------===//
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"
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
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
48 AnalyzerHandler(BytecodeAnalysis
& TheBca
, std::ostream
* output
)
55 /// @name BytecodeHandler Implementations
58 virtual void handleError(const std::string
& str
) {
60 *os
<< "ERROR: " << str
<< "\n";
63 virtual void handleStart( Module
* Mod
, unsigned theSize
) {
66 *os
<< "Bytecode {\n";
67 bca
.byteSize
= theSize
;
74 bca
.numGlobalVars
= 0;
75 bca
.numInstructions
= 0;
76 bca
.numBasicBlocks
= 0;
78 bca
.numCmpctnTables
= 0;
85 bca
.fileDensity
= 0.0;
86 bca
.globalsDensity
= 0.0;
87 bca
.functionDensity
= 0.0;
88 bca
.instructionSize
= 0;
89 bca
.longInstructions
= 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;
106 virtual void handleFinish() {
108 *os
<< "} End Bytecode\n";
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
+
117 bca
.functionDensity
= double(bca
.BlockSizes
[BytecodeFormat::FunctionBlockID
]) /
118 double(bca
.numFunctions
);
120 if ( bca
.progressiveVerify
) {
122 verifyModule(*M
, ThrowExceptionAction
);
123 } catch ( std::string
& msg
) {
124 bca
.VerifyInfo
+= "Verify@Finish: " + msg
+ "\n";
129 virtual void handleModuleBegin(const std::string
& id
) {
131 *os
<< " Module " << id
<< " {\n";
135 virtual void handleModuleEnd(const std::string
& id
) {
137 *os
<< " } End Module " << id
<< "\n";
138 if ( bca
.progressiveVerify
) {
140 verifyModule(*M
, ThrowExceptionAction
);
141 } catch ( std::string
& msg
) {
142 bca
.VerifyInfo
+= "Verify@EndModule: " + msg
+ "\n";
147 virtual void handleVersionInfo(
148 unsigned char RevisionNum
, ///< Byte code revision number
149 Module::Endianness Endianness
, ///< Endianness indicator
150 Module::PointerSize PointerSize
///< PointerSize indicator
153 *os
<< " RevisionNum: " << int(RevisionNum
)
154 << " Endianness: " << Endianness
155 << " PointerSize: " << PointerSize
<< "\n";
156 bca
.version
= RevisionNum
;
159 virtual void handleModuleGlobalsBegin() {
161 *os
<< " BLOCK: ModuleGlobalInfo {\n";
164 virtual void handleGlobalVariable(
165 const Type
* ElemType
,
167 GlobalValue::LinkageTypes Linkage
,
173 << ( initSlot
== 0 ? "Uni" : "I" ) << "nitialized, "
174 << ( isConstant
? "Constant, " : "Variable, ")
175 << " Linkage=" << Linkage
<< " Type=";
176 WriteTypeSymbolic(*os
, ElemType
, M
);
177 *os
<< " Slot=" << SlotNum
<< " InitSlot=" << initSlot
183 if (SlotNum
> bca
.maxValueSlot
)
184 bca
.maxValueSlot
= SlotNum
;
185 if (initSlot
> bca
.maxValueSlot
)
186 bca
.maxValueSlot
= initSlot
;
190 virtual void handleTypeList(unsigned numEntries
) {
191 bca
.maxTypeSlot
= numEntries
- 1;
194 virtual void handleType( const Type
* Ty
) {
198 WriteTypeSymbolic(*os
,Ty
,M
);
203 virtual void handleFunctionDeclaration(
204 Function
* Func
///< The function
209 *os
<< " Function Decl: ";
210 WriteTypeSymbolic(*os
,Func
->getType(),M
);
215 virtual void handleGlobalInitializer(GlobalVariable
* GV
, Constant
* CV
) {
217 *os
<< " Initializer: GV=";
225 virtual void handleDependentLibrary(const std::string
& libName
) {
227 bca
.libSize
+= libName
.size() + (libName
.size() < 128 ? 1 : 2);
229 *os
<< " Library: '" << libName
<< "'\n";
232 virtual void handleModuleGlobalsEnd() {
234 *os
<< " } END BLOCK: ModuleGlobalInfo\n";
235 if ( bca
.progressiveVerify
) {
237 verifyModule(*M
, ThrowExceptionAction
);
238 } catch ( std::string
& msg
) {
239 bca
.VerifyInfo
+= "Verify@EndModuleGlobalInfo: " + msg
+ "\n";
244 virtual void handleCompactionTableBegin() {
246 *os
<< " BLOCK: CompactionTable {\n";
247 bca
.numCmpctnTables
++;
250 virtual void handleCompactionTablePlane( unsigned Ty
, unsigned NumEntries
) {
252 *os
<< " Plane: Ty=" << Ty
<< " Size=" << NumEntries
<< "\n";
255 virtual void handleCompactionTableType( unsigned i
, unsigned TypSlot
,
258 *os
<< " Type: " << i
<< " Slot:" << TypSlot
<< " is ";
259 WriteTypeSymbolic(*os
,Ty
,M
);
264 virtual void handleCompactionTableValue(unsigned i
, unsigned TypSlot
,
267 *os
<< " Value: " << i
<< " TypSlot: " << TypSlot
268 << " ValSlot:" << ValSlot
<< "\n";
269 if (ValSlot
> bca
.maxValueSlot
)
270 bca
.maxValueSlot
= ValSlot
;
273 virtual void handleCompactionTableEnd() {
275 *os
<< " } END BLOCK: CompactionTable\n";
278 virtual void handleSymbolTableBegin(Function
* CF
, SymbolTable
* ST
) {
281 *os
<< " BLOCK: SymbolTable {\n";
284 virtual void handleSymbolTablePlane(unsigned Ty
, unsigned NumEntries
,
287 *os
<< " Plane: Ty=" << Ty
<< " Size=" << NumEntries
<< " Type: ";
288 WriteTypeSymbolic(*os
,Typ
,M
);
293 virtual void handleSymbolTableType(unsigned i
, unsigned TypSlot
,
294 const std::string
& name
) {
296 *os
<< " Type " << i
<< " Slot=" << TypSlot
297 << " Name: " << name
<< "\n";
300 virtual void handleSymbolTableValue(unsigned i
, unsigned ValSlot
,
301 const std::string
& name
) {
303 *os
<< " Value " << i
<< " Slot=" << ValSlot
304 << " Name: " << name
<< "\n";
305 if (ValSlot
> bca
.maxValueSlot
)
306 bca
.maxValueSlot
= ValSlot
;
309 virtual void handleSymbolTableEnd() {
311 *os
<< " } END BLOCK: SymbolTable\n";
314 virtual void handleFunctionBegin(Function
* Func
, unsigned Size
) {
316 *os
<< " BLOCK: Function {\n"
317 << " Linkage: " << Func
->getLinkage() << "\n"
319 WriteTypeSymbolic(*os
,Func
->getType(),M
);
323 currFunc
= &bca
.FunctionInfo
[Func
];
324 std::ostringstream tmp
;
325 WriteTypeSymbolic(tmp
,Func
->getType(),M
);
326 currFunc
->description
= tmp
.str();
327 currFunc
->name
= Func
->getName();
328 currFunc
->byteSize
= Size
;
329 currFunc
->numInstructions
= 0;
330 currFunc
->numBasicBlocks
= 0;
331 currFunc
->numPhis
= 0;
332 currFunc
->numOperands
= 0;
333 currFunc
->density
= 0.0;
334 currFunc
->instructionSize
= 0;
335 currFunc
->longInstructions
= 0;
336 currFunc
->vbrCount32
= 0;
337 currFunc
->vbrCount64
= 0;
338 currFunc
->vbrCompBytes
= 0;
339 currFunc
->vbrExpdBytes
= 0;
343 virtual void handleFunctionEnd( Function
* Func
) {
345 *os
<< " } END BLOCK: Function\n";
346 currFunc
->density
= double(currFunc
->byteSize
) /
347 double(currFunc
->numInstructions
);
349 if ( bca
.progressiveVerify
) {
351 verifyModule(*M
, ThrowExceptionAction
);
352 } catch ( std::string
& msg
) {
353 bca
.VerifyInfo
+= "Verify@EndFunction: " + msg
+ "\n";
358 virtual void handleBasicBlockBegin( unsigned blocknum
) {
360 *os
<< " BLOCK: BasicBlock #" << blocknum
<< "{\n";
361 bca
.numBasicBlocks
++;
363 if ( currFunc
) currFunc
->numBasicBlocks
++;
366 virtual bool handleInstruction( unsigned Opcode
, const Type
* iType
,
367 std::vector
<unsigned>& Operands
, unsigned Size
){
369 *os
<< " INST: OpCode="
370 << Instruction::getOpcodeName(Opcode
) << " Type=\"";
371 WriteTypeSymbolic(*os
,iType
,M
);
373 for ( unsigned i
= 0; i
< Operands
.size(); ++i
)
374 *os
<< " Op(" << i
<< ")=Slot(" << Operands
[i
] << ")";
378 bca
.numInstructions
++;
380 bca
.instructionSize
+= Size
;
381 if (Size
> 4 ) bca
.longInstructions
++;
382 bca
.numOperands
+= Operands
.size();
383 for (unsigned i
= 0; i
< Operands
.size(); ++i
)
384 if (Operands
[i
] > bca
.maxValueSlot
)
385 bca
.maxValueSlot
= Operands
[i
];
387 currFunc
->numInstructions
++;
388 currFunc
->instructionSize
+= Size
;
389 if (Size
> 4 ) currFunc
->longInstructions
++;
390 if ( Opcode
== Instruction::PHI
) currFunc
->numPhis
++;
392 return Instruction::isTerminator(Opcode
);
395 virtual void handleBasicBlockEnd(unsigned blocknum
) {
397 *os
<< " } END BLOCK: BasicBlock #" << blocknum
<< "{\n";
400 virtual void handleGlobalConstantsBegin() {
402 *os
<< " BLOCK: GlobalConstants {\n";
405 virtual void handleConstantExpression( unsigned Opcode
,
406 std::vector
<Constant
*> ArgVec
, Constant
* C
) {
408 *os
<< " EXPR: " << Instruction::getOpcodeName(Opcode
) << "\n";
409 for ( unsigned i
= 0; i
< ArgVec
.size(); ++i
) {
410 *os
<< " Arg#" << i
<< " "; ArgVec
[i
]->print(*os
);
421 virtual void handleConstantValue( Constant
* c
) {
431 virtual void handleConstantArray( const ArrayType
* AT
,
432 std::vector
<Constant
*>& Elements
,
434 Constant
* ArrayVal
) {
437 WriteTypeSymbolic(*os
,AT
,M
);
438 *os
<< " TypeSlot=" << TypeSlot
<< "\n";
439 for ( unsigned i
= 0; i
< Elements
.size(); ++i
) {
441 Elements
[i
]->print(*os
);
445 ArrayVal
->print(*os
);
453 virtual void handleConstantStruct(
454 const StructType
* ST
,
455 std::vector
<Constant
*>& Elements
,
460 WriteTypeSymbolic(*os
,ST
,M
);
462 for ( unsigned i
= 0; i
< Elements
.size(); ++i
) {
463 *os
<< " #" << i
<< " "; Elements
[i
]->print(*os
);
467 StructVal
->print(*os
);
474 virtual void handleConstantPacked(
475 const PackedType
* PT
,
476 std::vector
<Constant
*>& Elements
,
482 WriteTypeSymbolic(*os
,PT
,M
);
483 *os
<< " TypeSlot=" << TypeSlot
<< "\n";
484 for ( unsigned i
= 0; i
< Elements
.size(); ++i
) {
486 Elements
[i
]->print(*os
);
490 PackedVal
->print(*os
);
498 virtual void handleConstantPointer( const PointerType
* PT
,
499 unsigned Slot
, GlobalValue
* GV
) {
502 WriteTypeSymbolic(*os
,PT
,M
);
503 *os
<< " Slot=" << Slot
<< " GlobalValue=";
511 virtual void handleConstantString( const ConstantArray
* CA
) {
521 virtual void handleGlobalConstantsEnd() {
523 *os
<< " } END BLOCK: GlobalConstants\n";
525 if ( bca
.progressiveVerify
) {
527 verifyModule(*M
, ThrowExceptionAction
);
528 } catch ( std::string
& msg
) {
529 bca
.VerifyInfo
+= "Verify@EndGlobalConstants: " + msg
+ "\n";
534 virtual void handleAlignment(unsigned numBytes
) {
535 bca
.numAlignment
+= numBytes
;
538 virtual void handleBlock(
539 unsigned BType
, const unsigned char* StartPtr
, unsigned Size
) {
541 assert(BType
>= BytecodeFormat::ModuleBlockID
);
542 assert(BType
< BytecodeFormat::NumberOfBlockIDs
);
544 llvm::BytecodeFormat::CompressedBytecodeBlockIdentifiers(BType
)] += Size
;
546 if (bca
.version
< 3) // Check for long block headers versions
547 bca
.BlockSizes
[llvm::BytecodeFormat::Reserved_DoNotUse
] += 8;
549 bca
.BlockSizes
[llvm::BytecodeFormat::Reserved_DoNotUse
] += 4;
552 virtual void handleVBR32(unsigned Size
) {
554 bca
.vbrCompBytes
+= Size
;
555 bca
.vbrExpdBytes
+= sizeof(uint32_t);
557 currFunc
->vbrCount32
++;
558 currFunc
->vbrCompBytes
+= Size
;
559 currFunc
->vbrExpdBytes
+= sizeof(uint32_t);
563 virtual void handleVBR64(unsigned Size
) {
565 bca
.vbrCompBytes
+= Size
;
566 bca
.vbrExpdBytes
+= sizeof(uint64_t);
568 currFunc
->vbrCount64
++;
569 currFunc
->vbrCompBytes
+= Size
;
570 currFunc
->vbrExpdBytes
+= sizeof(uint64_t);
576 /// @brief Utility for printing a titled unsigned value with
577 /// an aligned colon.
578 inline static void print(std::ostream
& Out
, const char*title
,
579 unsigned val
, bool nl
= true ) {
580 Out
<< std::setw(30) << std::right
<< title
581 << std::setw(0) << ": "
582 << std::setw(9) << val
<< "\n";
585 /// @brief Utility for printing a titled double value with an
587 inline static void print(std::ostream
&Out
, const char*title
,
589 Out
<< std::setw(30) << std::right
<< title
590 << std::setw(0) << ": "
591 << std::setw(9) << std::setprecision(6) << val
<< "\n" ;
594 /// @brief Utility for printing a titled double value with a
595 /// percentage and aligned colon.
596 inline static void print(std::ostream
&Out
, const char*title
,
597 double top
, double bot
) {
598 Out
<< std::setw(30) << std::right
<< title
599 << std::setw(0) << ": "
600 << std::setw(9) << std::setprecision(6) << top
601 << " (" << std::left
<< std::setw(0) << std::setprecision(4)
602 << (top
/bot
)*100.0 << "%)\n";
605 /// @brief Utility for printing a titled string value with
606 /// an aligned colon.
607 inline static void print(std::ostream
&Out
, const char*title
,
608 std::string val
, bool nl
= true) {
609 Out
<< std::setw(30) << std::right
<< title
610 << std::setw(0) << ": "
611 << std::left
<< val
<< (nl
? "\n" : "");
618 /// This function prints the contents of rhe BytecodeAnalysis structure in
619 /// a human legible form.
620 /// @brief Print BytecodeAnalysis structure to an ostream
621 void PrintBytecodeAnalysis(BytecodeAnalysis
& bca
, std::ostream
& Out
)
623 Out
<< "\nSummary Analysis Of " << bca
.ModuleId
<< ": \n\n";
624 print(Out
, "Bytecode Analysis Of Module", bca
.ModuleId
);
625 print(Out
, "Bytecode Version Number", bca
.version
);
626 print(Out
, "File Size", bca
.byteSize
);
627 print(Out
, "Module Bytes",
628 double(bca
.BlockSizes
[BytecodeFormat::ModuleBlockID
]),
629 double(bca
.byteSize
));
630 print(Out
, "Function Bytes",
631 double(bca
.BlockSizes
[BytecodeFormat::FunctionBlockID
]),
632 double(bca
.byteSize
));
633 print(Out
, "Global Types Bytes",
634 double(bca
.BlockSizes
[BytecodeFormat::GlobalTypePlaneBlockID
]),
635 double(bca
.byteSize
));
636 print(Out
, "Constant Pool Bytes",
637 double(bca
.BlockSizes
[BytecodeFormat::ConstantPoolBlockID
]),
638 double(bca
.byteSize
));
639 print(Out
, "Module Globals Bytes",
640 double(bca
.BlockSizes
[BytecodeFormat::ModuleGlobalInfoBlockID
]),
641 double(bca
.byteSize
));
642 print(Out
, "Instruction List Bytes",
643 double(bca
.BlockSizes
[BytecodeFormat::InstructionListBlockID
]),
644 double(bca
.byteSize
));
645 print(Out
, "Compaction Table Bytes",
646 double(bca
.BlockSizes
[BytecodeFormat::CompactionTableBlockID
]),
647 double(bca
.byteSize
));
648 print(Out
, "Symbol Table Bytes",
649 double(bca
.BlockSizes
[BytecodeFormat::SymbolTableBlockID
]),
650 double(bca
.byteSize
));
651 print(Out
, "Alignment Bytes",
652 double(bca
.numAlignment
), double(bca
.byteSize
));
653 print(Out
, "Block Header Bytes",
654 double(bca
.BlockSizes
[BytecodeFormat::Reserved_DoNotUse
]),
655 double(bca
.byteSize
));
656 print(Out
, "Dependent Libraries Bytes", double(bca
.libSize
),
657 double(bca
.byteSize
));
658 print(Out
, "Number Of Bytecode Blocks", bca
.numBlocks
);
659 print(Out
, "Number Of Functions", bca
.numFunctions
);
660 print(Out
, "Number Of Types", bca
.numTypes
);
661 print(Out
, "Number Of Constants", bca
.numConstants
);
662 print(Out
, "Number Of Global Variables", bca
.numGlobalVars
);
663 print(Out
, "Number Of Values", bca
.numValues
);
664 print(Out
, "Number Of Basic Blocks", bca
.numBasicBlocks
);
665 print(Out
, "Number Of Instructions", bca
.numInstructions
);
666 print(Out
, "Number Of Long Instructions", bca
.longInstructions
);
667 print(Out
, "Number Of Operands", bca
.numOperands
);
668 print(Out
, "Number Of Compaction Tables", bca
.numCmpctnTables
);
669 print(Out
, "Number Of Symbol Tables", bca
.numSymTab
);
670 print(Out
, "Number Of Dependent Libs", bca
.numLibraries
);
671 print(Out
, "Total Instruction Size", bca
.instructionSize
);
672 print(Out
, "Average Instruction Size",
673 double(bca
.instructionSize
)/double(bca
.numInstructions
));
675 print(Out
, "Maximum Type Slot Number", bca
.maxTypeSlot
);
676 print(Out
, "Maximum Value Slot Number", bca
.maxValueSlot
);
677 print(Out
, "Bytes Per Value ", bca
.fileDensity
);
678 print(Out
, "Bytes Per Global", bca
.globalsDensity
);
679 print(Out
, "Bytes Per Function", bca
.functionDensity
);
680 print(Out
, "# of VBR 32-bit Integers", bca
.vbrCount32
);
681 print(Out
, "# of VBR 64-bit Integers", bca
.vbrCount64
);
682 print(Out
, "# of VBR Compressed Bytes", bca
.vbrCompBytes
);
683 print(Out
, "# of VBR Expanded Bytes", bca
.vbrExpdBytes
);
684 print(Out
, "Bytes Saved With VBR",
685 double(bca
.vbrExpdBytes
)-double(bca
.vbrCompBytes
),
686 double(bca
.vbrExpdBytes
));
688 if (bca
.detailedResults
) {
689 Out
<< "\nDetailed Analysis Of " << bca
.ModuleId
<< " Functions:\n";
691 std::map
<const Function
*,BytecodeAnalysis::BytecodeFunctionInfo
>::iterator I
=
692 bca
.FunctionInfo
.begin();
693 std::map
<const Function
*,BytecodeAnalysis::BytecodeFunctionInfo
>::iterator E
=
694 bca
.FunctionInfo
.end();
697 Out
<< std::left
<< std::setw(0) << "\n";
698 if (I
->second
.numBasicBlocks
== 0) Out
<< "External ";
699 Out
<< "Function: " << I
->second
.name
<< "\n";
700 print(Out
, "Type:", I
->second
.description
);
701 print(Out
, "Byte Size", I
->second
.byteSize
);
702 if (I
->second
.numBasicBlocks
) {
703 print(Out
, "Basic Blocks", I
->second
.numBasicBlocks
);
704 print(Out
, "Instructions", I
->second
.numInstructions
);
705 print(Out
, "Long Instructions", I
->second
.longInstructions
);
706 print(Out
, "Operands", I
->second
.numOperands
);
707 print(Out
, "Instruction Size", I
->second
.instructionSize
);
708 print(Out
, "Average Instruction Size",
709 double(I
->second
.instructionSize
) / I
->second
.numInstructions
);
710 print(Out
, "Bytes Per Instruction", I
->second
.density
);
711 print(Out
, "# of VBR 32-bit Integers", I
->second
.vbrCount32
);
712 print(Out
, "# of VBR 64-bit Integers", I
->second
.vbrCount64
);
713 print(Out
, "# of VBR Compressed Bytes", I
->second
.vbrCompBytes
);
714 print(Out
, "# of VBR Expanded Bytes", I
->second
.vbrExpdBytes
);
715 print(Out
, "Bytes Saved With VBR",
716 double(I
->second
.vbrExpdBytes
) - I
->second
.vbrCompBytes
),
717 double(I
->second
.vbrExpdBytes
);
723 if ( bca
.progressiveVerify
)
724 Out
<< bca
.VerifyInfo
;
727 BytecodeHandler
* createBytecodeAnalyzerHandler(BytecodeAnalysis
& bca
,
728 std::ostream
* output
)
730 return new AnalyzerHandler(bca
,output
);