Analyzer moved to ../Reader directory.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14491 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2004-06-29 23:21:53 +00:00
parent 46bd33f336
commit cc1091e66b
7 changed files with 0 additions and 2573 deletions

View File

@ -1,297 +0,0 @@
//===-- BytecodeHandler.cpp - Parsing Handler -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines the BytecodeHandler class that gets called by the
// AbstractBytecodeParser when parsing events occur.
//
//===----------------------------------------------------------------------===//
#include "AnalyzerInternals.h"
#include <iostream>
using namespace llvm;
namespace {
class AnalyzerHandler : public BytecodeHandler {
BytecodeAnalysis& bca;
BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
public:
AnalyzerHandler(BytecodeAnalysis& TheBca)
: bca(TheBca)
, currFunc(0)
{ }
virtual bool handleError(const std::string& str ) {
return false;
}
virtual void handleStart() {
bca.ModuleId.clear();
bca.numBlocks = 0;
bca.numTypes = 0;
bca.numValues = 0;
bca.numFunctions = 0;
bca.numConstants = 0;
bca.numGlobalVars = 0;
bca.numInstructions = 0;
bca.numBasicBlocks = 0;
bca.numOperands = 0;
bca.numCmpctnTables = 0;
bca.numSymTab = 0;
bca.maxTypeSlot = 0;
bca.maxValueSlot = 0;
bca.numAlignment = 0;
bca.fileDensity = 0.0;
bca.globalsDensity = 0.0;
bca.functionDensity = 0.0;
bca.instructionSize = 0;
bca.longInstructions = 0;
bca.vbrCount32 = 0;
bca.vbrCount64 = 0;
bca.vbrCompBytes = 0;
bca.vbrExpdBytes = 0;
bca.FunctionInfo.clear();
bca.BytecodeDump.clear();
bca.BlockSizes[BytecodeFormat::Module] = 0;
bca.BlockSizes[BytecodeFormat::Function] = 0;
bca.BlockSizes[BytecodeFormat::ConstantPool] = 0;
bca.BlockSizes[BytecodeFormat::SymbolTable] = 0;
bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo] = 0;
bca.BlockSizes[BytecodeFormat::GlobalTypePlane] = 0;
bca.BlockSizes[BytecodeFormat::BasicBlock] = 0;
bca.BlockSizes[BytecodeFormat::InstructionList] = 0;
bca.BlockSizes[BytecodeFormat::CompactionTable] = 0;
}
virtual void handleFinish() {
bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
double globalSize = 0.0;
globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPool]);
globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]);
globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]);
bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
bca.numGlobalVars );
bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::Function]) /
double(bca.numFunctions);
}
virtual void handleModuleBegin(const std::string& id) {
bca.ModuleId = id;
}
virtual void handleModuleEnd(const std::string& id) { }
virtual void handleVersionInfo(
unsigned char RevisionNum, ///< Byte code revision number
Module::Endianness Endianness, ///< Endianness indicator
Module::PointerSize PointerSize ///< PointerSize indicator
) { }
virtual void handleModuleGlobalsBegin(unsigned size) { }
virtual void handleGlobalVariable(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes ///< The linkage type of the GV
) {
bca.numGlobalVars++;
bca.numValues++;
}
virtual void handleInitializedGV(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes,///< The linkage type of the GV
unsigned initSlot ///< Slot number of GV's initializer
) {
bca.numGlobalVars++;
bca.numValues++;
}
virtual void handleType( const Type* Ty ) { bca.numTypes++; }
virtual void handleFunctionDeclaration(
Function* Func, ///< The function
const FunctionType* FuncType ///< The type of the function
) {
bca.numFunctions++;
bca.numValues++;
}
virtual void handleModuleGlobalsEnd() { }
virtual void handleCompactionTableBegin() { }
virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries) {
bca.numCmpctnTables++;
}
virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
const Type* ) {}
virtual void handleCompactionTableValue(
unsigned i,
unsigned ValSlot,
const Type* ) { }
virtual void handleCompactionTableEnd() { }
virtual void handleSymbolTableBegin() { bca.numSymTab++; }
virtual void handleSymbolTablePlane( unsigned Ty, unsigned NumEntries,
const Type* Typ) { }
virtual void handleSymbolTableType( unsigned i, unsigned slot,
const std::string& name ) { }
virtual void handleSymbolTableValue( unsigned i, unsigned slot,
const std::string& name ) { }
virtual void handleSymbolTableEnd() { }
virtual void handleFunctionBegin( Function* Func, unsigned Size) {
const FunctionType* FType =
cast<FunctionType>(Func->getType()->getElementType());
currFunc = &bca.FunctionInfo[Func];
currFunc->description = FType->getDescription();
currFunc->name = Func->getName();
currFunc->byteSize = Size;
currFunc->numInstructions = 0;
currFunc->numBasicBlocks = 0;
currFunc->numPhis = 0;
currFunc->numOperands = 0;
currFunc->density = 0.0;
currFunc->instructionSize = 0;
currFunc->longInstructions = 0;
currFunc->vbrCount32 = 0;
currFunc->vbrCount64 = 0;
currFunc->vbrCompBytes = 0;
currFunc->vbrExpdBytes = 0;
}
virtual void handleFunctionEnd( Function* Func) {
currFunc->density = double(currFunc->byteSize) /
double(currFunc->numInstructions+currFunc->numBasicBlocks);
}
virtual void handleBasicBlockBegin( unsigned blocknum) {
bca.numBasicBlocks++;
bca.numValues++;
if ( currFunc ) currFunc->numBasicBlocks++;
}
virtual bool handleInstruction( unsigned Opcode, const Type* iType,
std::vector<unsigned>& Operands, unsigned Size) {
bca.numInstructions++;
bca.numValues++;
bca.instructionSize += Size;
if (Size > 4 ) bca.longInstructions++;
bca.numOperands += Operands.size();
if ( currFunc ) {
currFunc->numInstructions++;
currFunc->instructionSize += Size;
if (Size > 4 ) currFunc->longInstructions++;
if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
}
return Instruction::isTerminator(Opcode);
}
virtual void handleBasicBlockEnd(unsigned blocknum) { }
virtual void handleGlobalConstantsBegin() { }
virtual void handleConstantExpression( unsigned Opcode, const Type* Typ,
std::vector<std::pair<const Type*,unsigned> > ArgVec ) {
bca.numConstants++;
bca.numValues++;
}
virtual void handleConstantValue( Constant * c ) {
bca.numConstants++;
bca.numValues++;
}
virtual void handleConstantArray( const ArrayType* AT,
std::vector<unsigned>& Elements ) {
bca.numConstants++;
bca.numValues++;
}
virtual void handleConstantStruct(
const StructType* ST,
std::vector<unsigned>& ElementSlots)
{
bca.numConstants++;
bca.numValues++;
}
virtual void handleConstantPointer( const PointerType* PT, unsigned Slot) {
bca.numConstants++;
bca.numValues++;
}
virtual void handleConstantString( const ConstantArray* CA ) {
bca.numConstants++;
bca.numValues++;
}
virtual void handleGlobalConstantsEnd() { }
virtual void handleAlignment(unsigned numBytes) {
bca.numAlignment += numBytes;
}
virtual void handleBlock(
unsigned BType, const unsigned char* StartPtr, unsigned Size) {
bca.numBlocks++;
bca.BlockSizes[llvm::BytecodeFormat::FileBlockIDs(BType)] += Size;
}
virtual void handleVBR32(unsigned Size ) {
bca.vbrCount32++;
bca.vbrCompBytes += Size;
bca.vbrExpdBytes += sizeof(uint32_t);
if (currFunc) {
currFunc->vbrCount32++;
currFunc->vbrCompBytes += Size;
currFunc->vbrExpdBytes += sizeof(uint32_t);
}
}
virtual void handleVBR64(unsigned Size ) {
bca.vbrCount64++;
bca.vbrCompBytes += Size;
bca.vbrExpdBytes += sizeof(uint64_t);
if ( currFunc ) {
currFunc->vbrCount64++;
currFunc->vbrCompBytes += Size;
currFunc->vbrExpdBytes += sizeof(uint64_t);
}
}
};
}
void llvm::BytecodeAnalyzer::AnalyzeBytecode(
const unsigned char *Buf,
unsigned Length,
BytecodeAnalysis& bca,
const std::string &ModuleID
)
{
bca.byteSize = Length;
AnalyzerHandler TheHandler(bca);
AbstractBytecodeParser TheParser(&TheHandler, true, true, true);
TheParser.ParseBytecode( Buf, Length, ModuleID );
TheParser.ParseAllFunctionBodies();
}
// vim: sw=2

