blob: 3500ed09ea04bfa0ef752fcd0c2fbf6edae09c8e [file] [log] [blame]
Reid Spencerdac69c82004-06-07 17:53:43 +00001//===-- BytecodeHandler.cpp - Parsing Handler -------------------*- 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 header file defines the BytecodeHandler class that gets called by the
11// AbstractBytecodeParser when parsing events occur.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AnalyzerInternals.h"
Reid Spencer649ee572004-06-09 06:16:43 +000016#include <iostream>
Reid Spencerdac69c82004-06-07 17:53:43 +000017
18using namespace llvm;
19
20
21namespace {
22
23class AnalyzerHandler : public BytecodeHandler {
Reid Spencer649ee572004-06-09 06:16:43 +000024 BytecodeAnalysis& bca;
Reid Spencercbb22e22004-06-10 22:00:54 +000025 BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
Reid Spencerdac69c82004-06-07 17:53:43 +000026public:
Reid Spencer649ee572004-06-09 06:16:43 +000027 AnalyzerHandler(BytecodeAnalysis& TheBca)
Reid Spencercbb22e22004-06-10 22:00:54 +000028 : bca(TheBca)
29 , currFunc(0)
30 { }
Reid Spencer649ee572004-06-09 06:16:43 +000031
Reid Spencercbb22e22004-06-10 22:00:54 +000032 virtual bool handleError(const std::string& str ) {
Reid Spencerdac69c82004-06-07 17:53:43 +000033 return false;
34 }
35
Reid Spencercbb22e22004-06-10 22:00:54 +000036 virtual void handleStart() {
Reid Spencer649ee572004-06-09 06:16:43 +000037 bca.ModuleId.clear();
Reid Spencer00c28a72004-06-10 08:09:13 +000038 bca.numBlocks = 0;
Reid Spencer649ee572004-06-09 06:16:43 +000039 bca.numTypes = 0;
40 bca.numValues = 0;
41 bca.numFunctions = 0;
42 bca.numConstants = 0;
43 bca.numGlobalVars = 0;
44 bca.numInstructions = 0;
45 bca.numBasicBlocks = 0;
46 bca.numOperands = 0;
47 bca.numCmpctnTables = 0;
48 bca.numSymTab = 0;
49 bca.maxTypeSlot = 0;
50 bca.maxValueSlot = 0;
Reid Spencer00c28a72004-06-10 08:09:13 +000051 bca.numAlignment = 0;
52 bca.fileDensity = 0.0;
53 bca.globalsDensity = 0.0;
54 bca.functionDensity = 0.0;
55 bca.vbrCount32 = 0;
56 bca.vbrCount64 = 0;
57 bca.vbrCompBytes = 0;
58 bca.vbrExpdBytes = 0;
Reid Spencer649ee572004-06-09 06:16:43 +000059 bca.FunctionInfo.clear();
60 bca.BytecodeDump.clear();
Reid Spencer00c28a72004-06-10 08:09:13 +000061 bca.BlockSizes[BytecodeFormat::Module] = 0;
62 bca.BlockSizes[BytecodeFormat::Function] = 0;
63 bca.BlockSizes[BytecodeFormat::ConstantPool] = 0;
64 bca.BlockSizes[BytecodeFormat::SymbolTable] = 0;
65 bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo] = 0;
66 bca.BlockSizes[BytecodeFormat::GlobalTypePlane] = 0;
67 bca.BlockSizes[BytecodeFormat::BasicBlock] = 0;
68 bca.BlockSizes[BytecodeFormat::InstructionList] = 0;
69 bca.BlockSizes[BytecodeFormat::CompactionTable] = 0;
Reid Spencerdac69c82004-06-07 17:53:43 +000070 }
71
Reid Spencercbb22e22004-06-10 22:00:54 +000072 virtual void handleFinish() {
Reid Spencer00c28a72004-06-10 08:09:13 +000073 bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
74 double globalSize = 0.0;
75 globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPool]);
76 globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]);
77 globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]);
78 bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
79 bca.numGlobalVars );
80 bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::Function]) /
81 double(bca.numFunctions);
Reid Spencerdac69c82004-06-07 17:53:43 +000082 }
83
Reid Spencercbb22e22004-06-10 22:00:54 +000084 virtual void handleModuleBegin(const std::string& id) {
Reid Spencer649ee572004-06-09 06:16:43 +000085 bca.ModuleId = id;
Reid Spencerdac69c82004-06-07 17:53:43 +000086 }
87
Reid Spencercbb22e22004-06-10 22:00:54 +000088 virtual void handleModuleEnd(const std::string& id) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000089
Reid Spencercbb22e22004-06-10 22:00:54 +000090 virtual void handleVersionInfo(
Reid Spencerdac69c82004-06-07 17:53:43 +000091 unsigned char RevisionNum, ///< Byte code revision number
92 Module::Endianness Endianness, ///< Endianness indicator
93 Module::PointerSize PointerSize ///< PointerSize indicator
Reid Spencercbb22e22004-06-10 22:00:54 +000094 ) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000095
Reid Spencercbb22e22004-06-10 22:00:54 +000096 virtual void handleModuleGlobalsBegin(unsigned size) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000097
Reid Spencercbb22e22004-06-10 22:00:54 +000098 virtual void handleGlobalVariable(
Reid Spencerdac69c82004-06-07 17:53:43 +000099 const Type* ElemType, ///< The type of the global variable
100 bool isConstant, ///< Whether the GV is constant or not
101 GlobalValue::LinkageTypes ///< The linkage type of the GV
Reid Spencercbb22e22004-06-10 22:00:54 +0000102 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000103 bca.numGlobalVars++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000104 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000105 }
106
Reid Spencercbb22e22004-06-10 22:00:54 +0000107 virtual void handleInitializedGV(
Reid Spencerdac69c82004-06-07 17:53:43 +0000108 const Type* ElemType, ///< The type of the global variable
109 bool isConstant, ///< Whether the GV is constant or not
110 GlobalValue::LinkageTypes,///< The linkage type of the GV
111 unsigned initSlot ///< Slot number of GV's initializer
Reid Spencercbb22e22004-06-10 22:00:54 +0000112 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000113 bca.numGlobalVars++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000114 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000115 }
116
Reid Spencercbb22e22004-06-10 22:00:54 +0000117 virtual void handleType( const Type* Ty ) { bca.numTypes++; }
Reid Spencerdac69c82004-06-07 17:53:43 +0000118
Reid Spencercbb22e22004-06-10 22:00:54 +0000119 virtual void handleFunctionDeclaration(
120 Function* Func, ///< The function
121 const FunctionType* FuncType ///< The type of the function
122 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000123 bca.numFunctions++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000124 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000125 }
126
Reid Spencercbb22e22004-06-10 22:00:54 +0000127 virtual void handleModuleGlobalsEnd() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000128
Reid Spencercbb22e22004-06-10 22:00:54 +0000129 virtual void handleCompactionTableBegin() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000130
Reid Spencercbb22e22004-06-10 22:00:54 +0000131 virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) {
Reid Spencer649ee572004-06-09 06:16:43 +0000132 bca.numCmpctnTables++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000133 }
134
Reid Spencercbb22e22004-06-10 22:00:54 +0000135 virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
136 const Type* ) {}
Reid Spencerdac69c82004-06-07 17:53:43 +0000137
Reid Spencercbb22e22004-06-10 22:00:54 +0000138 virtual void handleCompactionTableValue(
Reid Spencerdac69c82004-06-07 17:53:43 +0000139 unsigned i,
140 unsigned ValSlot,
Reid Spencercbb22e22004-06-10 22:00:54 +0000141 const Type* ) { }
142
143 virtual void handleCompactionTableEnd() { }
144
145 virtual void handleSymbolTableBegin() { bca.numSymTab++; }
146
147 virtual void handleSymbolTablePlane( unsigned Ty, unsigned NumEntries,
148 const Type* Typ) { }
149
150 virtual void handleSymbolTableType( unsigned i, unsigned slot,
151 const std::string& name ) { }
152
153 virtual void handleSymbolTableValue( unsigned i, unsigned slot,
154 const std::string& name ) { }
155
156 virtual void handleSymbolTableEnd() { }
157
158 virtual void handleFunctionBegin( Function* Func, unsigned Size) {
159 const FunctionType* FType =
160 cast<FunctionType>(Func->getType()->getElementType());
161 currFunc = &bca.FunctionInfo[Func];
162 currFunc->description = FType->getDescription();
163 currFunc->name = Func->getName();
164 currFunc->byteSize = Size;
165 currFunc->numInstructions = 0;
166 currFunc->numBasicBlocks = 0;
167 currFunc->numPhis = 0;
168 currFunc->numOperands = 0;
169 currFunc->density = 0.0;
170 currFunc->vbrCount32 = 0;
171 currFunc->vbrCount64 = 0;
172 currFunc->vbrCompBytes = 0;
173 currFunc->vbrExpdBytes = 0;
Reid Spencerdac69c82004-06-07 17:53:43 +0000174 }
175
Reid Spencercbb22e22004-06-10 22:00:54 +0000176 virtual void handleFunctionEnd( Function* Func) {
177 currFunc->density = double(currFunc->byteSize) /
178 double(currFunc->numInstructions+currFunc->numBasicBlocks);
Reid Spencerdac69c82004-06-07 17:53:43 +0000179 }
180
Reid Spencercbb22e22004-06-10 22:00:54 +0000181 virtual void handleBasicBlockBegin( unsigned blocknum) {
Reid Spencer649ee572004-06-09 06:16:43 +0000182 bca.numBasicBlocks++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000183 bca.numValues++;
Reid Spencercbb22e22004-06-10 22:00:54 +0000184 if ( currFunc ) currFunc->numBasicBlocks++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000185 }
186
Reid Spencercbb22e22004-06-10 22:00:54 +0000187 virtual bool handleInstruction( unsigned Opcode, const Type* iType,
188 std::vector<unsigned>& Operands, unsigned Size) {
Reid Spencer649ee572004-06-09 06:16:43 +0000189 bca.numInstructions++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000190 bca.numValues++;
191 bca.numOperands += Operands.size();
Reid Spencercbb22e22004-06-10 22:00:54 +0000192 if ( currFunc ) {
193 currFunc->numInstructions++;
194 if ( Instruction::isPhiNode(Opcode) ) currFunc->numPhis++;
195 }
Reid Spencer649ee572004-06-09 06:16:43 +0000196 return Instruction::isTerminator(Opcode);
Reid Spencerdac69c82004-06-07 17:53:43 +0000197 }
198
Reid Spencercbb22e22004-06-10 22:00:54 +0000199 virtual void handleBasicBlockEnd(unsigned blocknum) { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000200
Reid Spencercbb22e22004-06-10 22:00:54 +0000201 virtual void handleGlobalConstantsBegin() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000202
Reid Spencercbb22e22004-06-10 22:00:54 +0000203 virtual void handleConstantExpression( unsigned Opcode, const Type* Typ,
204 std::vector<std::pair<const Type*,unsigned> > ArgVec ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000205 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000206 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000207 }
208
Reid Spencercbb22e22004-06-10 22:00:54 +0000209 virtual void handleConstantValue( Constant * c ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000210 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000211 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000212 }
213
Reid Spencercbb22e22004-06-10 22:00:54 +0000214 virtual void handleConstantArray( const ArrayType* AT,
215 std::vector<unsigned>& Elements ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000216 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000217 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000218 }
219
Reid Spencercbb22e22004-06-10 22:00:54 +0000220 virtual void handleConstantStruct(
Reid Spencer00c28a72004-06-10 08:09:13 +0000221 const StructType* ST,
222 std::vector<unsigned>& ElementSlots)
Reid Spencerdac69c82004-06-07 17:53:43 +0000223 {
Reid Spencer649ee572004-06-09 06:16:43 +0000224 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000225 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000226 }
227
Reid Spencercbb22e22004-06-10 22:00:54 +0000228 virtual void handleConstantPointer( const PointerType* PT, unsigned Slot) {
Reid Spencer649ee572004-06-09 06:16:43 +0000229 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000230 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000231 }
232
Reid Spencercbb22e22004-06-10 22:00:54 +0000233 virtual void handleConstantString( const ConstantArray* CA ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000234 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000235 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000236 }
237
Reid Spencercbb22e22004-06-10 22:00:54 +0000238 virtual void handleGlobalConstantsEnd() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000239
Reid Spencercbb22e22004-06-10 22:00:54 +0000240 virtual void handleAlignment(unsigned numBytes) {
Reid Spencer00c28a72004-06-10 08:09:13 +0000241 bca.numAlignment += numBytes;
Reid Spencerdac69c82004-06-07 17:53:43 +0000242 }
243
Reid Spencercbb22e22004-06-10 22:00:54 +0000244 virtual void handleBlock(
Reid Spencer00c28a72004-06-10 08:09:13 +0000245 unsigned BType, const unsigned char* StartPtr, unsigned Size) {
246 bca.numBlocks++;
247 bca.BlockSizes[llvm::BytecodeFormat::FileBlockIDs(BType)] += Size;
248 }
249
250 virtual void handleVBR32(unsigned Size ) {
251 bca.vbrCount32++;
252 bca.vbrCompBytes += Size;
253 bca.vbrExpdBytes += sizeof(uint32_t);
Reid Spencercbb22e22004-06-10 22:00:54 +0000254 if (currFunc) {
255 currFunc->vbrCount32++;
256 currFunc->vbrCompBytes += Size;
257 currFunc->vbrExpdBytes += sizeof(uint32_t);
258 }
Reid Spencer00c28a72004-06-10 08:09:13 +0000259 }
Reid Spencercbb22e22004-06-10 22:00:54 +0000260
Reid Spencer00c28a72004-06-10 08:09:13 +0000261 virtual void handleVBR64(unsigned Size ) {
262 bca.vbrCount64++;
263 bca.vbrCompBytes += Size;
264 bca.vbrExpdBytes += sizeof(uint64_t);
Reid Spencercbb22e22004-06-10 22:00:54 +0000265 if ( currFunc ) {
266 currFunc->vbrCount64++;
267 currFunc->vbrCompBytes += Size;
268 currFunc->vbrExpdBytes += sizeof(uint64_t);
269 }
Reid Spencer00c28a72004-06-10 08:09:13 +0000270 }
Reid Spencerdac69c82004-06-07 17:53:43 +0000271};
272
273}
274
275void llvm::BytecodeAnalyzer::AnalyzeBytecode(
276 const unsigned char *Buf,
277 unsigned Length,
278 BytecodeAnalysis& bca,
279 const std::string &ModuleID
280)
281{
Reid Spencer649ee572004-06-09 06:16:43 +0000282 bca.byteSize = Length;
283 AnalyzerHandler TheHandler(bca);
Reid Spencer00c28a72004-06-10 08:09:13 +0000284 AbstractBytecodeParser TheParser(&TheHandler, true, true, true);
Reid Spencerdac69c82004-06-07 17:53:43 +0000285 TheParser.ParseBytecode( Buf, Length, ModuleID );
Reid Spencer00c28a72004-06-10 08:09:13 +0000286 TheParser.ParseAllFunctionBodies();
Reid Spencerdac69c82004-06-07 17:53:43 +0000287}
288
289// vim: sw=2