blob: 94680949cb53ace4cdf7073757216bade015e3b3 [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;
Reid Spencer1cf50242004-06-11 15:10:38 +000055 bca.instructionSize = 0;
56 bca.longInstructions = 0;
Reid Spencer00c28a72004-06-10 08:09:13 +000057 bca.vbrCount32 = 0;
58 bca.vbrCount64 = 0;
59 bca.vbrCompBytes = 0;
60 bca.vbrExpdBytes = 0;
Reid Spencer649ee572004-06-09 06:16:43 +000061 bca.FunctionInfo.clear();
62 bca.BytecodeDump.clear();
Reid Spencer00c28a72004-06-10 08:09:13 +000063 bca.BlockSizes[BytecodeFormat::Module] = 0;
64 bca.BlockSizes[BytecodeFormat::Function] = 0;
65 bca.BlockSizes[BytecodeFormat::ConstantPool] = 0;
66 bca.BlockSizes[BytecodeFormat::SymbolTable] = 0;
67 bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo] = 0;
68 bca.BlockSizes[BytecodeFormat::GlobalTypePlane] = 0;
69 bca.BlockSizes[BytecodeFormat::BasicBlock] = 0;
70 bca.BlockSizes[BytecodeFormat::InstructionList] = 0;
71 bca.BlockSizes[BytecodeFormat::CompactionTable] = 0;
Reid Spencerdac69c82004-06-07 17:53:43 +000072 }
73
Reid Spencercbb22e22004-06-10 22:00:54 +000074 virtual void handleFinish() {
Reid Spencer00c28a72004-06-10 08:09:13 +000075 bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
76 double globalSize = 0.0;
77 globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPool]);
78 globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]);
79 globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]);
80 bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
81 bca.numGlobalVars );
82 bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::Function]) /
83 double(bca.numFunctions);
Reid Spencerdac69c82004-06-07 17:53:43 +000084 }
85
Reid Spencercbb22e22004-06-10 22:00:54 +000086 virtual void handleModuleBegin(const std::string& id) {
Reid Spencer649ee572004-06-09 06:16:43 +000087 bca.ModuleId = id;
Reid Spencerdac69c82004-06-07 17:53:43 +000088 }
89
Reid Spencercbb22e22004-06-10 22:00:54 +000090 virtual void handleModuleEnd(const std::string& id) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000091
Reid Spencercbb22e22004-06-10 22:00:54 +000092 virtual void handleVersionInfo(
Reid Spencerdac69c82004-06-07 17:53:43 +000093 unsigned char RevisionNum, ///< Byte code revision number
94 Module::Endianness Endianness, ///< Endianness indicator
95 Module::PointerSize PointerSize ///< PointerSize indicator
Reid Spencercbb22e22004-06-10 22:00:54 +000096 ) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000097
Reid Spencercbb22e22004-06-10 22:00:54 +000098 virtual void handleModuleGlobalsBegin(unsigned size) { }
Reid Spencerdac69c82004-06-07 17:53:43 +000099
Reid Spencercbb22e22004-06-10 22:00:54 +0000100 virtual void handleGlobalVariable(
Reid Spencerdac69c82004-06-07 17:53:43 +0000101 const Type* ElemType, ///< The type of the global variable
102 bool isConstant, ///< Whether the GV is constant or not
103 GlobalValue::LinkageTypes ///< The linkage type of the GV
Reid Spencercbb22e22004-06-10 22:00:54 +0000104 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000105 bca.numGlobalVars++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000106 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000107 }
108
Reid Spencercbb22e22004-06-10 22:00:54 +0000109 virtual void handleInitializedGV(
Reid Spencerdac69c82004-06-07 17:53:43 +0000110 const Type* ElemType, ///< The type of the global variable
111 bool isConstant, ///< Whether the GV is constant or not
112 GlobalValue::LinkageTypes,///< The linkage type of the GV
113 unsigned initSlot ///< Slot number of GV's initializer
Reid Spencercbb22e22004-06-10 22:00:54 +0000114 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000115 bca.numGlobalVars++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000116 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000117 }
118
Reid Spencercbb22e22004-06-10 22:00:54 +0000119 virtual void handleType( const Type* Ty ) { bca.numTypes++; }
Reid Spencerdac69c82004-06-07 17:53:43 +0000120
Reid Spencercbb22e22004-06-10 22:00:54 +0000121 virtual void handleFunctionDeclaration(
122 Function* Func, ///< The function
123 const FunctionType* FuncType ///< The type of the function
124 ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000125 bca.numFunctions++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000126 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000127 }
128
Reid Spencercbb22e22004-06-10 22:00:54 +0000129 virtual void handleModuleGlobalsEnd() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000130
Reid Spencercbb22e22004-06-10 22:00:54 +0000131 virtual void handleCompactionTableBegin() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000132
Reid Spencercbb22e22004-06-10 22:00:54 +0000133 virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) {
Reid Spencer649ee572004-06-09 06:16:43 +0000134 bca.numCmpctnTables++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000135 }
136
Reid Spencercbb22e22004-06-10 22:00:54 +0000137 virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
138 const Type* ) {}
Reid Spencerdac69c82004-06-07 17:53:43 +0000139
Reid Spencercbb22e22004-06-10 22:00:54 +0000140 virtual void handleCompactionTableValue(
Reid Spencerdac69c82004-06-07 17:53:43 +0000141 unsigned i,
142 unsigned ValSlot,
Reid Spencercbb22e22004-06-10 22:00:54 +0000143 const Type* ) { }
144
145 virtual void handleCompactionTableEnd() { }
146
147 virtual void handleSymbolTableBegin() { bca.numSymTab++; }
148
149 virtual void handleSymbolTablePlane( unsigned Ty, unsigned NumEntries,
150 const Type* Typ) { }
151
152 virtual void handleSymbolTableType( unsigned i, unsigned slot,
153 const std::string& name ) { }
154
155 virtual void handleSymbolTableValue( unsigned i, unsigned slot,
156 const std::string& name ) { }
157
158 virtual void handleSymbolTableEnd() { }
159
160 virtual void handleFunctionBegin( Function* Func, unsigned Size) {
161 const FunctionType* FType =
162 cast<FunctionType>(Func->getType()->getElementType());
163 currFunc = &bca.FunctionInfo[Func];
164 currFunc->description = FType->getDescription();
165 currFunc->name = Func->getName();
166 currFunc->byteSize = Size;
167 currFunc->numInstructions = 0;
168 currFunc->numBasicBlocks = 0;
169 currFunc->numPhis = 0;
170 currFunc->numOperands = 0;
171 currFunc->density = 0.0;
Reid Spencer1cf50242004-06-11 15:10:38 +0000172 currFunc->instructionSize = 0;
173 currFunc->longInstructions = 0;
Reid Spencercbb22e22004-06-10 22:00:54 +0000174 currFunc->vbrCount32 = 0;
175 currFunc->vbrCount64 = 0;
176 currFunc->vbrCompBytes = 0;
177 currFunc->vbrExpdBytes = 0;
Reid Spencerdac69c82004-06-07 17:53:43 +0000178 }
179
Reid Spencercbb22e22004-06-10 22:00:54 +0000180 virtual void handleFunctionEnd( Function* Func) {
181 currFunc->density = double(currFunc->byteSize) /
182 double(currFunc->numInstructions+currFunc->numBasicBlocks);
Reid Spencerdac69c82004-06-07 17:53:43 +0000183 }
184
Reid Spencercbb22e22004-06-10 22:00:54 +0000185 virtual void handleBasicBlockBegin( unsigned blocknum) {
Reid Spencer649ee572004-06-09 06:16:43 +0000186 bca.numBasicBlocks++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000187 bca.numValues++;
Reid Spencercbb22e22004-06-10 22:00:54 +0000188 if ( currFunc ) currFunc->numBasicBlocks++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000189 }
190
Reid Spencercbb22e22004-06-10 22:00:54 +0000191 virtual bool handleInstruction( unsigned Opcode, const Type* iType,
192 std::vector<unsigned>& Operands, unsigned Size) {
Reid Spencer649ee572004-06-09 06:16:43 +0000193 bca.numInstructions++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000194 bca.numValues++;
Reid Spencer1cf50242004-06-11 15:10:38 +0000195 bca.instructionSize += Size;
196 if (Size > 4 ) bca.longInstructions++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000197 bca.numOperands += Operands.size();
Reid Spencercbb22e22004-06-10 22:00:54 +0000198 if ( currFunc ) {
199 currFunc->numInstructions++;
Reid Spencer1cf50242004-06-11 15:10:38 +0000200 currFunc->instructionSize += Size;
201 if (Size > 4 ) currFunc->longInstructions++;
Reid Spencer8a9a3702004-06-11 03:06:43 +0000202 if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
Reid Spencercbb22e22004-06-10 22:00:54 +0000203 }
Reid Spencer649ee572004-06-09 06:16:43 +0000204 return Instruction::isTerminator(Opcode);
Reid Spencerdac69c82004-06-07 17:53:43 +0000205 }
206
Reid Spencercbb22e22004-06-10 22:00:54 +0000207 virtual void handleBasicBlockEnd(unsigned blocknum) { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000208
Reid Spencercbb22e22004-06-10 22:00:54 +0000209 virtual void handleGlobalConstantsBegin() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000210
Reid Spencercbb22e22004-06-10 22:00:54 +0000211 virtual void handleConstantExpression( unsigned Opcode, const Type* Typ,
212 std::vector<std::pair<const Type*,unsigned> > ArgVec ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000213 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000214 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000215 }
216
Reid Spencercbb22e22004-06-10 22:00:54 +0000217 virtual void handleConstantValue( Constant * c ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000218 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000219 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000220 }
221
Reid Spencercbb22e22004-06-10 22:00:54 +0000222 virtual void handleConstantArray( const ArrayType* AT,
223 std::vector<unsigned>& Elements ) {
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 handleConstantStruct(
Reid Spencer00c28a72004-06-10 08:09:13 +0000229 const StructType* ST,
230 std::vector<unsigned>& ElementSlots)
Reid Spencerdac69c82004-06-07 17:53:43 +0000231 {
Reid Spencer649ee572004-06-09 06:16:43 +0000232 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000233 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000234 }
235
Reid Spencercbb22e22004-06-10 22:00:54 +0000236 virtual void handleConstantPointer( const PointerType* PT, unsigned Slot) {
Reid Spencer649ee572004-06-09 06:16:43 +0000237 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000238 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000239 }
240
Reid Spencercbb22e22004-06-10 22:00:54 +0000241 virtual void handleConstantString( const ConstantArray* CA ) {
Reid Spencer649ee572004-06-09 06:16:43 +0000242 bca.numConstants++;
Reid Spencer00c28a72004-06-10 08:09:13 +0000243 bca.numValues++;
Reid Spencerdac69c82004-06-07 17:53:43 +0000244 }
245
Reid Spencercbb22e22004-06-10 22:00:54 +0000246 virtual void handleGlobalConstantsEnd() { }
Reid Spencerdac69c82004-06-07 17:53:43 +0000247
Reid Spencercbb22e22004-06-10 22:00:54 +0000248 virtual void handleAlignment(unsigned numBytes) {
Reid Spencer00c28a72004-06-10 08:09:13 +0000249 bca.numAlignment += numBytes;
Reid Spencerdac69c82004-06-07 17:53:43 +0000250 }
251
Reid Spencercbb22e22004-06-10 22:00:54 +0000252 virtual void handleBlock(
Reid Spencer00c28a72004-06-10 08:09:13 +0000253 unsigned BType, const unsigned char* StartPtr, unsigned Size) {
254 bca.numBlocks++;
255 bca.BlockSizes[llvm::BytecodeFormat::FileBlockIDs(BType)] += Size;
256 }
257
258 virtual void handleVBR32(unsigned Size ) {
259 bca.vbrCount32++;
260 bca.vbrCompBytes += Size;
261 bca.vbrExpdBytes += sizeof(uint32_t);
Reid Spencercbb22e22004-06-10 22:00:54 +0000262 if (currFunc) {
263 currFunc->vbrCount32++;
264 currFunc->vbrCompBytes += Size;
265 currFunc->vbrExpdBytes += sizeof(uint32_t);
266 }
Reid Spencer00c28a72004-06-10 08:09:13 +0000267 }
Reid Spencercbb22e22004-06-10 22:00:54 +0000268
Reid Spencer00c28a72004-06-10 08:09:13 +0000269 virtual void handleVBR64(unsigned Size ) {
270 bca.vbrCount64++;
271 bca.vbrCompBytes += Size;
272 bca.vbrExpdBytes += sizeof(uint64_t);
Reid Spencercbb22e22004-06-10 22:00:54 +0000273 if ( currFunc ) {
274 currFunc->vbrCount64++;
275 currFunc->vbrCompBytes += Size;
276 currFunc->vbrExpdBytes += sizeof(uint64_t);
277 }
Reid Spencer00c28a72004-06-10 08:09:13 +0000278 }
Reid Spencerdac69c82004-06-07 17:53:43 +0000279};
280
281}
282
283void llvm::BytecodeAnalyzer::AnalyzeBytecode(
284 const unsigned char *Buf,
285 unsigned Length,
286 BytecodeAnalysis& bca,
287 const std::string &ModuleID
288)
289{
Reid Spencer649ee572004-06-09 06:16:43 +0000290 bca.byteSize = Length;
291 AnalyzerHandler TheHandler(bca);
Reid Spencer00c28a72004-06-10 08:09:13 +0000292 AbstractBytecodeParser TheParser(&TheHandler, true, true, true);
Reid Spencerdac69c82004-06-07 17:53:43 +0000293 TheParser.ParseBytecode( Buf, Length, ModuleID );
Reid Spencer00c28a72004-06-10 08:09:13 +0000294 TheParser.ParseAllFunctionBodies();
Reid Spencerdac69c82004-06-07 17:53:43 +0000295}
296
297// vim: sw=2