View File

@ -1,51 +0,0 @@
//===-- ReaderInternals.h - Definitions internal to the reader --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines various stuff that is used by the bytecode reader.
//
//===----------------------------------------------------------------------===//
#ifndef ANALYZER_INTERNALS_H
#define ANALYZER_INTERNALS_H
#include "Parser.h"
#include "llvm/Bytecode/Analyzer.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
namespace llvm {
class BytecodeAnalyzer {
BytecodeAnalyzer(const BytecodeAnalyzer &); // DO NOT IMPLEMENT
void operator=(const BytecodeAnalyzer &); // DO NOT IMPLEMENT
public:
BytecodeAnalyzer() { }
~BytecodeAnalyzer() { }
void AnalyzeBytecode(
const unsigned char *Buf,
unsigned Length,
BytecodeAnalysis& bca,
const std::string &ModuleID
);
void DumpBytecode(
const unsigned char *Buf,
unsigned Length,
BytecodeAnalysis& bca,
const std::string &ModuleID
);
};
} // End llvm namespace
#endif
// vim: sw=2

View File

@ -1,332 +0,0 @@
//===- AnalyzerWrappers.cpp - Analyze bytecode from file or buffer -------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements loading and analysis of a bytecode file and analyzing a
// bytecode buffer.
//
//===----------------------------------------------------------------------===//
#include "llvm/Bytecode/Analyzer.h"
#include "AnalyzerInternals.h"
#include "Support/FileUtilities.h"
#include "Support/StringExtras.h"
#include "Config/unistd.h"
#include <cerrno>
#include <iomanip>
using namespace llvm;
//===----------------------------------------------------------------------===//
// BytecodeFileAnalyzer - Analyze from an mmap'able file descriptor.
//
namespace {
/// BytecodeFileAnalyzer - parses a bytecode file from a file
class BytecodeFileAnalyzer : public BytecodeAnalyzer {
private:
unsigned char *Buffer;
unsigned Length;
BytecodeFileAnalyzer(const BytecodeFileAnalyzer&); // Do not implement
void operator=(const BytecodeFileAnalyzer &BFR); // Do not implement
public:
BytecodeFileAnalyzer(const std::string &Filename, BytecodeAnalysis& bca);
~BytecodeFileAnalyzer();
};
}
static std::string ErrnoMessage (int savedErrNum, std::string descr) {
return ::strerror(savedErrNum) + std::string(", while trying to ") + descr;
}
BytecodeFileAnalyzer::BytecodeFileAnalyzer(const std::string &Filename,
BytecodeAnalysis& bca) {
Buffer = (unsigned char*)ReadFileIntoAddressSpace(Filename, Length);
if (Buffer == 0)
throw "Error reading file '" + Filename + "'.";
try {
// Parse the bytecode we mmapped in
if ( bca.dumpBytecode )
DumpBytecode(Buffer, Length, bca, Filename);
AnalyzeBytecode(Buffer, Length, bca, Filename);
} catch (...) {
UnmapFileFromAddressSpace(Buffer, Length);
throw;
}
}
BytecodeFileAnalyzer::~BytecodeFileAnalyzer() {
// Unmmap the bytecode...
UnmapFileFromAddressSpace(Buffer, Length);
}
//===----------------------------------------------------------------------===//
// BytecodeBufferAnalyzer - Read from a memory buffer
//
namespace {
/// BytecodeBufferAnalyzer - parses a bytecode file from a buffer
///
class BytecodeBufferAnalyzer : public BytecodeAnalyzer {
private:
const unsigned char *Buffer;
bool MustDelete;
BytecodeBufferAnalyzer(const BytecodeBufferAnalyzer&); // Do not implement
void operator=(const BytecodeBufferAnalyzer &BFR); // Do not implement
public:
BytecodeBufferAnalyzer(const unsigned char *Buf, unsigned Length,
BytecodeAnalysis& bca, const std::string &ModuleID);
~BytecodeBufferAnalyzer();
};
}
BytecodeBufferAnalyzer::BytecodeBufferAnalyzer(const unsigned char *Buf,
unsigned Length,
BytecodeAnalysis& bca,
const std::string &ModuleID) {
// If not aligned, allocate a new buffer to hold the bytecode...
const unsigned char *ParseBegin = 0;
if ((intptr_t)Buf & 3) {
Buffer = new unsigned char[Length+4];
unsigned Offset = 4 - ((intptr_t)Buffer & 3); // Make sure it's aligned
ParseBegin = Buffer + Offset;
memcpy((unsigned char*)ParseBegin, Buf, Length); // Copy it over
MustDelete = true;
} else {
// If we don't need to copy it over, just use the caller's copy
ParseBegin = Buffer = Buf;
MustDelete = false;
}
try {
if ( bca.dumpBytecode )
DumpBytecode(ParseBegin, Length, bca, ModuleID);
AnalyzeBytecode(ParseBegin, Length, bca, ModuleID);
} catch (...) {
if (MustDelete) delete [] Buffer;
throw;
}
}
BytecodeBufferAnalyzer::~BytecodeBufferAnalyzer() {
if (MustDelete) delete [] Buffer;
}
//===----------------------------------------------------------------------===//
// BytecodeStdinAnalyzer - Read bytecode from Standard Input
//
namespace {
/// BytecodeStdinAnalyzer - parses a bytecode file from stdin
///
class BytecodeStdinAnalyzer : public BytecodeAnalyzer {
private:
std::vector<unsigned char> FileData;
unsigned char *FileBuf;
BytecodeStdinAnalyzer(const BytecodeStdinAnalyzer&); // Do not implement
void operator=(const BytecodeStdinAnalyzer &BFR); // Do not implement
public:
BytecodeStdinAnalyzer(BytecodeAnalysis& bca);
};
}
BytecodeStdinAnalyzer::BytecodeStdinAnalyzer(BytecodeAnalysis& bca ) {
int BlockSize;
unsigned char Buffer[4096*4];
// Read in all of the data from stdin, we cannot mmap stdin...
while ((BlockSize = ::read(0 /*stdin*/, Buffer, 4096*4))) {
if (BlockSize == -1)
throw ErrnoMessage(errno, "read from standard input");
FileData.insert(FileData.end(), Buffer, Buffer+BlockSize);
}
if (FileData.empty())
throw std::string("Standard Input empty!");
FileBuf = &FileData[0];
if (bca.dumpBytecode)
DumpBytecode(&FileData[0], FileData.size(), bca, "<stdin>");
AnalyzeBytecode(FileBuf, FileData.size(), bca, "<stdin>");
}
//===----------------------------------------------------------------------===//
// Wrapper functions
//===----------------------------------------------------------------------===//
// AnalyzeBytecodeFile - analyze one file
void llvm::AnalyzeBytecodeFile(const std::string &Filename,
BytecodeAnalysis& bca,
std::string *ErrorStr)
{
try {
if ( Filename != "-" )
BytecodeFileAnalyzer bfa(Filename,bca);
else
BytecodeStdinAnalyzer bsa(bca);
} catch (std::string &err) {
if (ErrorStr) *ErrorStr = err;
}
}
// AnalyzeBytecodeBuffer - analyze a buffer
void llvm::AnalyzeBytecodeBuffer(
const unsigned char* Buffer, ///< Pointer to start of bytecode buffer
unsigned BufferSize, ///< Size of the bytecode buffer
BytecodeAnalysis& Results, ///< The results of the analysis
std::string* ErrorStr ///< Errors, if any.
)
{
try {
BytecodeBufferAnalyzer(Buffer, BufferSize, Results, "<buffer>" );
} catch (std::string& err ) {
if ( ErrorStr) *ErrorStr = err;
}
}
/// This function prints the contents of rhe BytecodeAnalysis structure in
/// a human legible form.
/// @brief Print BytecodeAnalysis structure to an ostream
namespace {
inline static void print(std::ostream& Out, const char*title,
unsigned val, bool nl = true ) {
Out << std::setw(30) << std::right << title
<< std::setw(0) << ": "
<< std::setw(9) << val << "\n";
}
inline static void print(std::ostream&Out, const char*title,
double val ) {
Out << std::setw(30) << std::right << title
<< std::setw(0) << ": "
<< std::setw(9) << std::setprecision(6) << val << "\n" ;
}
inline static void print(std::ostream&Out, const char*title,
double top, double bot ) {
Out << std::setw(30) << std::right << title
<< std::setw(0) << ": "
<< std::setw(9) << std::setprecision(6) << top
<< " (" << std::left << std::setw(0) << std::setprecision(4)
<< (top/bot)*100.0 << "%)\n";
}
inline static void print(std::ostream&Out, const char*title,
std::string val, bool nl = true) {
Out << std::setw(30) << std::right << title
<< std::setw(0) << ": "
<< std::left << val << (nl ? "\n" : "");
}
}
void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
{
print(Out, "Bytecode Analysis Of Module", bca.ModuleId);
print(Out, "File Size", bca.byteSize);
print(Out, "Bytecode Compression Index",std::string("TBD"));
print(Out, "Number Of Bytecode Blocks", bca.numBlocks);
print(Out, "Number Of Types", bca.numTypes);
print(Out, "Number Of Values", bca.numValues);
print(Out, "Number Of Constants", bca.numConstants);
print(Out, "Number Of Global Variables", bca.numGlobalVars);
print(Out, "Number Of Functions", bca.numFunctions);
print(Out, "Number Of Basic Blocks", bca.numBasicBlocks);
print(Out, "Number Of Instructions", bca.numInstructions);
print(Out, "Number Of Operands", bca.numOperands);
print(Out, "Number Of Compaction Tables", bca.numCmpctnTables);
print(Out, "Number Of Symbol Tables", bca.numSymTab);
print(Out, "Long Instructions", bca.longInstructions);
print(Out, "Instruction Size", bca.instructionSize);
print(Out, "Average Instruction Size",
double(bca.instructionSize)/double(bca.numInstructions));
print(Out, "Maximum Type Slot Number", bca.maxTypeSlot);
print(Out, "Maximum Value Slot Number", bca.maxValueSlot);
print(Out, "Bytes Thrown To Alignment", double(bca.numAlignment),
double(bca.byteSize));
print(Out, "File Density (bytes/def)", bca.fileDensity);
print(Out, "Globals Density (bytes/def)", bca.globalsDensity);
print(Out, "Function Density (bytes/func)", bca.functionDensity);
print(Out, "Number of VBR 32-bit Integers", bca.vbrCount32);
print(Out, "Number of VBR 64-bit Integers", bca.vbrCount64);
print(Out, "Number of VBR Compressed Bytes", bca.vbrCompBytes);
print(Out, "Number of VBR Expanded Bytes", bca.vbrExpdBytes);
print(Out, "VBR Savings",
double(bca.vbrExpdBytes)-double(bca.vbrCompBytes),
double(bca.byteSize));
if ( bca.detailedResults ) {
print(Out, "Module Bytes",
double(bca.BlockSizes[BytecodeFormat::Module]),
double(bca.byteSize));
print(Out, "Function Bytes",
double(bca.BlockSizes[BytecodeFormat::Function]),
double(bca.byteSize));
print(Out, "Constant Pool Bytes",
double(bca.BlockSizes[BytecodeFormat::ConstantPool]),
double(bca.byteSize));
print(Out, "Symbol Table Bytes",
double(bca.BlockSizes[BytecodeFormat::SymbolTable]),
double(bca.byteSize));
print(Out, "Module Global Info Bytes",
double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]),
double(bca.byteSize));
print(Out, "Global Type Plane Bytes",
double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]),
double(bca.byteSize));
print(Out, "Basic Block Bytes",
double(bca.BlockSizes[BytecodeFormat::BasicBlock]),
double(bca.byteSize));
print(Out, "Instruction List Bytes",
double(bca.BlockSizes[BytecodeFormat::InstructionList]),
double(bca.byteSize));
print(Out, "Compaction Table Bytes",
double(bca.BlockSizes[BytecodeFormat::CompactionTable]),
double(bca.byteSize));
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
bca.FunctionInfo.begin();
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
bca.FunctionInfo.end();
while ( I != E ) {
Out << std::left << std::setw(0);
Out << "Function: " << I->second.name << "\n";
print(Out, "Type:", I->second.description);
print(Out, "Byte Size", I->second.byteSize);
print(Out, "Instructions", I->second.numInstructions);
print(Out, "Long Instructions", I->second.longInstructions);
print(Out, "Instruction Size", I->second.instructionSize);
print(Out, "Average Instruction Size",
double(I->second.instructionSize)/double(I->second.numInstructions));
print(Out, "Basic Blocks", I->second.numBasicBlocks);
print(Out, "Operand", I->second.numOperands);
print(Out, "Function Density", I->second.density);
print(Out, "Number of VBR 32-bit Integers", I->second.vbrCount32);
print(Out, "Number of VBR 64-bit Integers", I->second.vbrCount64);
print(Out, "Number of VBR Compressed Bytes", I->second.vbrCompBytes);
print(Out, "Number of VBR Expanded Bytes", I->second.vbrExpdBytes);
print(Out, "VBR Savings",
double(I->second.vbrExpdBytes)-double(I->second.vbrCompBytes),
double(I->second.byteSize));
++I;
}
}
if ( bca.dumpBytecode )
Out << bca.BytecodeDump;
}
// vim: sw=2

View File

@ -1,274 +0,0 @@
//===-- BytecodeDumper.cpp - Parsing Handler --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines the BytecodeDumper class that gets called by the
// AbstractBytecodeParser when parsing events occur. It merely dumps the
// information presented to it from the parser.
//
//===----------------------------------------------------------------------===//
#include "AnalyzerInternals.h"
#include "llvm/Constant.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instruction.h"
#include "llvm/Type.h"
using namespace llvm;
namespace {
class BytecodeDumper : public llvm::BytecodeHandler {
public:
virtual bool handleError(const std::string& str )
{
std::cout << "ERROR: " << str << "\n";
return true;
}
virtual void handleStart()
{
std::cout << "Bytecode {\n";
}
virtual void handleFinish()
{
std::cout << "} End Bytecode\n";
}
virtual void handleModuleBegin(const std::string& id)
{
std::cout << " Module " << id << " {\n";
}
virtual void handleModuleEnd(const std::string& id)
{
std::cout << " } End Module " << id << "\n";
}
virtual void handleVersionInfo(
unsigned char RevisionNum, ///< Byte code revision number
Module::Endianness Endianness, ///< Endianness indicator
Module::PointerSize PointerSize ///< PointerSize indicator
)
{
std::cout << " RevisionNum: " << int(RevisionNum)
<< " Endianness: " << Endianness
<< " PointerSize: " << PointerSize << "\n";
}
virtual void handleModuleGlobalsBegin()
{
std::cout << " BLOCK: ModuleGlobalInfo {\n";
}
virtual void handleGlobalVariable(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes Linkage ///< The linkage type of the GV
)
{
std::cout << " GV: Uninitialized, "
<< ( isConstant? "Constant, " : "Variable, ")
<< " Linkage=" << Linkage << " Type="
<< ElemType->getDescription() << "\n";
}
virtual void handleInitializedGV(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes Linkage,///< The linkage type of the GV
unsigned initSlot ///< Slot number of GV's initializer
)
{
std::cout << " GV: Initialized, "
<< ( isConstant? "Constant, " : "Variable, ")
<< " Linkage=" << Linkage << " Type="
<< ElemType->getDescription()
<< " InitializerSlot=" << initSlot << "\n";
}
virtual void handleType( const Type* Ty ) {
std::cout << " Type: " << Ty->getDescription() << "\n";
}
virtual void handleFunctionDeclaration(
Function* Func,
const FunctionType* FuncType) {
std::cout << " Function: " << FuncType->getDescription() << "\n";
}
virtual void handleModuleGlobalsEnd() {
std::cout << " } END BLOCK: ModuleGlobalInfo\n";
}
virtual void handleCompactionTableBegin() {
std::cout << " BLOCK: CompactionTable {\n";
}
virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries ) {
std::cout << " Plane: Ty=" << Ty << " Size=" << NumEntries << "\n";
}
virtual void handleCompactionTableType(
unsigned i,
unsigned TypSlot,
const Type* Ty) {
std::cout << " Type: " << i << " Slot:" << TypSlot
<< " is " << Ty->getDescription() << "\n";
}
virtual void handleCompactionTableValue(
unsigned i,
unsigned ValSlot,
const Type* Ty ) {
std::cout << " Value: " << i << " Slot:" << ValSlot
<< " is " << Ty->getDescription() << "\n";
}
virtual void handleCompactionTableEnd() {
std::cout << " } END BLOCK: CompactionTable\n";
}
virtual void handleSymbolTableBegin() {
std::cout << " BLOCK: SymbolTable {\n";
}
virtual void handleSymbolTablePlane(
unsigned Ty,
unsigned NumEntries,
const Type* Typ) {
std::cout << " Plane: Ty=" << Ty << " Size=" << NumEntries
<< " Type: " << Typ->getDescription() << "\n";
}
virtual void handleSymbolTableType(
unsigned i,
unsigned slot,
const std::string& name ) {
std::cout << " Type " << i << " Slot=" << slot
<< " Name: " << name << "\n";
}
virtual void handleSymbolTableValue(
unsigned i,
unsigned slot,
const std::string& name ) {
std::cout << " Value " << i << " Slot=" << slot
<< " Name: " << name << "\n";
}
virtual void handleSymbolTableEnd() {
std::cout << " } END BLOCK: SymbolTable\n";
}
virtual void handleFunctionBegin(
const Type* FType, GlobalValue::LinkageTypes linkage ) {
std::cout << "BLOCK: Function {\n";
std::cout << " Linkage: " << linkage << "\n";
std::cout << " Type: " << FType->getDescription() << "\n";
}
virtual void handleFunctionEnd( const Type* FType) {
std::cout << "} END BLOCK: Function\n";
}
virtual void handleBasicBlockBegin( unsigned blocknum) {
std::cout << " BLOCK: BasicBlock #" << blocknum << "{\n";
}
virtual bool handleInstruction(
unsigned Opcode,
const Type* iType,
std::vector<unsigned>& Operands,
unsigned Size) {
std::cout << " INST: OpCode="
<< Instruction::getOpcodeName(Opcode) << " Type="
<< iType->getDescription() << "\n";
for ( unsigned i = 0; i < Operands.size(); ++i )
std::cout << " Op#" << i << " Slot=" << Operands[i] << "\n";
return Instruction::isTerminator(Opcode);
}
virtual void handleBasicBlockEnd(unsigned blocknum) {
std::cout << " } END BLOCK: BasicBlock #" << blocknum << "{\n";
}
virtual void handleGlobalConstantsBegin() {
std::cout << " BLOCK: GlobalConstants {\n";
}
virtual void handleConstantExpression(
unsigned Opcode,
const Type* Typ,
std::vector<std::pair<const Type*,unsigned> > ArgVec
) {
std::cout << " EXPR: " << Instruction::getOpcodeName(Opcode)
<< " Type=" << Typ->getDescription() << "\n";
for ( unsigned i = 0; i < ArgVec.size(); ++i )
std::cout << " Arg#" << i << " Type="
<< ArgVec[i].first->getDescription() << " Slot="
<< ArgVec[i].second << "\n";
}
virtual void handleConstantValue( Constant * c ) {
std::cout << " VALUE: ";
c->print(std::cout);
std::cout << "\n";
}
virtual void handleConstantArray(const ArrayType* AT,
std::vector<unsigned>& Elements ) {
std::cout << " ARRAY: " << AT->getDescription() << "\n";
for ( unsigned i = 0; i < Elements.size(); ++i )
std::cout << " #" << i << " Slot=" << Elements[i] << "\n";
}
virtual void handleConstantStruct( const StructType* ST,
std::vector<unsigned>& Elements) {
std::cout << " STRUC: " << ST->getDescription() << "\n";
for ( unsigned i = 0; i < Elements.size(); ++i )
std::cout << " #" << i << " Slot=" << Elements[i] << "\n";
}
virtual void handleConstantPointer(
const PointerType* PT, unsigned Slot)
{
std::cout << " POINT: " << PT->getDescription()
<< " Slot=" << Slot << "\n";
}
virtual void handleConstantString( const ConstantArray* CA ) {
std::cout << " STRNG: ";
CA->print(std::cout);
std::cout << "\n";
}
virtual void handleGlobalConstantsEnd() {
std::cout << " } END BLOCK: GlobalConstants\n";
}
};
}
void BytecodeAnalyzer::DumpBytecode(
const unsigned char *Buf,
unsigned Length,
BytecodeAnalysis& bca,
const std::string &ModuleID) {
BytecodeDumper TheHandler;
AbstractBytecodeParser TheParser(&TheHandler);
TheParser.ParseBytecode( Buf, Length, ModuleID );
if ( bca.detailedResults )
TheParser.ParseAllFunctionBodies();
}
// vim: sw=2

View File

@ -1,13 +0,0 @@
##===- lib/Bytecode/Reader/Makefile ------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file was developed by the LLVM research group and is distributed under
# the University of Illinois Open Source License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../..
LIBRARYNAME = bcanalyzer
include $(LEVEL)/Makefile.common

File diff suppressed because it is too large Load Diff

View File

@ -1,544 +0,0 @@
//===-- Parser.h - Abstract Interface To Bytecode Parsing -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines the interface to the Bytecode Parser and the
// Bytecode Handler interface that it calls.
//
//===----------------------------------------------------------------------===//
#ifndef BYTECODE_PARSER_H
#define BYTECODE_PARSER_H
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalValue.h"
#include "llvm/Module.h"
#include <utility>
#include <vector>
#include <map>
namespace llvm {
class BytecodeHandler; ///< Forward declare the handler interface
/// This class defines the interface for parsing a buffer of bytecode. The
/// parser itself takes no action except to call the various functions of
/// the handler interface. The parser's sole responsibility is the correct
/// interpretation of the bytecode buffer. The handler is responsible for
/// instantiating and keeping track of all values. As a convenience, the parser
/// is responsible for materializing types and will pass them through the
/// handler interface as necessary.
/// @see BytecodeHandler
/// @brief Abstract Bytecode Parser interface
class AbstractBytecodeParser {
/// @name Constructors
/// @{
public:
AbstractBytecodeParser(
BytecodeHandler* h,
bool repAlignment = false,
bool repBlocks = false,
bool repVBR = false
) {
handler = h;
reportAlignment = repAlignment;
reportBlocks = repBlocks;
reportVBR = repVBR;
}
~AbstractBytecodeParser() { }
/// @}
/// @name Types
/// @{
public:
/// @brief A convenience type for the buffer pointer
typedef const unsigned char* BufPtr;
/// @brief The type used for vector of potentially abstract types
typedef std::vector<PATypeHolder> TypeListTy;
/// @brief
/// @}
/// @name Methods
/// @{
public:
/// @brief Main interface to parsing a bytecode buffer.
void ParseBytecode(const unsigned char *Buf, unsigned Length,
const std::string &ModuleID);
/// The ParseBytecode method lazily parses functions. Use this
/// method to cause the parser to actually parse all the function bodies
/// in the bytecode buffer.
/// @see ParseBytecode
/// @brief Parse all function bodies
void ParseAllFunctionBodies ();
/// The Parsebytecode method lazily parses functions. Use this
/// method to casue the parser to parse the next function of a given
/// types. Note that this will remove the function from what is to be
/// included by ParseAllFunctionBodies.
/// @see ParseAllFunctionBodies
/// @see ParseBytecode
/// @brief Parse the next function of specific type
void ParseNextFunction (Function* Func) ;
/// @}
/// @name Parsing Units For Subclasses
/// @{
protected:
/// @brief Parse whole module scope
void ParseModule ();
/// @brief Parse the version information block
void ParseVersionInfo ();
/// @brief Parse the ModuleGlobalInfo block
void ParseModuleGlobalInfo ();
/// @brief Parse a symbol table
void ParseSymbolTable ();
/// This function parses LLVM functions lazily. It obtains the type of the
/// function and records where the body of the function is in the bytecode
/// buffer. The caller can then use the ParseNextFunction and
/// ParseAllFunctionBodies to get handler events for the functions.
/// @brief Parse functions lazily.
void ParseFunctionLazily ();
/// @brief Parse a function body
void ParseFunctionBody (Function* Func);
/// @brief Parse a compaction table
void ParseCompactionTable ();
/// @brief Parse global types
void ParseGlobalTypes ();
/// @brief Parse a basic block (for LLVM 1.0 basic block blocks)
void ParseBasicBlock (unsigned BlockNo);
/// @brief parse an instruction list (for post LLVM 1.0 instruction lists
/// with blocks differentiated by terminating instructions.
unsigned ParseInstructionList();
/// @brief Parse an instruction.
bool ParseInstruction (std::vector<unsigned>& Args);
/// @brief Parse a constant pool
void ParseConstantPool (TypeListTy& List);
/// @brief Parse a constant value
void ParseConstantValue (unsigned TypeID);
/// @brief Parse a block of types.
void ParseTypeConstants (TypeListTy &Tab, unsigned NumEntries);
/// @brief Parse a single type.
const Type *ParseTypeConstant();
/// @brief Parse a string constants block
void ParseStringConstants (unsigned NumEntries);
/// @}
/// @name Data
/// @{
private:
BufPtr MemStart; ///< Start of the memory buffer
BufPtr MemEnd; ///< End of the memory buffer
BufPtr BlockStart; ///< Start of current block being parsed
BufPtr BlockEnd; ///< End of current block being parsed
BufPtr At; ///< Where we're currently parsing at
bool reportAlignment; ///< Parser should report alignment?
bool reportBlocks; ///< Parser should report blocks?
bool reportVBR; ///< Report VBR compression events
// Information about the module, extracted from the bytecode revision number.
unsigned char RevisionNum; // The rev # itself
// Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0)
// Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo
// block. This was fixed to be like all other blocks in 1.2
bool hasInconsistentModuleGlobalInfo;
// Revision #0 also explicitly encoded zero values for primitive types like
// int/sbyte/etc.
bool hasExplicitPrimitiveZeros;
// Flags to control features specific the LLVM 1.2 and before (revision #1)
// LLVM 1.2 and earlier required that getelementptr structure indices were
// ubyte constants and that sequential type indices were longs.
bool hasRestrictedGEPTypes;
/// CompactionTable - If a compaction table is active in the current function,
/// this is the mapping that it contains.
std::vector<Type*> CompactionTypeTable;
// ConstantFwdRefs - This maintains a mapping between <Type, Slot #>'s and
// forward references to constants. Such values may be referenced before they
// are defined, and if so, the temporary object that they represent is held
// here.
//
typedef std::map<std::pair<const Type*,unsigned>, Constant*> ConstantRefsType;
ConstantRefsType ConstantFwdRefs;
// TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used
// to deal with forward references to types.
//
TypeListTy ModuleTypes;
TypeListTy FunctionTypes;
// When the ModuleGlobalInfo section is read, we create a FunctionType object
// for each function in the module. When the function is loaded, this type is
// used to instantiate the actual function object.
std::vector<Function*> FunctionSignatureList;
// Constant values are read in after global variables. Because of this, we
// must defer setting the initializers on global variables until after module
// level constants have been read. In the mean time, this list keeps track of
// what we must do.
//
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
/// @}
/// @name Implementation Details
/// @{
private:
/// This stores the parser's handler. It makes virtual function calls through
/// the BytecodeHandler to notify the handler of parsing events. What the
/// handler does with the events is completely orthogonal to the business of
/// parsing the bytecode.
/// @brief The handler of bytecode parsing events.
BytecodeHandler* handler;
/// For lazy reading-in of functions, we need to save away several pieces of
/// information about each function: its begin and end pointer in the buffer
/// and its FunctionSlot.
struct LazyFunctionInfo {
const unsigned char *Buf, *EndBuf;
LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0)
: Buf(B), EndBuf(EB) {}
};
typedef std::map<Function*, LazyFunctionInfo> LazyFunctionMap;
LazyFunctionMap LazyFunctionLoadMap;
private:
/// Is there more to parse in the current block?
inline bool moreInBlock();
/// Have we read past the end of the block
inline void checkPastBlockEnd(const char * block_name);
/// Align to 32 bits
inline void align32();
/// Reader interface
inline unsigned read_uint();
inline unsigned read_vbr_uint();
inline uint64_t read_vbr_uint64();
inline int64_t read_vbr_int64();
inline std::string read_str();
inline void read_data(void *Ptr, void *End);
/// Read a block header
inline void readBlock(unsigned &Type, unsigned &Size);
const Type *AbstractBytecodeParser::getType(unsigned ID);
/// getGlobalTableType - This is just like getType, but when a compaction
/// table is in use, it is ignored. Also, no forward references or other
/// fancy features are supported.
const Type *getGlobalTableType(unsigned Slot) {
if (Slot < Type::FirstDerivedTyID) {
const Type *Ty = Type::getPrimitiveType((Type::TypeID)Slot);
assert(Ty && "Not a primitive type ID?");
return Ty;
}
Slot -= Type::FirstDerivedTyID;
if (Slot >= ModuleTypes.size())
throw std::string("Illegal compaction table type reference!");
return ModuleTypes[Slot];
}
unsigned getGlobalTableTypeSlot(const Type *Ty) {
if (Ty->isPrimitiveType())
return Ty->getTypeID();
TypeListTy::iterator I = find(ModuleTypes.begin(),
ModuleTypes.end(), Ty);
if (I == ModuleTypes.end())
throw std::string("Didn't find type in ModuleTypes.");
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
}
AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
/// @}
};
/// This class provides the interface for the handling bytecode events during
/// parsing. The methods on this interface are invoked by the
/// AbstractBytecodeParser as it discovers the content of a bytecode stream.
/// This class provides a a clear separation of concerns between recognizing
/// the semantic units of a bytecode file and deciding what to do with them.
/// The AbstractBytecodeParser recognizes the content of the bytecode file and
/// calls the BytecodeHandler methods to determine what should be done. This
/// arrangement allows Bytecode files to be read and handled for a number of
/// purposes simply by creating a subclass of BytecodeHandler. None of the
/// parsing details need to be understood, only the meaning of the calls
/// made on this interface.
///
/// Another paradigm that uses this design pattern is the XML SAX Parser. The
/// ContentHandler for SAX plays the same role as the BytecodeHandler here.
/// @see AbstractbytecodeParser
/// @brief Handle Bytecode Parsing Events
class BytecodeHandler {
/// @name Constructors And Operators
/// @{
public:
/// @brief Default constructor (empty)
BytecodeHandler() {}
/// @brief Virtual destructor (empty)
virtual ~BytecodeHandler() {}
private:
BytecodeHandler(const BytecodeHandler &); // DO NOT IMPLEMENT
void operator=(const BytecodeHandler &); // DO NOT IMPLEMENT
/// @}
/// @name Handler Methods
/// @{
public:
/// This method is called whenever the parser detects an error in the
/// bytecode formatting. Returning true will cause the parser to keep
/// going, however this is inadvisable in most cases. Returning false will
/// cause the parser to throw the message as a std::string.
/// @brief Handle parsing errors.
virtual bool handleError(const std::string& str );
/// This method is called at the beginning of a parse before anything is
/// read in order to give the handler a chance to initialize.
/// @brief Handle the start of a bytecode parse
virtual void handleStart();
/// This method is called at the end of a parse after everything has been
/// read in order to give the handler a chance to terminate.
/// @brief Handle the end of a bytecode parse
virtual void handleFinish();
/// This method is called at the start of a module to indicate that a
/// module is being parsed.
/// @brief Handle the start of a module.
virtual void handleModuleBegin(const std::string& id);
/// This method is called at the end of a module to indicate that the module
/// previously being parsed has concluded.
/// @brief Handle the end of a module.
virtual void handleModuleEnd(const std::string& id);
/// This method is called once the version information has been parsed. It
/// provides the information about the version of the bytecode file being
/// read.
/// @brief Handle the bytecode prolog
virtual void handleVersionInfo(
unsigned char RevisionNum, ///< Byte code revision number
Module::Endianness Endianness, ///< Endianness indicator
Module::PointerSize PointerSize ///< PointerSize indicator
);
/// This method is called at the start of a module globals block which
/// contains the global variables and the function placeholders
virtual void handleModuleGlobalsBegin();
/// This method is called when a non-initialized global variable is
/// recognized. Its type, constness, and linkage type are provided.
/// @brief Handle a non-initialized global variable
virtual void handleGlobalVariable(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes ///< The linkage type of the GV
);
/// This method is called when an initialized global variable is recognized.
/// Its type constness, linkage type, and the slot number of the initializer
/// are provided.
/// @brief Handle an intialized global variable.
virtual void handleInitializedGV(
const Type* ElemType, ///< The type of the global variable
bool isConstant, ///< Whether the GV is constant or not
GlobalValue::LinkageTypes,///< The linkage type of the GV
unsigned initSlot ///< Slot number of GV's initializer
);
/// This method is called when a new type is recognized. The type is
/// converted from the bytecode and passed to this method.
/// @brief Handle a type
virtual void handleType( const Type* Ty );
/// This method is called when the function prototype for a function is
/// encountered in the module globals block.
virtual void handleFunctionDeclaration(
Function* Func,
const FunctionType* FuncType ///< The type of the function
);
/// This method is called at the end of the module globals block.
/// @brief Handle end of module globals block.
virtual void handleModuleGlobalsEnd();
/// This method is called at the beginning of a compaction table.
/// @brief Handle start of compaction table.
virtual void handleCompactionTableBegin();
/// @brief Handle start of a compaction table plane
virtual void handleCompactionTablePlane(
unsigned Ty,
unsigned NumEntries
);
/// @brief Handle a type entry in the compaction table
virtual void handleCompactionTableType(
unsigned i,
unsigned TypSlot,
const Type*
);
/// @brief Handle a value entry in the compaction table
virtual void handleCompactionTableValue(
unsigned i,
unsigned ValSlot,
const Type*
);
/// @brief Handle end of a compaction table
virtual void handleCompactionTableEnd();
/// @brief Handle start of a symbol table
virtual void handleSymbolTableBegin();
/// @brief Handle start of a symbol table plane
virtual void handleSymbolTablePlane(
unsigned Ty,
unsigned NumEntries,
const Type* Ty
);
/// @brief Handle a named type in the symbol table
virtual void handleSymbolTableType(
unsigned i,
unsigned slot,
const std::string& name
);
/// @brief Handle a named value in the symbol table
virtual void handleSymbolTableValue(
unsigned i,
unsigned slot,
const std::string& name
);
/// @brief Handle the end of a symbol table
virtual void handleSymbolTableEnd();
/// @brief Handle the beginning of a function body
virtual void handleFunctionBegin(
Function* Func, unsigned Size
);
/// @brief Handle the end of a function body
virtual void handleFunctionEnd(
Function* Func
);
/// @brief Handle the beginning of a basic block
virtual void handleBasicBlockBegin(
unsigned blocknum
);
/// This method is called for each instruction that is parsed.
/// @returns true if the instruction is a block terminating instruction
/// @brief Handle an instruction
virtual bool handleInstruction(
unsigned Opcode,
const Type* iType,
std::vector<unsigned>& Operands,
unsigned Length
);
/// @brief Handle the end of a basic block
virtual void handleBasicBlockEnd(unsigned blocknum);
/// @brief Handle start of global constants block.
virtual void handleGlobalConstantsBegin();
/// @brief Handle a constant expression
virtual void handleConstantExpression(
unsigned Opcode,
const Type* Typ,
std::vector<std::pair<const Type*,unsigned> > ArgVec
);
/// @brief Handle a constant array
virtual void handleConstantArray(
const ArrayType* AT,
std::vector<unsigned>& ElementSlots
);
/// @brief Handle a constant structure
virtual void handleConstantStruct(
const StructType* ST,
std::vector<unsigned>& ElementSlots
);
/// @brief Handle a constant pointer
virtual void handleConstantPointer(
const PointerType* PT,
unsigned Slot
);
/// @brief Handle a constant strings (array special case)
virtual void handleConstantString(
const ConstantArray* CA
);
/// @brief Handle a primitive constant value
virtual void handleConstantValue( Constant * c );
/// @brief Handle the end of the global constants
virtual void handleGlobalConstantsEnd();
/// @brief Handle an alignment event
virtual void handleAlignment(unsigned numBytes);
virtual void handleBlock(
unsigned BType, ///< The type of block
const unsigned char* StartPtr, ///< The start of the block
unsigned Size ///< The size of the block
);
virtual void handleVBR32(unsigned Size );
virtual void handleVBR64(unsigned Size );
/// @}
};
} // End llvm namespace
// vim: sw=2
#endif