mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-12 01:46:06 +00:00
Remove trailing whitespace
llvm-svn: 21417
This commit is contained in:
parent
01808caded
commit
2ecc34dd3c
@ -1,10 +1,10 @@
|
|||||||
//===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===//
|
//===-- Analyzer.cpp - Analysis and Dumping of Bytecode 000000---*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by Reid Spencer and is distributed under the
|
// This file was developed by Reid Spencer and is distributed under the
|
||||||
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file implements the AnalyzerHandler class and PrintBytecodeAnalysis
|
// This file implements the AnalyzerHandler class and PrintBytecodeAnalysis
|
||||||
@ -35,7 +35,7 @@ class AnalyzerHandler : public BytecodeHandler {
|
|||||||
BytecodeAnalysis& bca; ///< The structure in which data is recorded
|
BytecodeAnalysis& bca; ///< The structure in which data is recorded
|
||||||
std::ostream* os; ///< A convenience for osing data.
|
std::ostream* os; ///< A convenience for osing data.
|
||||||
/// @brief Keeps track of current function
|
/// @brief Keeps track of current function
|
||||||
BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
|
BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
|
||||||
Module* M; ///< Keeps track of current module
|
Module* M; ///< Keeps track of current module
|
||||||
|
|
||||||
/// @name Constructor
|
/// @name Constructor
|
||||||
@ -44,8 +44,8 @@ public:
|
|||||||
/// The only way to construct an AnalyzerHandler. All that is needed is a
|
/// The only way to construct an AnalyzerHandler. All that is needed is a
|
||||||
/// reference to the BytecodeAnalysis structure where the output will be
|
/// reference to the BytecodeAnalysis structure where the output will be
|
||||||
/// placed.
|
/// placed.
|
||||||
AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output)
|
AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output)
|
||||||
: bca(TheBca)
|
: bca(TheBca)
|
||||||
, os(output)
|
, os(output)
|
||||||
, currFunc(0)
|
, currFunc(0)
|
||||||
{ }
|
{ }
|
||||||
@ -54,7 +54,7 @@ public:
|
|||||||
/// @name BytecodeHandler Implementations
|
/// @name BytecodeHandler Implementations
|
||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
virtual void handleError(const std::string& str ) {
|
virtual void handleError(const std::string& str ) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << "ERROR: " << str << "\n";
|
*os << "ERROR: " << str << "\n";
|
||||||
}
|
}
|
||||||
@ -104,16 +104,16 @@ public:
|
|||||||
|
|
||||||
virtual void handleFinish() {
|
virtual void handleFinish() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << "} End Bytecode\n";
|
*os << "} End Bytecode\n";
|
||||||
|
|
||||||
bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
|
bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
|
||||||
double globalSize = 0.0;
|
double globalSize = 0.0;
|
||||||
globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]);
|
globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]);
|
||||||
globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]);
|
globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]);
|
||||||
globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]);
|
globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]);
|
||||||
bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
|
bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
|
||||||
bca.numGlobalVars );
|
bca.numGlobalVars );
|
||||||
bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) /
|
bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) /
|
||||||
double(bca.numFunctions);
|
double(bca.numFunctions);
|
||||||
|
|
||||||
if ( bca.progressiveVerify ) {
|
if ( bca.progressiveVerify ) {
|
||||||
@ -131,7 +131,7 @@ public:
|
|||||||
bca.ModuleId = id;
|
bca.ModuleId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleModuleEnd(const std::string& id) {
|
virtual void handleModuleEnd(const std::string& id) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } End Module " << id << "\n";
|
*os << " } End Module " << id << "\n";
|
||||||
if ( bca.progressiveVerify ) {
|
if ( bca.progressiveVerify ) {
|
||||||
@ -147,22 +147,22 @@ public:
|
|||||||
unsigned char RevisionNum, ///< Byte code revision number
|
unsigned char RevisionNum, ///< Byte code revision number
|
||||||
Module::Endianness Endianness, ///< Endianness indicator
|
Module::Endianness Endianness, ///< Endianness indicator
|
||||||
Module::PointerSize PointerSize ///< PointerSize indicator
|
Module::PointerSize PointerSize ///< PointerSize indicator
|
||||||
) {
|
) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " RevisionNum: " << int(RevisionNum)
|
*os << " RevisionNum: " << int(RevisionNum)
|
||||||
<< " Endianness: " << Endianness
|
<< " Endianness: " << Endianness
|
||||||
<< " PointerSize: " << PointerSize << "\n";
|
<< " PointerSize: " << PointerSize << "\n";
|
||||||
bca.version = RevisionNum;
|
bca.version = RevisionNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleModuleGlobalsBegin() {
|
virtual void handleModuleGlobalsBegin() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " BLOCK: ModuleGlobalInfo {\n";
|
*os << " BLOCK: ModuleGlobalInfo {\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleGlobalVariable(
|
virtual void handleGlobalVariable(
|
||||||
const Type* ElemType,
|
const Type* ElemType,
|
||||||
bool isConstant,
|
bool isConstant,
|
||||||
GlobalValue::LinkageTypes Linkage,
|
GlobalValue::LinkageTypes Linkage,
|
||||||
unsigned SlotNum,
|
unsigned SlotNum,
|
||||||
unsigned initSlot
|
unsigned initSlot
|
||||||
@ -173,7 +173,7 @@ public:
|
|||||||
<< ( isConstant? "Constant, " : "Variable, ")
|
<< ( isConstant? "Constant, " : "Variable, ")
|
||||||
<< " Linkage=" << Linkage << " Type=";
|
<< " Linkage=" << Linkage << " Type=";
|
||||||
WriteTypeSymbolic(*os, ElemType, M);
|
WriteTypeSymbolic(*os, ElemType, M);
|
||||||
*os << " Slot=" << SlotNum << " InitSlot=" << initSlot
|
*os << " Slot=" << SlotNum << " InitSlot=" << initSlot
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,8 +190,8 @@ public:
|
|||||||
bca.maxTypeSlot = numEntries - 1;
|
bca.maxTypeSlot = numEntries - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleType( const Type* Ty ) {
|
virtual void handleType( const Type* Ty ) {
|
||||||
bca.numTypes++;
|
bca.numTypes++;
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " Type: ";
|
*os << " Type: ";
|
||||||
WriteTypeSymbolic(*os,Ty,M);
|
WriteTypeSymbolic(*os,Ty,M);
|
||||||
@ -199,7 +199,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleFunctionDeclaration(
|
virtual void handleFunctionDeclaration(
|
||||||
Function* Func ///< The function
|
Function* Func ///< The function
|
||||||
) {
|
) {
|
||||||
bca.numFunctions++;
|
bca.numFunctions++;
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
*os << " Library: '" << libName << "'\n";
|
*os << " Library: '" << libName << "'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleModuleGlobalsEnd() {
|
virtual void handleModuleGlobalsEnd() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } END BLOCK: ModuleGlobalInfo\n";
|
*os << " } END BLOCK: ModuleGlobalInfo\n";
|
||||||
if ( bca.progressiveVerify ) {
|
if ( bca.progressiveVerify ) {
|
||||||
@ -240,7 +240,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleCompactionTableBegin() {
|
virtual void handleCompactionTableBegin() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " BLOCK: CompactionTable {\n";
|
*os << " BLOCK: CompactionTable {\n";
|
||||||
bca.numCmpctnTables++;
|
bca.numCmpctnTables++;
|
||||||
@ -251,53 +251,53 @@ public:
|
|||||||
*os << " Plane: Ty=" << Ty << " Size=" << NumEntries << "\n";
|
*os << " Plane: Ty=" << Ty << " Size=" << NumEntries << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
|
virtual void handleCompactionTableType( unsigned i, unsigned TypSlot,
|
||||||
const Type* Ty ) {
|
const Type* Ty ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " Type: " << i << " Slot:" << TypSlot << " is ";
|
*os << " Type: " << i << " Slot:" << TypSlot << " is ";
|
||||||
WriteTypeSymbolic(*os,Ty,M);
|
WriteTypeSymbolic(*os,Ty,M);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot,
|
virtual void handleCompactionTableValue(unsigned i, unsigned TypSlot,
|
||||||
unsigned ValSlot) {
|
unsigned ValSlot) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " Value: " << i << " TypSlot: " << TypSlot
|
*os << " Value: " << i << " TypSlot: " << TypSlot
|
||||||
<< " ValSlot:" << ValSlot << "\n";
|
<< " ValSlot:" << ValSlot << "\n";
|
||||||
if (ValSlot > bca.maxValueSlot)
|
if (ValSlot > bca.maxValueSlot)
|
||||||
bca.maxValueSlot = ValSlot;
|
bca.maxValueSlot = ValSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleCompactionTableEnd() {
|
virtual void handleCompactionTableEnd() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } END BLOCK: CompactionTable\n";
|
*os << " } END BLOCK: CompactionTable\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleSymbolTableBegin(Function* CF, SymbolTable* ST) {
|
virtual void handleSymbolTableBegin(Function* CF, SymbolTable* ST) {
|
||||||
bca.numSymTab++;
|
bca.numSymTab++;
|
||||||
if (os)
|
if (os)
|
||||||
*os << " BLOCK: SymbolTable {\n";
|
*os << " BLOCK: SymbolTable {\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleSymbolTablePlane(unsigned Ty, unsigned NumEntries,
|
virtual void handleSymbolTablePlane(unsigned Ty, unsigned NumEntries,
|
||||||
const Type* Typ) {
|
const Type* Typ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " Plane: Ty=" << Ty << " Size=" << NumEntries << " Type: ";
|
*os << " Plane: Ty=" << Ty << " Size=" << NumEntries << " Type: ";
|
||||||
WriteTypeSymbolic(*os,Typ,M);
|
WriteTypeSymbolic(*os,Typ,M);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleSymbolTableType(unsigned i, unsigned TypSlot,
|
virtual void handleSymbolTableType(unsigned i, unsigned TypSlot,
|
||||||
const std::string& name ) {
|
const std::string& name ) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " Type " << i << " Slot=" << TypSlot
|
*os << " Type " << i << " Slot=" << TypSlot
|
||||||
<< " Name: " << name << "\n";
|
<< " Name: " << name << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleSymbolTableValue(unsigned i, unsigned ValSlot,
|
virtual void handleSymbolTableValue(unsigned i, unsigned ValSlot,
|
||||||
const std::string& name ) {
|
const std::string& name ) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " Value " << i << " Slot=" << ValSlot
|
*os << " Value " << i << " Slot=" << ValSlot
|
||||||
<< " Name: " << name << "\n";
|
<< " Name: " << name << "\n";
|
||||||
@ -305,7 +305,7 @@ public:
|
|||||||
bca.maxValueSlot = ValSlot;
|
bca.maxValueSlot = ValSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleSymbolTableEnd() {
|
virtual void handleSymbolTableEnd() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } END BLOCK: SymbolTable\n";
|
*os << " } END BLOCK: SymbolTable\n";
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ public:
|
|||||||
if (os) {
|
if (os) {
|
||||||
*os << " BLOCK: Function {\n"
|
*os << " BLOCK: Function {\n"
|
||||||
<< " Linkage: " << Func->getLinkage() << "\n"
|
<< " Linkage: " << Func->getLinkage() << "\n"
|
||||||
<< " Type: ";
|
<< " Type: ";
|
||||||
WriteTypeSymbolic(*os,Func->getType(),M);
|
WriteTypeSymbolic(*os,Func->getType(),M);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
@ -362,14 +362,14 @@ public:
|
|||||||
if ( currFunc ) currFunc->numBasicBlocks++;
|
if ( currFunc ) currFunc->numBasicBlocks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool handleInstruction( unsigned Opcode, const Type* iType,
|
virtual bool handleInstruction( unsigned Opcode, const Type* iType,
|
||||||
std::vector<unsigned>& Operands, unsigned Size){
|
std::vector<unsigned>& Operands, unsigned Size){
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " INST: OpCode="
|
*os << " INST: OpCode="
|
||||||
<< Instruction::getOpcodeName(Opcode) << " Type=\"";
|
<< Instruction::getOpcodeName(Opcode) << " Type=\"";
|
||||||
WriteTypeSymbolic(*os,iType,M);
|
WriteTypeSymbolic(*os,iType,M);
|
||||||
*os << "\"";
|
*os << "\"";
|
||||||
for ( unsigned i = 0; i < Operands.size(); ++i )
|
for ( unsigned i = 0; i < Operands.size(); ++i )
|
||||||
*os << " Op(" << i << ")=Slot(" << Operands[i] << ")";
|
*os << " Op(" << i << ")=Slot(" << Operands[i] << ")";
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
@ -388,25 +388,25 @@ public:
|
|||||||
if (Size > 4 ) currFunc->longInstructions++;
|
if (Size > 4 ) currFunc->longInstructions++;
|
||||||
if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
|
if ( Opcode == Instruction::PHI ) currFunc->numPhis++;
|
||||||
}
|
}
|
||||||
return Instruction::isTerminator(Opcode);
|
return Instruction::isTerminator(Opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleBasicBlockEnd(unsigned blocknum) {
|
virtual void handleBasicBlockEnd(unsigned blocknum) {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } END BLOCK: BasicBlock #" << blocknum << "{\n";
|
*os << " } END BLOCK: BasicBlock #" << blocknum << "{\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleGlobalConstantsBegin() {
|
virtual void handleGlobalConstantsBegin() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " BLOCK: GlobalConstants {\n";
|
*os << " BLOCK: GlobalConstants {\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleConstantExpression( unsigned Opcode,
|
virtual void handleConstantExpression( unsigned Opcode,
|
||||||
std::vector<Constant*> ArgVec, Constant* C ) {
|
std::vector<Constant*> ArgVec, Constant* C ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " EXPR: " << Instruction::getOpcodeName(Opcode) << "\n";
|
*os << " EXPR: " << Instruction::getOpcodeName(Opcode) << "\n";
|
||||||
for ( unsigned i = 0; i < ArgVec.size(); ++i ) {
|
for ( unsigned i = 0; i < ArgVec.size(); ++i ) {
|
||||||
*os << " Arg#" << i << " "; ArgVec[i]->print(*os);
|
*os << " Arg#" << i << " "; ArgVec[i]->print(*os);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
*os << " Value=";
|
*os << " Value=";
|
||||||
@ -427,13 +427,13 @@ public:
|
|||||||
bca.numValues++;
|
bca.numValues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleConstantArray( const ArrayType* AT,
|
virtual void handleConstantArray( const ArrayType* AT,
|
||||||
std::vector<Constant*>& Elements,
|
std::vector<Constant*>& Elements,
|
||||||
unsigned TypeSlot,
|
unsigned TypeSlot,
|
||||||
Constant* ArrayVal ) {
|
Constant* ArrayVal ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " ARRAY: ";
|
*os << " ARRAY: ";
|
||||||
WriteTypeSymbolic(*os,AT,M);
|
WriteTypeSymbolic(*os,AT,M);
|
||||||
*os << " TypeSlot=" << TypeSlot << "\n";
|
*os << " TypeSlot=" << TypeSlot << "\n";
|
||||||
for ( unsigned i = 0; i < Elements.size(); ++i ) {
|
for ( unsigned i = 0; i < Elements.size(); ++i ) {
|
||||||
*os << " #" << i;
|
*os << " #" << i;
|
||||||
@ -459,7 +459,7 @@ public:
|
|||||||
WriteTypeSymbolic(*os,ST,M);
|
WriteTypeSymbolic(*os,ST,M);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
for ( unsigned i = 0; i < Elements.size(); ++i ) {
|
for ( unsigned i = 0; i < Elements.size(); ++i ) {
|
||||||
*os << " #" << i << " "; Elements[i]->print(*os);
|
*os << " #" << i << " "; Elements[i]->print(*os);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
*os << " Value=";
|
*os << " Value=";
|
||||||
@ -470,11 +470,11 @@ public:
|
|||||||
bca.numValues++;
|
bca.numValues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleConstantPacked(
|
virtual void handleConstantPacked(
|
||||||
const PackedType* PT,
|
const PackedType* PT,
|
||||||
std::vector<Constant*>& Elements,
|
std::vector<Constant*>& Elements,
|
||||||
unsigned TypeSlot,
|
unsigned TypeSlot,
|
||||||
Constant* PackedVal)
|
Constant* PackedVal)
|
||||||
{
|
{
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " PACKD: ";
|
*os << " PACKD: ";
|
||||||
@ -494,7 +494,7 @@ public:
|
|||||||
bca.numValues++;
|
bca.numValues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleConstantPointer( const PointerType* PT,
|
virtual void handleConstantPointer( const PointerType* PT,
|
||||||
unsigned Slot, GlobalValue* GV ) {
|
unsigned Slot, GlobalValue* GV ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " PNTR: ";
|
*os << " PNTR: ";
|
||||||
@ -510,14 +510,14 @@ public:
|
|||||||
virtual void handleConstantString( const ConstantArray* CA ) {
|
virtual void handleConstantString( const ConstantArray* CA ) {
|
||||||
if (os) {
|
if (os) {
|
||||||
*os << " STRNG: ";
|
*os << " STRNG: ";
|
||||||
CA->print(*os);
|
CA->print(*os);
|
||||||
*os << "\n";
|
*os << "\n";
|
||||||
}
|
}
|
||||||
bca.numConstants++;
|
bca.numConstants++;
|
||||||
bca.numValues++;
|
bca.numValues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handleGlobalConstantsEnd() {
|
virtual void handleGlobalConstantsEnd() {
|
||||||
if (os)
|
if (os)
|
||||||
*os << " } END BLOCK: GlobalConstants\n";
|
*os << " } END BLOCK: GlobalConstants\n";
|
||||||
|
|
||||||
@ -574,38 +574,38 @@ public:
|
|||||||
|
|
||||||
/// @brief Utility for printing a titled unsigned value with
|
/// @brief Utility for printing a titled unsigned value with
|
||||||
/// an aligned colon.
|
/// an aligned colon.
|
||||||
inline static void print(std::ostream& Out, const char*title,
|
inline static void print(std::ostream& Out, const char*title,
|
||||||
unsigned val, bool nl = true ) {
|
unsigned val, bool nl = true ) {
|
||||||
Out << std::setw(30) << std::right << title
|
Out << std::setw(30) << std::right << title
|
||||||
<< std::setw(0) << ": "
|
<< std::setw(0) << ": "
|
||||||
<< std::setw(9) << val << "\n";
|
<< std::setw(9) << val << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Utility for printing a titled double value with an
|
/// @brief Utility for printing a titled double value with an
|
||||||
/// aligned colon
|
/// aligned colon
|
||||||
inline static void print(std::ostream&Out, const char*title,
|
inline static void print(std::ostream&Out, const char*title,
|
||||||
double val ) {
|
double val ) {
|
||||||
Out << std::setw(30) << std::right << title
|
Out << std::setw(30) << std::right << title
|
||||||
<< std::setw(0) << ": "
|
<< std::setw(0) << ": "
|
||||||
<< std::setw(9) << std::setprecision(6) << val << "\n" ;
|
<< std::setw(9) << std::setprecision(6) << val << "\n" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Utility for printing a titled double value with a
|
/// @brief Utility for printing a titled double value with a
|
||||||
/// percentage and aligned colon.
|
/// percentage and aligned colon.
|
||||||
inline static void print(std::ostream&Out, const char*title,
|
inline static void print(std::ostream&Out, const char*title,
|
||||||
double top, double bot ) {
|
double top, double bot ) {
|
||||||
Out << std::setw(30) << std::right << title
|
Out << std::setw(30) << std::right << title
|
||||||
<< std::setw(0) << ": "
|
<< std::setw(0) << ": "
|
||||||
<< std::setw(9) << std::setprecision(6) << top
|
<< std::setw(9) << std::setprecision(6) << top
|
||||||
<< " (" << std::left << std::setw(0) << std::setprecision(4)
|
<< " (" << std::left << std::setw(0) << std::setprecision(4)
|
||||||
<< (top/bot)*100.0 << "%)\n";
|
<< (top/bot)*100.0 << "%)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Utility for printing a titled string value with
|
/// @brief Utility for printing a titled string value with
|
||||||
/// an aligned colon.
|
/// an aligned colon.
|
||||||
inline static void print(std::ostream&Out, const char*title,
|
inline static void print(std::ostream&Out, const char*title,
|
||||||
std::string val, bool nl = true) {
|
std::string val, bool nl = true) {
|
||||||
Out << std::setw(30) << std::right << title
|
Out << std::setw(30) << std::right << title
|
||||||
<< std::setw(0) << ": "
|
<< std::setw(0) << ": "
|
||||||
<< std::left << val << (nl ? "\n" : "");
|
<< std::left << val << (nl ? "\n" : "");
|
||||||
}
|
}
|
||||||
@ -626,33 +626,33 @@ void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
|
|||||||
print(Out, "Module Bytes",
|
print(Out, "Module Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Function Bytes",
|
print(Out, "Function Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Global Types Bytes",
|
print(Out, "Global Types Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Constant Pool Bytes",
|
print(Out, "Constant Pool Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Module Globals Bytes",
|
print(Out, "Module Globals Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Instruction List Bytes",
|
print(Out, "Instruction List Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Compaction Table Bytes",
|
print(Out, "Compaction Table Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::CompactionTableBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::CompactionTableBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Symbol Table Bytes",
|
print(Out, "Symbol Table Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::SymbolTableBlockID]),
|
double(bca.BlockSizes[BytecodeFormat::SymbolTableBlockID]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Alignment Bytes",
|
print(Out, "Alignment Bytes",
|
||||||
double(bca.numAlignment), double(bca.byteSize));
|
double(bca.numAlignment), double(bca.byteSize));
|
||||||
print(Out, "Block Header Bytes",
|
print(Out, "Block Header Bytes",
|
||||||
double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]),
|
double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Dependent Libraries Bytes", double(bca.libSize),
|
print(Out, "Dependent Libraries Bytes", double(bca.libSize),
|
||||||
double(bca.byteSize));
|
double(bca.byteSize));
|
||||||
print(Out, "Number Of Bytecode Blocks", bca.numBlocks);
|
print(Out, "Number Of Bytecode Blocks", bca.numBlocks);
|
||||||
print(Out, "Number Of Functions", bca.numFunctions);
|
print(Out, "Number Of Functions", bca.numFunctions);
|
||||||
@ -668,7 +668,7 @@ void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
|
|||||||
print(Out, "Number Of Symbol Tables", bca.numSymTab);
|
print(Out, "Number Of Symbol Tables", bca.numSymTab);
|
||||||
print(Out, "Number Of Dependent Libs", bca.numLibraries);
|
print(Out, "Number Of Dependent Libs", bca.numLibraries);
|
||||||
print(Out, "Total Instruction Size", bca.instructionSize);
|
print(Out, "Total Instruction Size", bca.instructionSize);
|
||||||
print(Out, "Average Instruction Size",
|
print(Out, "Average Instruction Size",
|
||||||
double(bca.instructionSize)/double(bca.numInstructions));
|
double(bca.instructionSize)/double(bca.numInstructions));
|
||||||
|
|
||||||
print(Out, "Maximum Type Slot Number", bca.maxTypeSlot);
|
print(Out, "Maximum Type Slot Number", bca.maxTypeSlot);
|
||||||
@ -680,16 +680,16 @@ void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
|
|||||||
print(Out, "# of VBR 64-bit Integers", bca.vbrCount64);
|
print(Out, "# of VBR 64-bit Integers", bca.vbrCount64);
|
||||||
print(Out, "# of VBR Compressed Bytes", bca.vbrCompBytes);
|
print(Out, "# of VBR Compressed Bytes", bca.vbrCompBytes);
|
||||||
print(Out, "# of VBR Expanded Bytes", bca.vbrExpdBytes);
|
print(Out, "# of VBR Expanded Bytes", bca.vbrExpdBytes);
|
||||||
print(Out, "Bytes Saved With VBR",
|
print(Out, "Bytes Saved With VBR",
|
||||||
double(bca.vbrExpdBytes)-double(bca.vbrCompBytes),
|
double(bca.vbrExpdBytes)-double(bca.vbrCompBytes),
|
||||||
double(bca.vbrExpdBytes));
|
double(bca.vbrExpdBytes));
|
||||||
|
|
||||||
if (bca.detailedResults) {
|
if (bca.detailedResults) {
|
||||||
Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n";
|
Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n";
|
||||||
|
|
||||||
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
|
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
|
||||||
bca.FunctionInfo.begin();
|
bca.FunctionInfo.begin();
|
||||||
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
|
std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
|
||||||
bca.FunctionInfo.end();
|
bca.FunctionInfo.end();
|
||||||
|
|
||||||
while ( I != E ) {
|
while ( I != E ) {
|
||||||
@ -704,14 +704,14 @@ void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
|
|||||||
print(Out, "Long Instructions", I->second.longInstructions);
|
print(Out, "Long Instructions", I->second.longInstructions);
|
||||||
print(Out, "Operands", I->second.numOperands);
|
print(Out, "Operands", I->second.numOperands);
|
||||||
print(Out, "Instruction Size", I->second.instructionSize);
|
print(Out, "Instruction Size", I->second.instructionSize);
|
||||||
print(Out, "Average Instruction Size",
|
print(Out, "Average Instruction Size",
|
||||||
double(I->second.instructionSize) / I->second.numInstructions);
|
double(I->second.instructionSize) / I->second.numInstructions);
|
||||||
print(Out, "Bytes Per Instruction", I->second.density);
|
print(Out, "Bytes Per Instruction", I->second.density);
|
||||||
print(Out, "# of VBR 32-bit Integers", I->second.vbrCount32);
|
print(Out, "# of VBR 32-bit Integers", I->second.vbrCount32);
|
||||||
print(Out, "# of VBR 64-bit Integers", I->second.vbrCount64);
|
print(Out, "# of VBR 64-bit Integers", I->second.vbrCount64);
|
||||||
print(Out, "# of VBR Compressed Bytes", I->second.vbrCompBytes);
|
print(Out, "# of VBR Compressed Bytes", I->second.vbrCompBytes);
|
||||||
print(Out, "# of VBR Expanded Bytes", I->second.vbrExpdBytes);
|
print(Out, "# of VBR Expanded Bytes", I->second.vbrExpdBytes);
|
||||||
print(Out, "Bytes Saved With VBR",
|
print(Out, "Bytes Saved With VBR",
|
||||||
double(I->second.vbrExpdBytes) - I->second.vbrCompBytes),
|
double(I->second.vbrExpdBytes) - I->second.vbrCompBytes),
|
||||||
double(I->second.vbrExpdBytes);
|
double(I->second.vbrExpdBytes);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
//===- Reader.cpp - Code to read bytecode files ---------------------------===//
|
//===- Reader.cpp - Code to read bytecode files ---------------------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// 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.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This library implements the functionality defined in llvm/Bytecode/Reader.h
|
// This library implements the functionality defined in llvm/Bytecode/Reader.h
|
||||||
//
|
//
|
||||||
// Note that this library should be as fast as possible, reentrant, and
|
// Note that this library should be as fast as possible, reentrant, and
|
||||||
// threadsafe!!
|
// threadsafe!!
|
||||||
//
|
//
|
||||||
// TODO: Allow passing in an option to ignore the symbol table
|
// TODO: Allow passing in an option to ignore the symbol table
|
||||||
@ -39,7 +39,7 @@ namespace {
|
|||||||
void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
|
void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
|
||||||
public:
|
public:
|
||||||
Use Op;
|
Use Op;
|
||||||
ConstantPlaceHolder(const Type *Ty)
|
ConstantPlaceHolder(const Type *Ty)
|
||||||
: ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
|
: ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
|
||||||
Op(UndefValue::get(Type::IntTy), this) {
|
Op(UndefValue::get(Type::IntTy), this) {
|
||||||
}
|
}
|
||||||
@ -77,16 +77,16 @@ inline void BytecodeReader::align32() {
|
|||||||
if (hasAlignment) {
|
if (hasAlignment) {
|
||||||
BufPtr Save = At;
|
BufPtr Save = At;
|
||||||
At = (const unsigned char *)((unsigned long)(At+3) & (~3UL));
|
At = (const unsigned char *)((unsigned long)(At+3) & (~3UL));
|
||||||
if (At > Save)
|
if (At > Save)
|
||||||
if (Handler) Handler->handleAlignment(At - Save);
|
if (Handler) Handler->handleAlignment(At - Save);
|
||||||
if (At > BlockEnd)
|
if (At > BlockEnd)
|
||||||
error("Ran out of data while aligning!");
|
error("Ran out of data while aligning!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a whole unsigned integer
|
/// Read a whole unsigned integer
|
||||||
inline unsigned BytecodeReader::read_uint() {
|
inline unsigned BytecodeReader::read_uint() {
|
||||||
if (At+4 > BlockEnd)
|
if (At+4 > BlockEnd)
|
||||||
error("Ran out of data reading uint!");
|
error("Ran out of data reading uint!");
|
||||||
At += 4;
|
At += 4;
|
||||||
return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24);
|
return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24);
|
||||||
@ -97,9 +97,9 @@ inline unsigned BytecodeReader::read_vbr_uint() {
|
|||||||
unsigned Shift = 0;
|
unsigned Shift = 0;
|
||||||
unsigned Result = 0;
|
unsigned Result = 0;
|
||||||
BufPtr Save = At;
|
BufPtr Save = At;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (At == BlockEnd)
|
if (At == BlockEnd)
|
||||||
error("Ran out of data reading vbr_uint!");
|
error("Ran out of data reading vbr_uint!");
|
||||||
Result |= (unsigned)((*At++) & 0x7F) << Shift;
|
Result |= (unsigned)((*At++) & 0x7F) << Shift;
|
||||||
Shift += 7;
|
Shift += 7;
|
||||||
@ -113,9 +113,9 @@ inline uint64_t BytecodeReader::read_vbr_uint64() {
|
|||||||
unsigned Shift = 0;
|
unsigned Shift = 0;
|
||||||
uint64_t Result = 0;
|
uint64_t Result = 0;
|
||||||
BufPtr Save = At;
|
BufPtr Save = At;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (At == BlockEnd)
|
if (At == BlockEnd)
|
||||||
error("Ran out of data reading vbr_uint64!");
|
error("Ran out of data reading vbr_uint64!");
|
||||||
Result |= (uint64_t)((*At++) & 0x7F) << Shift;
|
Result |= (uint64_t)((*At++) & 0x7F) << Shift;
|
||||||
Shift += 7;
|
Shift += 7;
|
||||||
@ -151,7 +151,7 @@ inline std::string BytecodeReader::read_str() {
|
|||||||
inline void BytecodeReader::read_data(void *Ptr, void *End) {
|
inline void BytecodeReader::read_data(void *Ptr, void *End) {
|
||||||
unsigned char *Start = (unsigned char *)Ptr;
|
unsigned char *Start = (unsigned char *)Ptr;
|
||||||
unsigned Amount = (unsigned char *)End - Start;
|
unsigned Amount = (unsigned char *)End - Start;
|
||||||
if (At+Amount > BlockEnd)
|
if (At+Amount > BlockEnd)
|
||||||
error("Ran out of data!");
|
error("Ran out of data!");
|
||||||
std::copy(At, At+Amount, Start);
|
std::copy(At, At+Amount, Start);
|
||||||
At += Amount;
|
At += Amount;
|
||||||
@ -178,9 +178,9 @@ inline void BytecodeReader::read_double(double& DoubleVal) {
|
|||||||
double d;
|
double d;
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
} DoubleUnion;
|
} DoubleUnion;
|
||||||
DoubleUnion.i = (uint64_t(At[0]) << 0) | (uint64_t(At[1]) << 8) |
|
DoubleUnion.i = (uint64_t(At[0]) << 0) | (uint64_t(At[1]) << 8) |
|
||||||
(uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
|
(uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
|
||||||
(uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
|
(uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
|
||||||
(uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56);
|
(uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56);
|
||||||
At+=sizeof(uint64_t);
|
At+=sizeof(uint64_t);
|
||||||
DoubleVal = DoubleUnion.d;
|
DoubleVal = DoubleUnion.d;
|
||||||
@ -192,10 +192,10 @@ inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
|
|||||||
Type = read_uint();
|
Type = read_uint();
|
||||||
Size = read_uint();
|
Size = read_uint();
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case BytecodeFormat::Reserved_DoNotUse :
|
case BytecodeFormat::Reserved_DoNotUse :
|
||||||
error("Reserved_DoNotUse used as Module Type?");
|
error("Reserved_DoNotUse used as Module Type?");
|
||||||
Type = BytecodeFormat::ModuleBlockID; break;
|
Type = BytecodeFormat::ModuleBlockID; break;
|
||||||
case BytecodeFormat::Module:
|
case BytecodeFormat::Module:
|
||||||
Type = BytecodeFormat::ModuleBlockID; break;
|
Type = BytecodeFormat::ModuleBlockID; break;
|
||||||
case BytecodeFormat::Function:
|
case BytecodeFormat::Function:
|
||||||
Type = BytecodeFormat::FunctionBlockID; break;
|
Type = BytecodeFormat::FunctionBlockID; break;
|
||||||
@ -238,8 +238,8 @@ inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
|
|||||||
/// 1.3 this changed so that Type does not derive from Value. Consequently,
|
/// 1.3 this changed so that Type does not derive from Value. Consequently,
|
||||||
/// the BytecodeReader's containers for Values can't contain Types because
|
/// the BytecodeReader's containers for Values can't contain Types because
|
||||||
/// there's no inheritance relationship. This means that the "Type Type"
|
/// there's no inheritance relationship. This means that the "Type Type"
|
||||||
/// plane is defunct along with the Type::TypeTyID TypeID. In LLVM 1.3
|
/// plane is defunct along with the Type::TypeTyID TypeID. In LLVM 1.3
|
||||||
/// whenever a bytecode construct must have both types and values together,
|
/// whenever a bytecode construct must have both types and values together,
|
||||||
/// the types are always read/written first and then the Values. Furthermore
|
/// the types are always read/written first and then the Values. Furthermore
|
||||||
/// since Type::TypeTyID no longer exists, its value (12) now corresponds to
|
/// since Type::TypeTyID no longer exists, its value (12) now corresponds to
|
||||||
/// Type::LabelTyID. In order to overcome this we must "sanitize" all the
|
/// Type::LabelTyID. In order to overcome this we must "sanitize" all the
|
||||||
@ -249,7 +249,7 @@ inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
|
|||||||
/// larger than 12 (Type::LabelTyID). If the value is exactly 12, then this
|
/// larger than 12 (Type::LabelTyID). If the value is exactly 12, then this
|
||||||
/// function returns true, otherwise false. This helps detect situations
|
/// function returns true, otherwise false. This helps detect situations
|
||||||
/// where the pre 1.3 bytecode is indicating that what follows is a type.
|
/// where the pre 1.3 bytecode is indicating that what follows is a type.
|
||||||
/// @returns true iff type id corresponds to pre 1.3 "type type"
|
/// @returns true iff type id corresponds to pre 1.3 "type type"
|
||||||
inline bool BytecodeReader::sanitizeTypeId(unsigned &TypeId) {
|
inline bool BytecodeReader::sanitizeTypeId(unsigned &TypeId) {
|
||||||
if (hasTypeDerivedFromValue) { /// do nothing if 1.3 or later
|
if (hasTypeDerivedFromValue) { /// do nothing if 1.3 or later
|
||||||
if (TypeId == Type::LabelTyID) {
|
if (TypeId == Type::LabelTyID) {
|
||||||
@ -342,7 +342,7 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
|||||||
if (!CompactionTypes.empty()) {
|
if (!CompactionTypes.empty()) {
|
||||||
for (unsigned i = 0, e = CompactionTypes.size(); i != e; ++i)
|
for (unsigned i = 0, e = CompactionTypes.size(); i != e; ++i)
|
||||||
if (CompactionTypes[i].first == Ty)
|
if (CompactionTypes[i].first == Ty)
|
||||||
return Type::FirstDerivedTyID + i;
|
return Type::FirstDerivedTyID + i;
|
||||||
|
|
||||||
error("Couldn't find type specified in compaction table!");
|
error("Couldn't find type specified in compaction table!");
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
|||||||
FunctionTypes.end(), Ty);
|
FunctionTypes.end(), Ty);
|
||||||
|
|
||||||
if (I != FunctionTypes.end())
|
if (I != FunctionTypes.end())
|
||||||
return Type::FirstDerivedTyID + ModuleTypes.size() +
|
return Type::FirstDerivedTyID + ModuleTypes.size() +
|
||||||
(&*I - &FunctionTypes[0]);
|
(&*I - &FunctionTypes[0]);
|
||||||
|
|
||||||
// Check the module level types now...
|
// Check the module level types now...
|
||||||
@ -390,8 +390,8 @@ unsigned BytecodeReader::getGlobalTableTypeSlot(const Type *Ty) {
|
|||||||
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a value of a given type and slot number, possibly creating
|
/// Retrieve a value of a given type and slot number, possibly creating
|
||||||
/// it if it doesn't already exist.
|
/// it if it doesn't already exist.
|
||||||
Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
|
Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
|
||||||
assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
|
assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
|
||||||
unsigned Num = oNum;
|
unsigned Num = oNum;
|
||||||
@ -424,8 +424,8 @@ Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FunctionValues.size() > type &&
|
if (FunctionValues.size() > type &&
|
||||||
FunctionValues[type] &&
|
FunctionValues[type] &&
|
||||||
Num < FunctionValues[type]->size())
|
Num < FunctionValues[type]->size())
|
||||||
return FunctionValues[type]->getOperand(Num);
|
return FunctionValues[type]->getOperand(Num);
|
||||||
|
|
||||||
@ -447,8 +447,8 @@ Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
|
|||||||
throw "Can't create placeholder for value of type slot #" + utostr(type);
|
throw "Can't create placeholder for value of type slot #" + utostr(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is just like getValue, but when a compaction table is in use, it
|
/// This is just like getValue, but when a compaction table is in use, it
|
||||||
/// is ignored. Also, no forward references or other fancy features are
|
/// is ignored. Also, no forward references or other fancy features are
|
||||||
/// supported.
|
/// supported.
|
||||||
Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) {
|
Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) {
|
||||||
if (SlotNo == 0)
|
if (SlotNo == 0)
|
||||||
@ -467,11 +467,11 @@ Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) {
|
|||||||
SlotNo >= ModuleValues[TyID]->size()) {
|
SlotNo >= ModuleValues[TyID]->size()) {
|
||||||
if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0)
|
if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0)
|
||||||
error("Corrupt compaction table entry!"
|
error("Corrupt compaction table entry!"
|
||||||
+ utostr(TyID) + ", " + utostr(SlotNo) + ": "
|
+ utostr(TyID) + ", " + utostr(SlotNo) + ": "
|
||||||
+ utostr(ModuleValues.size()));
|
+ utostr(ModuleValues.size()));
|
||||||
else
|
else
|
||||||
error("Corrupt compaction table entry!"
|
error("Corrupt compaction table entry!"
|
||||||
+ utostr(TyID) + ", " + utostr(SlotNo) + ": "
|
+ utostr(TyID) + ", " + utostr(SlotNo) + ": "
|
||||||
+ utostr(ModuleValues.size()) + ", "
|
+ utostr(ModuleValues.size()) + ", "
|
||||||
+ utohexstr(reinterpret_cast<uint64_t>(((void*)ModuleValues[TyID])))
|
+ utohexstr(reinterpret_cast<uint64_t>(((void*)ModuleValues[TyID])))
|
||||||
+ ", "
|
+ ", "
|
||||||
@ -483,14 +483,14 @@ Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) {
|
|||||||
/// Just like getValue, except that it returns a null pointer
|
/// Just like getValue, except that it returns a null pointer
|
||||||
/// only on error. It always returns a constant (meaning that if the value is
|
/// only on error. It always returns a constant (meaning that if the value is
|
||||||
/// defined, but is not a constant, that is an error). If the specified
|
/// defined, but is not a constant, that is an error). If the specified
|
||||||
/// constant hasn't been parsed yet, a placeholder is defined and used.
|
/// constant hasn't been parsed yet, a placeholder is defined and used.
|
||||||
/// Later, after the real value is parsed, the placeholder is eliminated.
|
/// Later, after the real value is parsed, the placeholder is eliminated.
|
||||||
Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
||||||
if (Value *V = getValue(TypeSlot, Slot, false))
|
if (Value *V = getValue(TypeSlot, Slot, false))
|
||||||
if (Constant *C = dyn_cast<Constant>(V))
|
if (Constant *C = dyn_cast<Constant>(V))
|
||||||
return C; // If we already have the value parsed, just return it
|
return C; // If we already have the value parsed, just return it
|
||||||
else
|
else
|
||||||
error("Value for slot " + utostr(Slot) +
|
error("Value for slot " + utostr(Slot) +
|
||||||
" is expected to be a constant!");
|
" is expected to be a constant!");
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> Key(TypeSlot, Slot);
|
std::pair<unsigned, unsigned> Key(TypeSlot, Slot);
|
||||||
@ -502,7 +502,7 @@ Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
|||||||
// Create a placeholder for the constant reference and
|
// Create a placeholder for the constant reference and
|
||||||
// keep track of the fact that we have a forward ref to recycle it
|
// keep track of the fact that we have a forward ref to recycle it
|
||||||
Constant *C = new ConstantPlaceHolder(getType(TypeSlot));
|
Constant *C = new ConstantPlaceHolder(getType(TypeSlot));
|
||||||
|
|
||||||
// Keep track of the fact that we have a forward ref to recycle it
|
// Keep track of the fact that we have a forward ref to recycle it
|
||||||
ConstantFwdRefs.insert(I, std::make_pair(Key, C));
|
ConstantFwdRefs.insert(I, std::make_pair(Key, C));
|
||||||
return C;
|
return C;
|
||||||
@ -516,7 +516,7 @@ Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
|||||||
/// As values are created, they are inserted into the appropriate place
|
/// As values are created, they are inserted into the appropriate place
|
||||||
/// with this method. The ValueTable argument must be one of ModuleValues
|
/// with this method. The ValueTable argument must be one of ModuleValues
|
||||||
/// or FunctionValues data members of this class.
|
/// or FunctionValues data members of this class.
|
||||||
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
|
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
|
||||||
ValueTable &ValueTab) {
|
ValueTable &ValueTab) {
|
||||||
assert((!isa<Constant>(Val) || !cast<Constant>(Val)->isNullValue()) ||
|
assert((!isa<Constant>(Val) || !cast<Constant>(Val)->isNullValue()) ||
|
||||||
!hasImplicitNull(type) &&
|
!hasImplicitNull(type) &&
|
||||||
@ -584,7 +584,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
// --------------------------
|
// --------------------------
|
||||||
// 15-08: Resulting type plane
|
// 15-08: Resulting type plane
|
||||||
// 23-16: Operand #1
|
// 23-16: Operand #1
|
||||||
// 31-24: Operand #2
|
// 31-24: Operand #2
|
||||||
//
|
//
|
||||||
iType = (Op >> 8) & 255;
|
iType = (Op >> 8) & 255;
|
||||||
Oprnds[0] = (Op >> 16) & 255;
|
Oprnds[0] = (Op >> 16) & 255;
|
||||||
@ -646,20 +646,20 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
getValue(iType, Oprnds[1]));
|
getValue(iType, Oprnds[1]));
|
||||||
|
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default:
|
default:
|
||||||
if (Result == 0)
|
if (Result == 0)
|
||||||
error("Illegal instruction read!");
|
error("Illegal instruction read!");
|
||||||
break;
|
break;
|
||||||
case Instruction::VAArg:
|
case Instruction::VAArg:
|
||||||
Result = new VAArgInst(getValue(iType, Oprnds[0]),
|
Result = new VAArgInst(getValue(iType, Oprnds[0]),
|
||||||
getSanitizedType(Oprnds[1]));
|
getSanitizedType(Oprnds[1]));
|
||||||
break;
|
break;
|
||||||
case Instruction::VANext:
|
case Instruction::VANext:
|
||||||
Result = new VANextInst(getValue(iType, Oprnds[0]),
|
Result = new VANextInst(getValue(iType, Oprnds[0]),
|
||||||
getSanitizedType(Oprnds[1]));
|
getSanitizedType(Oprnds[1]));
|
||||||
break;
|
break;
|
||||||
case Instruction::Cast:
|
case Instruction::Cast:
|
||||||
Result = new CastInst(getValue(iType, Oprnds[0]),
|
Result = new CastInst(getValue(iType, Oprnds[0]),
|
||||||
getSanitizedType(Oprnds[1]));
|
getSanitizedType(Oprnds[1]));
|
||||||
break;
|
break;
|
||||||
case Instruction::Select:
|
case Instruction::Select:
|
||||||
@ -698,7 +698,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
if (Oprnds.size() == 1)
|
if (Oprnds.size() == 1)
|
||||||
Result = new BranchInst(getBasicBlock(Oprnds[0]));
|
Result = new BranchInst(getBasicBlock(Oprnds[0]));
|
||||||
else if (Oprnds.size() == 3)
|
else if (Oprnds.size() == 3)
|
||||||
Result = new BranchInst(getBasicBlock(Oprnds[0]),
|
Result = new BranchInst(getBasicBlock(Oprnds[0]),
|
||||||
getBasicBlock(Oprnds[1]), getValue(Type::BoolTyID , Oprnds[2]));
|
getBasicBlock(Oprnds[1]), getValue(Type::BoolTyID , Oprnds[2]));
|
||||||
else
|
else
|
||||||
error("Invalid number of operands for a 'br' instruction!");
|
error("Invalid number of operands for a 'br' instruction!");
|
||||||
@ -750,13 +750,13 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
// Read all of the fixed arguments
|
// Read all of the fixed arguments
|
||||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
|
||||||
Params.push_back(getValue(getTypeSlot(FTy->getParamType(i)),Oprnds[i]));
|
Params.push_back(getValue(getTypeSlot(FTy->getParamType(i)),Oprnds[i]));
|
||||||
|
|
||||||
FirstVariableOperand = FTy->getNumParams();
|
FirstVariableOperand = FTy->getNumParams();
|
||||||
|
|
||||||
if ((Oprnds.size()-FirstVariableOperand) & 1)
|
if ((Oprnds.size()-FirstVariableOperand) & 1)
|
||||||
error("Invalid call instruction!"); // Must be pairs of type/value
|
error("Invalid call instruction!"); // Must be pairs of type/value
|
||||||
|
|
||||||
for (unsigned i = FirstVariableOperand, e = Oprnds.size();
|
for (unsigned i = FirstVariableOperand, e = Oprnds.size();
|
||||||
i != e; i += 2)
|
i != e; i += 2)
|
||||||
Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
|
Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
|
||||||
}
|
}
|
||||||
@ -765,16 +765,16 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
if (Oprnds.size() < 3)
|
if (Oprnds.size() < 3)
|
||||||
error("Invalid invoke instruction!");
|
error("Invalid invoke instruction!");
|
||||||
Value *F = getValue(iType, Oprnds[0]);
|
Value *F = getValue(iType, Oprnds[0]);
|
||||||
|
|
||||||
// Check to make sure we have a pointer to function type
|
// Check to make sure we have a pointer to function type
|
||||||
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
||||||
if (PTy == 0)
|
if (PTy == 0)
|
||||||
error("Invoke to non function pointer value!");
|
error("Invoke to non function pointer value!");
|
||||||
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
||||||
if (FTy == 0)
|
if (FTy == 0)
|
||||||
error("Invoke to non function pointer value!");
|
error("Invoke to non function pointer value!");
|
||||||
|
|
||||||
std::vector<Value *> Params;
|
std::vector<Value *> Params;
|
||||||
@ -797,12 +797,12 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
|
|
||||||
Normal = getBasicBlock(Oprnds[0]);
|
Normal = getBasicBlock(Oprnds[0]);
|
||||||
Except = getBasicBlock(Oprnds[1]);
|
Except = getBasicBlock(Oprnds[1]);
|
||||||
|
|
||||||
unsigned FirstVariableArgument = FTy->getNumParams()+2;
|
unsigned FirstVariableArgument = FTy->getNumParams()+2;
|
||||||
for (unsigned i = 2; i != FirstVariableArgument; ++i)
|
for (unsigned i = 2; i != FirstVariableArgument; ++i)
|
||||||
Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
|
Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
|
||||||
Oprnds[i]));
|
Oprnds[i]));
|
||||||
|
|
||||||
if (Oprnds.size()-FirstVariableArgument & 1) // Must be type/value pairs
|
if (Oprnds.size()-FirstVariableArgument & 1) // Must be type/value pairs
|
||||||
error("Invalid invoke instruction!");
|
error("Invalid invoke instruction!");
|
||||||
|
|
||||||
@ -814,7 +814,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::Malloc:
|
case Instruction::Malloc:
|
||||||
if (Oprnds.size() > 2)
|
if (Oprnds.size() > 2)
|
||||||
error("Invalid malloc instruction!");
|
error("Invalid malloc instruction!");
|
||||||
if (!isa<PointerType>(InstTy))
|
if (!isa<PointerType>(InstTy))
|
||||||
error("Invalid malloc instruction!");
|
error("Invalid malloc instruction!");
|
||||||
@ -825,13 +825,13 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction::Alloca:
|
case Instruction::Alloca:
|
||||||
if (Oprnds.size() > 2)
|
if (Oprnds.size() > 2)
|
||||||
error("Invalid alloca instruction!");
|
error("Invalid alloca instruction!");
|
||||||
if (!isa<PointerType>(InstTy))
|
if (!isa<PointerType>(InstTy))
|
||||||
error("Invalid alloca instruction!");
|
error("Invalid alloca instruction!");
|
||||||
|
|
||||||
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
||||||
Oprnds.size() ? getValue(Type::UIntTyID,
|
Oprnds.size() ? getValue(Type::UIntTyID,
|
||||||
Oprnds[0]) :0);
|
Oprnds[0]) :0);
|
||||||
break;
|
break;
|
||||||
case Instruction::Free:
|
case Instruction::Free:
|
||||||
@ -848,8 +848,8 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
const Type *NextTy = InstTy;
|
const Type *NextTy = InstTy;
|
||||||
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
||||||
const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
|
const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
|
||||||
if (!TopTy)
|
if (!TopTy)
|
||||||
error("Invalid getelementptr instruction!");
|
error("Invalid getelementptr instruction!");
|
||||||
|
|
||||||
unsigned ValIdx = Oprnds[i];
|
unsigned ValIdx = Oprnds[i];
|
||||||
unsigned IdxTy = 0;
|
unsigned IdxTy = 0;
|
||||||
@ -894,7 +894,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62);
|
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 63: // volatile store
|
case 63: // volatile store
|
||||||
case Instruction::Store: {
|
case Instruction::Store: {
|
||||||
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
|
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
|
||||||
error("Invalid store instruction!");
|
error("Invalid store instruction!");
|
||||||
@ -913,7 +913,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||||||
if (Oprnds.size() != 0) error("Invalid unreachable instruction!");
|
if (Oprnds.size() != 0) error("Invalid unreachable instruction!");
|
||||||
Result = new UnreachableInst();
|
Result = new UnreachableInst();
|
||||||
break;
|
break;
|
||||||
} // end switch(Opcode)
|
} // end switch(Opcode)
|
||||||
|
|
||||||
unsigned TypeSlot;
|
unsigned TypeSlot;
|
||||||
if (Result->getType() == InstTy)
|
if (Result->getType() == InstTy)
|
||||||
@ -945,7 +945,7 @@ BasicBlock *BytecodeReader::getBasicBlock(unsigned ID) {
|
|||||||
return ParsedBasicBlocks[ID] = new BasicBlock();
|
return ParsedBasicBlocks[ID] = new BasicBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In LLVM 1.0 bytecode files, we used to output one basicblock at a time.
|
/// In LLVM 1.0 bytecode files, we used to output one basicblock at a time.
|
||||||
/// This method reads in one of the basicblock packets. This method is not used
|
/// This method reads in one of the basicblock packets. This method is not used
|
||||||
/// for bytecode files after LLVM 1.0
|
/// for bytecode files after LLVM 1.0
|
||||||
/// @returns The basic block constructed.
|
/// @returns The basic block constructed.
|
||||||
@ -970,7 +970,7 @@ BasicBlock *BytecodeReader::ParseBasicBlock(unsigned BlockNo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse all of the BasicBlock's & Instruction's in the body of a function.
|
/// Parse all of the BasicBlock's & Instruction's in the body of a function.
|
||||||
/// In post 1.0 bytecode files, we no longer emit basic block individually,
|
/// In post 1.0 bytecode files, we no longer emit basic block individually,
|
||||||
/// in order to avoid per-basic-block overhead.
|
/// in order to avoid per-basic-block overhead.
|
||||||
/// @returns Rhe number of basic blocks encountered.
|
/// @returns Rhe number of basic blocks encountered.
|
||||||
unsigned BytecodeReader::ParseInstructionList(Function* F) {
|
unsigned BytecodeReader::ParseInstructionList(Function* F) {
|
||||||
@ -1071,7 +1071,7 @@ void BytecodeReader::ParseSymbolTable(Function *CurrentFunction,
|
|||||||
if (Handler) Handler->handleSymbolTableEnd();
|
if (Handler) Handler->handleSymbolTableEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read in the types portion of a compaction table.
|
/// Read in the types portion of a compaction table.
|
||||||
void BytecodeReader::ParseCompactionTypes(unsigned NumEntries) {
|
void BytecodeReader::ParseCompactionTypes(unsigned NumEntries) {
|
||||||
for (unsigned i = 0; i != NumEntries; ++i) {
|
for (unsigned i = 0; i != NumEntries; ++i) {
|
||||||
unsigned TypeSlot = 0;
|
unsigned TypeSlot = 0;
|
||||||
@ -1089,7 +1089,7 @@ void BytecodeReader::ParseCompactionTable() {
|
|||||||
// Notify handler that we're beginning a compaction table.
|
// Notify handler that we're beginning a compaction table.
|
||||||
if (Handler) Handler->handleCompactionTableBegin();
|
if (Handler) Handler->handleCompactionTableBegin();
|
||||||
|
|
||||||
// In LLVM 1.3 Type no longer derives from Value. So,
|
// In LLVM 1.3 Type no longer derives from Value. So,
|
||||||
// we always write them first in the compaction table
|
// we always write them first in the compaction table
|
||||||
// because they can't occupy a "type plane" where the
|
// because they can't occupy a "type plane" where the
|
||||||
// Values reside.
|
// Values reside.
|
||||||
@ -1155,10 +1155,10 @@ void BytecodeReader::ParseCompactionTable() {
|
|||||||
// Notify handler that the compaction table is done.
|
// Notify handler that the compaction table is done.
|
||||||
if (Handler) Handler->handleCompactionTableEnd();
|
if (Handler) Handler->handleCompactionTableEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a single type. The typeid is read in first. If its a primitive type
|
// Parse a single type. The typeid is read in first. If its a primitive type
|
||||||
// then nothing else needs to be read, we know how to instantiate it. If its
|
// then nothing else needs to be read, we know how to instantiate it. If its
|
||||||
// a derived type, then additional data is read to fill out the type
|
// a derived type, then additional data is read to fill out the type
|
||||||
// definition.
|
// definition.
|
||||||
const Type *BytecodeReader::ParseType() {
|
const Type *BytecodeReader::ParseType() {
|
||||||
unsigned PrimType = 0;
|
unsigned PrimType = 0;
|
||||||
@ -1168,7 +1168,7 @@ const Type *BytecodeReader::ParseType() {
|
|||||||
const Type *Result = 0;
|
const Type *Result = 0;
|
||||||
if ((Result = Type::getPrimitiveType((Type::TypeID)PrimType)))
|
if ((Result = Type::getPrimitiveType((Type::TypeID)PrimType)))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
switch (PrimType) {
|
switch (PrimType) {
|
||||||
case Type::FunctionTyID: {
|
case Type::FunctionTyID: {
|
||||||
const Type *RetType = readSanitizedType();
|
const Type *RetType = readSanitizedType();
|
||||||
@ -1176,7 +1176,7 @@ const Type *BytecodeReader::ParseType() {
|
|||||||
unsigned NumParams = read_vbr_uint();
|
unsigned NumParams = read_vbr_uint();
|
||||||
|
|
||||||
std::vector<const Type*> Params;
|
std::vector<const Type*> Params;
|
||||||
while (NumParams--)
|
while (NumParams--)
|
||||||
Params.push_back(readSanitizedType());
|
Params.push_back(readSanitizedType());
|
||||||
|
|
||||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||||
@ -1248,7 +1248,7 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
|
|||||||
for (unsigned i = 0; i != NumEntries; ++i)
|
for (unsigned i = 0; i != NumEntries; ++i)
|
||||||
Tab.push_back(OpaqueType::get());
|
Tab.push_back(OpaqueType::get());
|
||||||
|
|
||||||
if (Handler)
|
if (Handler)
|
||||||
Handler->handleTypeList(NumEntries);
|
Handler->handleTypeList(NumEntries);
|
||||||
|
|
||||||
// Loop through reading all of the types. Forward types will make use of the
|
// Loop through reading all of the types. Forward types will make use of the
|
||||||
@ -1257,10 +1257,10 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
|
|||||||
for (unsigned i = 0; i != NumEntries; ++i) {
|
for (unsigned i = 0; i != NumEntries; ++i) {
|
||||||
const Type* NewTy = ParseType();
|
const Type* NewTy = ParseType();
|
||||||
const Type* OldTy = Tab[i].get();
|
const Type* OldTy = Tab[i].get();
|
||||||
if (NewTy == 0)
|
if (NewTy == 0)
|
||||||
error("Couldn't parse type!");
|
error("Couldn't parse type!");
|
||||||
|
|
||||||
// Don't directly push the new type on the Tab. Instead we want to replace
|
// Don't directly push the new type on the Tab. Instead we want to replace
|
||||||
// the opaque type we previously inserted with the new concrete value. This
|
// the opaque type we previously inserted with the new concrete value. This
|
||||||
// approach helps with forward references to types. The refinement from the
|
// approach helps with forward references to types. The refinement from the
|
||||||
// abstract (opaque) type to the new type causes all uses of the abstract
|
// abstract (opaque) type to the new type causes all uses of the abstract
|
||||||
@ -1279,7 +1279,7 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
|
|||||||
Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
||||||
// We must check for a ConstantExpr before switching by type because
|
// We must check for a ConstantExpr before switching by type because
|
||||||
// a ConstantExpr can be of any type, and has no explicit value.
|
// a ConstantExpr can be of any type, and has no explicit value.
|
||||||
//
|
//
|
||||||
// 0 if not expr; numArgs if is expr
|
// 0 if not expr; numArgs if is expr
|
||||||
unsigned isExprNumArgs = read_vbr_uint();
|
unsigned isExprNumArgs = read_vbr_uint();
|
||||||
|
|
||||||
@ -1288,7 +1288,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
if (!hasNoUndefValue)
|
if (!hasNoUndefValue)
|
||||||
if (--isExprNumArgs == 0)
|
if (--isExprNumArgs == 0)
|
||||||
return UndefValue::get(getType(TypeID));
|
return UndefValue::get(getType(TypeID));
|
||||||
|
|
||||||
// FIXME: Encoding of constant exprs could be much more compact!
|
// FIXME: Encoding of constant exprs could be much more compact!
|
||||||
std::vector<Constant*> ArgVec;
|
std::vector<Constant*> ArgVec;
|
||||||
ArgVec.reserve(isExprNumArgs);
|
ArgVec.reserve(isExprNumArgs);
|
||||||
@ -1296,18 +1296,18 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
|
|
||||||
// Bytecode files before LLVM 1.4 need have a missing terminator inst.
|
// Bytecode files before LLVM 1.4 need have a missing terminator inst.
|
||||||
if (hasNoUnreachableInst) Opcode++;
|
if (hasNoUnreachableInst) Opcode++;
|
||||||
|
|
||||||
// Read the slot number and types of each of the arguments
|
// Read the slot number and types of each of the arguments
|
||||||
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
||||||
unsigned ArgValSlot = read_vbr_uint();
|
unsigned ArgValSlot = read_vbr_uint();
|
||||||
unsigned ArgTypeSlot = 0;
|
unsigned ArgTypeSlot = 0;
|
||||||
if (read_typeid(ArgTypeSlot))
|
if (read_typeid(ArgTypeSlot))
|
||||||
error("Invalid argument type (type type) for constant value");
|
error("Invalid argument type (type type) for constant value");
|
||||||
|
|
||||||
// Get the arg value from its slot if it exists, otherwise a placeholder
|
// Get the arg value from its slot if it exists, otherwise a placeholder
|
||||||
ArgVec.push_back(getConstantValue(ArgTypeSlot, ArgValSlot));
|
ArgVec.push_back(getConstantValue(ArgTypeSlot, ArgValSlot));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a ConstantExpr of the appropriate kind
|
// Construct a ConstantExpr of the appropriate kind
|
||||||
if (isExprNumArgs == 1) { // All one-operand expressions
|
if (isExprNumArgs == 1) { // All one-operand expressions
|
||||||
if (Opcode != Instruction::Cast)
|
if (Opcode != Instruction::Cast)
|
||||||
@ -1338,7 +1338,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
} else if (Opcode == Instruction::Select) {
|
} else if (Opcode == Instruction::Select) {
|
||||||
if (ArgVec.size() != 3)
|
if (ArgVec.size() != 3)
|
||||||
error("Select instruction must have three arguments.");
|
error("Select instruction must have three arguments.");
|
||||||
Constant* Result = ConstantExpr::getSelect(ArgVec[0], ArgVec[1],
|
Constant* Result = ConstantExpr::getSelect(ArgVec[0], ArgVec[1],
|
||||||
ArgVec[2]);
|
ArgVec[2]);
|
||||||
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
|
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
|
||||||
return Result;
|
return Result;
|
||||||
@ -1348,13 +1348,13 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, not an ConstantExpr. We now know how to read the given type...
|
// Ok, not an ConstantExpr. We now know how to read the given type...
|
||||||
const Type *Ty = getType(TypeID);
|
const Type *Ty = getType(TypeID);
|
||||||
switch (Ty->getTypeID()) {
|
switch (Ty->getTypeID()) {
|
||||||
case Type::BoolTyID: {
|
case Type::BoolTyID: {
|
||||||
unsigned Val = read_vbr_uint();
|
unsigned Val = read_vbr_uint();
|
||||||
if (Val != 0 && Val != 1)
|
if (Val != 0 && Val != 1)
|
||||||
error("Invalid boolean value read.");
|
error("Invalid boolean value read.");
|
||||||
Constant* Result = ConstantBool::get(Val == 1);
|
Constant* Result = ConstantBool::get(Val == 1);
|
||||||
if (Handler) Handler->handleConstantValue(Result);
|
if (Handler) Handler->handleConstantValue(Result);
|
||||||
@ -1365,7 +1365,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
case Type::UShortTyID:
|
case Type::UShortTyID:
|
||||||
case Type::UIntTyID: {
|
case Type::UIntTyID: {
|
||||||
unsigned Val = read_vbr_uint();
|
unsigned Val = read_vbr_uint();
|
||||||
if (!ConstantUInt::isValueValidForType(Ty, Val))
|
if (!ConstantUInt::isValueValidForType(Ty, Val))
|
||||||
error("Invalid unsigned byte/short/int read.");
|
error("Invalid unsigned byte/short/int read.");
|
||||||
Constant* Result = ConstantUInt::get(Ty, Val);
|
Constant* Result = ConstantUInt::get(Ty, Val);
|
||||||
if (Handler) Handler->handleConstantValue(Result);
|
if (Handler) Handler->handleConstantValue(Result);
|
||||||
@ -1383,7 +1383,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
case Type::IntTyID: {
|
case Type::IntTyID: {
|
||||||
case Type::LongTyID:
|
case Type::LongTyID:
|
||||||
int64_t Val = read_vbr_int64();
|
int64_t Val = read_vbr_int64();
|
||||||
if (!ConstantSInt::isValueValidForType(Ty, Val))
|
if (!ConstantSInt::isValueValidForType(Ty, Val))
|
||||||
error("Invalid signed byte/short/int/long read.");
|
error("Invalid signed byte/short/int/long read.");
|
||||||
Constant* Result = ConstantSInt::get(Ty, Val);
|
Constant* Result = ConstantSInt::get(Ty, Val);
|
||||||
if (Handler) Handler->handleConstantValue(Result);
|
if (Handler) Handler->handleConstantValue(Result);
|
||||||
@ -1432,7 +1432,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
Constant* Result = ConstantStruct::get(ST, Elements);
|
Constant* Result = ConstantStruct::get(ST, Elements);
|
||||||
if (Handler) Handler->handleConstantStruct(ST, Elements, Result);
|
if (Handler) Handler->handleConstantStruct(ST, Elements, Result);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::PackedTyID: {
|
case Type::PackedTyID: {
|
||||||
const PackedType *PT = cast<PackedType>(Ty);
|
const PackedType *PT = cast<PackedType>(Ty);
|
||||||
@ -1451,7 +1451,7 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
case Type::PointerTyID: { // ConstantPointerRef value (backwards compat).
|
case Type::PointerTyID: { // ConstantPointerRef value (backwards compat).
|
||||||
const PointerType *PT = cast<PointerType>(Ty);
|
const PointerType *PT = cast<PointerType>(Ty);
|
||||||
unsigned Slot = read_vbr_uint();
|
unsigned Slot = read_vbr_uint();
|
||||||
|
|
||||||
// Check to see if we have already read this global variable...
|
// Check to see if we have already read this global variable...
|
||||||
Value *Val = getValue(TypeID, Slot, false);
|
Value *Val = getValue(TypeID, Slot, false);
|
||||||
if (Val) {
|
if (Val) {
|
||||||
@ -1472,8 +1472,8 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve references for constants. This function resolves the forward
|
/// Resolve references for constants. This function resolves the forward
|
||||||
/// referenced constants in the ConstantFwdRefs map. It uses the
|
/// referenced constants in the ConstantFwdRefs map. It uses the
|
||||||
/// replaceAllUsesWith method of Value class to substitute the placeholder
|
/// replaceAllUsesWith method of Value class to substitute the placeholder
|
||||||
/// instance with the actual instance.
|
/// instance with the actual instance.
|
||||||
void BytecodeReader::ResolveReferencesToConstant(Constant *NewV, unsigned Typ,
|
void BytecodeReader::ResolveReferencesToConstant(Constant *NewV, unsigned Typ,
|
||||||
@ -1497,14 +1497,14 @@ void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
|
|||||||
const Type *Ty = getType(Typ);
|
const Type *Ty = getType(Typ);
|
||||||
if (!isa<ArrayType>(Ty))
|
if (!isa<ArrayType>(Ty))
|
||||||
error("String constant data invalid!");
|
error("String constant data invalid!");
|
||||||
|
|
||||||
const ArrayType *ATy = cast<ArrayType>(Ty);
|
const ArrayType *ATy = cast<ArrayType>(Ty);
|
||||||
if (ATy->getElementType() != Type::SByteTy &&
|
if (ATy->getElementType() != Type::SByteTy &&
|
||||||
ATy->getElementType() != Type::UByteTy)
|
ATy->getElementType() != Type::UByteTy)
|
||||||
error("String constant data invalid!");
|
error("String constant data invalid!");
|
||||||
|
|
||||||
// Read character data. The type tells us how long the string is.
|
// Read character data. The type tells us how long the string is.
|
||||||
char *Data = reinterpret_cast<char *>(alloca(ATy->getNumElements()));
|
char *Data = reinterpret_cast<char *>(alloca(ATy->getNumElements()));
|
||||||
read_data(Data, Data+ATy->getNumElements());
|
read_data(Data, Data+ATy->getNumElements());
|
||||||
|
|
||||||
std::vector<Constant*> Elements(ATy->getNumElements());
|
std::vector<Constant*> Elements(ATy->getNumElements());
|
||||||
@ -1524,7 +1524,7 @@ void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the constant pool.
|
/// Parse the constant pool.
|
||||||
void BytecodeReader::ParseConstantPool(ValueTable &Tab,
|
void BytecodeReader::ParseConstantPool(ValueTable &Tab,
|
||||||
TypeListTy &TypeTab,
|
TypeListTy &TypeTab,
|
||||||
bool isFunction) {
|
bool isFunction) {
|
||||||
if (Handler) Handler->handleGlobalConstantsBegin();
|
if (Handler) Handler->handleGlobalConstantsBegin();
|
||||||
@ -1574,9 +1574,9 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab,
|
|||||||
if (!ConstantFwdRefs.empty()) {
|
if (!ConstantFwdRefs.empty()) {
|
||||||
ConstantRefsType::const_iterator I = ConstantFwdRefs.begin();
|
ConstantRefsType::const_iterator I = ConstantFwdRefs.begin();
|
||||||
Constant* missingConst = I->second;
|
Constant* missingConst = I->second;
|
||||||
error(utostr(ConstantFwdRefs.size()) +
|
error(utostr(ConstantFwdRefs.size()) +
|
||||||
" unresolved constant reference exist. First one is '" +
|
" unresolved constant reference exist. First one is '" +
|
||||||
missingConst->getName() + "' of type '" +
|
missingConst->getName() + "' of type '" +
|
||||||
missingConst->getType()->getDescription() + "'.");
|
missingConst->getType()->getDescription() + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1658,7 +1658,7 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
|
|||||||
InsertedArguments = true;
|
InsertedArguments = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BlockNum)
|
if (BlockNum)
|
||||||
error("Already parsed basic blocks!");
|
error("Already parsed basic blocks!");
|
||||||
BlockNum = ParseInstructionList(F);
|
BlockNum = ParseInstructionList(F);
|
||||||
break;
|
break;
|
||||||
@ -1670,7 +1670,7 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
At += Size;
|
At += Size;
|
||||||
if (OldAt > At)
|
if (OldAt > At)
|
||||||
error("Wrapped around reading bytecode.");
|
error("Wrapped around reading bytecode.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1709,7 +1709,7 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
|
|||||||
|
|
||||||
/// This function parses LLVM functions lazily. It obtains the type of the
|
/// 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
|
/// function and records where the body of the function is in the bytecode
|
||||||
/// buffer. The caller can then use the ParseNextFunction and
|
/// buffer. The caller can then use the ParseNextFunction and
|
||||||
/// ParseAllFunctionBodies to get handler events for the functions.
|
/// ParseAllFunctionBodies to get handler events for the functions.
|
||||||
void BytecodeReader::ParseFunctionLazily() {
|
void BytecodeReader::ParseFunctionLazily() {
|
||||||
if (FunctionSignatureList.empty())
|
if (FunctionSignatureList.empty())
|
||||||
@ -1729,9 +1729,9 @@ void BytecodeReader::ParseFunctionLazily() {
|
|||||||
At = BlockEnd;
|
At = BlockEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ParserFunction method lazily parses one function. Use this method to
|
/// The ParserFunction method lazily parses one function. Use this method to
|
||||||
/// casue the parser to parse a specific function in the module. Note that
|
/// casue the parser to parse a specific function in the module. Note that
|
||||||
/// this will remove the function from what is to be included by
|
/// this will remove the function from what is to be included by
|
||||||
/// ParseAllFunctionBodies.
|
/// ParseAllFunctionBodies.
|
||||||
/// @see ParseAllFunctionBodies
|
/// @see ParseAllFunctionBodies
|
||||||
/// @see ParseBytecode
|
/// @see ParseBytecode
|
||||||
@ -1811,7 +1811,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
case 2: Linkage = GlobalValue::AppendingLinkage; break;
|
case 2: Linkage = GlobalValue::AppendingLinkage; break;
|
||||||
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
||||||
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
||||||
default:
|
default:
|
||||||
error("Unknown linkage type: " + utostr(LinkageID));
|
error("Unknown linkage type: " + utostr(LinkageID));
|
||||||
Linkage = GlobalValue::InternalLinkage;
|
Linkage = GlobalValue::InternalLinkage;
|
||||||
break;
|
break;
|
||||||
@ -1834,7 +1834,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
insertValue(GV, SlotNo, ModuleValues);
|
insertValue(GV, SlotNo, ModuleValues);
|
||||||
|
|
||||||
unsigned initSlot = 0;
|
unsigned initSlot = 0;
|
||||||
if (hasInitializer) {
|
if (hasInitializer) {
|
||||||
initSlot = read_vbr_uint();
|
initSlot = read_vbr_uint();
|
||||||
GlobalInits.push_back(std::make_pair(GV, initSlot));
|
GlobalInits.push_back(std::make_pair(GV, initSlot));
|
||||||
}
|
}
|
||||||
@ -1858,17 +1858,17 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
const Type *Ty = getType(FnSignature >> 5);
|
const Type *Ty = getType(FnSignature >> 5);
|
||||||
if (!isa<PointerType>(Ty) ||
|
if (!isa<PointerType>(Ty) ||
|
||||||
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
|
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
|
||||||
error("Function not a pointer to function type! Ty = " +
|
error("Function not a pointer to function type! Ty = " +
|
||||||
Ty->getDescription());
|
Ty->getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We create functions by passing the underlying FunctionType to create...
|
// We create functions by passing the underlying FunctionType to create...
|
||||||
const FunctionType* FTy =
|
const FunctionType* FTy =
|
||||||
cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
|
cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
|
||||||
|
|
||||||
|
|
||||||
// Insert the place holder.
|
// Insert the place holder.
|
||||||
Function* Func = new Function(FTy, GlobalValue::ExternalLinkage,
|
Function* Func = new Function(FTy, GlobalValue::ExternalLinkage,
|
||||||
"", TheModule);
|
"", TheModule);
|
||||||
insertValue(Func, FnSignature >> 5, ModuleValues);
|
insertValue(Func, FnSignature >> 5, ModuleValues);
|
||||||
|
|
||||||
@ -1889,7 +1889,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
|||||||
FnSignature = (FnSignature << 5) + 1;
|
FnSignature = (FnSignature << 5) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that the function signature list is set up, reverse it so that we can
|
// Now that the function signature list is set up, reverse it so that we can
|
||||||
// remove elements efficiently from the back of the vector.
|
// remove elements efficiently from the back of the vector.
|
||||||
std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
|
std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
|
||||||
|
|
||||||
@ -1937,7 +1937,7 @@ void BytecodeReader::ParseVersionInfo() {
|
|||||||
|
|
||||||
bool hasNoEndianness = Version & 4;
|
bool hasNoEndianness = Version & 4;
|
||||||
bool hasNoPointerSize = Version & 8;
|
bool hasNoPointerSize = Version & 8;
|
||||||
|
|
||||||
RevisionNum = Version >> 4;
|
RevisionNum = Version >> 4;
|
||||||
|
|
||||||
// Default values for the current bytecode version
|
// Default values for the current bytecode version
|
||||||
@ -1977,12 +1977,12 @@ void BytecodeReader::ParseVersionInfo() {
|
|||||||
|
|
||||||
// LLVM 1.2 and before had the Type class derive from Value class. This
|
// LLVM 1.2 and before had the Type class derive from Value class. This
|
||||||
// changed in release 1.3 and consequently LLVM 1.3 bytecode files are
|
// changed in release 1.3 and consequently LLVM 1.3 bytecode files are
|
||||||
// written differently because Types can no longer be part of the
|
// written differently because Types can no longer be part of the
|
||||||
// type planes for Values.
|
// type planes for Values.
|
||||||
hasTypeDerivedFromValue = true;
|
hasTypeDerivedFromValue = true;
|
||||||
|
|
||||||
// FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
case 2: // 1.2.5 (Not Released)
|
case 2: // 1.2.5 (Not Released)
|
||||||
|
|
||||||
// LLVM 1.2 and earlier had two-word block headers. This is a bit wasteful,
|
// LLVM 1.2 and earlier had two-word block headers. This is a bit wasteful,
|
||||||
@ -1999,7 +1999,7 @@ void BytecodeReader::ParseVersionInfo() {
|
|||||||
// in various places and to ensure consistency.
|
// in various places and to ensure consistency.
|
||||||
has32BitTypes = true;
|
has32BitTypes = true;
|
||||||
|
|
||||||
// LLVM 1.2 and earlier did not provide a target triple nor a list of
|
// LLVM 1.2 and earlier did not provide a target triple nor a list of
|
||||||
// libraries on which the bytecode is dependent. LLVM 1.3 provides these
|
// libraries on which the bytecode is dependent. LLVM 1.3 provides these
|
||||||
// features, for use in future versions of LLVM.
|
// features, for use in future versions of LLVM.
|
||||||
hasNoDependentLibraries = true;
|
hasNoDependentLibraries = true;
|
||||||
@ -2008,13 +2008,13 @@ void BytecodeReader::ParseVersionInfo() {
|
|||||||
|
|
||||||
case 3: // LLVM 1.3 (Released)
|
case 3: // LLVM 1.3 (Released)
|
||||||
// LLVM 1.3 and earlier caused alignment bytes to be written on some block
|
// LLVM 1.3 and earlier caused alignment bytes to be written on some block
|
||||||
// boundaries and at the end of some strings. In extreme cases (e.g. lots
|
// boundaries and at the end of some strings. In extreme cases (e.g. lots
|
||||||
// of GEP references to a constant array), this can increase the file size
|
// of GEP references to a constant array), this can increase the file size
|
||||||
// by 30% or more. In version 1.4 alignment is done away with completely.
|
// by 30% or more. In version 1.4 alignment is done away with completely.
|
||||||
hasAlignment = true;
|
hasAlignment = true;
|
||||||
|
|
||||||
// FALL THROUGH
|
// FALL THROUGH
|
||||||
|
|
||||||
case 4: // 1.3.1 (Not Released)
|
case 4: // 1.3.1 (Not Released)
|
||||||
// In version 4, we did not support the 'undef' constant.
|
// In version 4, we did not support the 'undef' constant.
|
||||||
hasNoUndefValue = true;
|
hasNoUndefValue = true;
|
||||||
@ -2034,8 +2034,8 @@ void BytecodeReader::ParseVersionInfo() {
|
|||||||
break;
|
break;
|
||||||
// FIXME: NONE of this is implemented yet!
|
// FIXME: NONE of this is implemented yet!
|
||||||
|
|
||||||
// In version 5, basic blocks have a minimum index of 0 whereas all the
|
// In version 5, basic blocks have a minimum index of 0 whereas all the
|
||||||
// other primitives have a minimum index of 1 (because 0 is the "null"
|
// other primitives have a minimum index of 1 (because 0 is the "null"
|
||||||
// value. In version 5, we made this consistent.
|
// value. In version 5, we made this consistent.
|
||||||
hasInconsistentBBSlotNums = true;
|
hasInconsistentBBSlotNums = true;
|
||||||
|
|
||||||
@ -2090,7 +2090,7 @@ void BytecodeReader::ParseModule() {
|
|||||||
SeenGlobalTypePlane = true;
|
SeenGlobalTypePlane = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BytecodeFormat::ModuleGlobalInfoBlockID:
|
case BytecodeFormat::ModuleGlobalInfoBlockID:
|
||||||
if (SeenModuleGlobalInfo)
|
if (SeenModuleGlobalInfo)
|
||||||
error("Two ModuleGlobalInfo Blocks Encountered!");
|
error("Two ModuleGlobalInfo Blocks Encountered!");
|
||||||
ParseModuleGlobalInfo();
|
ParseModuleGlobalInfo();
|
||||||
@ -2133,7 +2133,7 @@ void BytecodeReader::ParseModule() {
|
|||||||
const llvm::PointerType* GVType = GV->getType();
|
const llvm::PointerType* GVType = GV->getType();
|
||||||
unsigned TypeSlot = getTypeSlot(GVType->getElementType());
|
unsigned TypeSlot = getTypeSlot(GVType->getElementType());
|
||||||
if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
|
if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
|
||||||
if (GV->hasInitializer())
|
if (GV->hasInitializer())
|
||||||
error("Global *already* has an initializer?!");
|
error("Global *already* has an initializer?!");
|
||||||
if (Handler) Handler->handleGlobalInitializer(GV,CV);
|
if (Handler) Handler->handleGlobalInitializer(GV,CV);
|
||||||
GV->setInitializer(CV);
|
GV->setInitializer(CV);
|
||||||
@ -2149,7 +2149,7 @@ void BytecodeReader::ParseModule() {
|
|||||||
|
|
||||||
/// This function completely parses a bytecode buffer given by the \p Buf
|
/// This function completely parses a bytecode buffer given by the \p Buf
|
||||||
/// and \p Length parameters.
|
/// and \p Length parameters.
|
||||||
void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
|
void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
|
||||||
const std::string &ModuleID) {
|
const std::string &ModuleID) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -2198,7 +2198,7 @@ void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
|
|||||||
Type = read_uint();
|
Type = read_uint();
|
||||||
Size = read_uint();
|
Size = read_uint();
|
||||||
if (Type != BytecodeFormat::ModuleBlockID) {
|
if (Type != BytecodeFormat::ModuleBlockID) {
|
||||||
error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
|
error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
|
||||||
+ utostr(Size));
|
+ utostr(Size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2220,7 +2220,7 @@ void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
|
|||||||
error("Function expected, but bytecode stream ended!");
|
error("Function expected, but bytecode stream ended!");
|
||||||
|
|
||||||
// Tell the handler we're done with the module
|
// Tell the handler we're done with the module
|
||||||
if (Handler)
|
if (Handler)
|
||||||
Handler->handleModuleEnd(ModuleID);
|
Handler->handleModuleEnd(ModuleID);
|
||||||
|
|
||||||
// Tell the handler we're finished the parse
|
// Tell the handler we're finished the parse
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
//===-- Reader.h - Interface To Bytecode Reading ----------------*- C++ -*-===//
|
//===-- Reader.h - Interface To Bytecode Reading ----------------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by Reid Spencer and is distributed under the
|
// This file was developed by Reid Spencer and is distributed under the
|
||||||
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This header file defines the interface to the Bytecode Reader which is
|
// This header file defines the interface to the Bytecode Reader which is
|
||||||
// responsible for correctly interpreting bytecode files (backwards compatible)
|
// responsible for correctly interpreting bytecode files (backwards compatible)
|
||||||
// and materializing a module from the bytecode read.
|
// and materializing a module from the bytecode read.
|
||||||
//
|
//
|
||||||
@ -32,8 +32,8 @@ class BytecodeHandler; ///< Forward declare the handler interface
|
|||||||
/// This class defines the interface for parsing a buffer of bytecode. The
|
/// This class defines the interface for parsing a buffer of bytecode. The
|
||||||
/// parser itself takes no action except to call the various functions of
|
/// parser itself takes no action except to call the various functions of
|
||||||
/// the handler interface. The parser's sole responsibility is the correct
|
/// the handler interface. The parser's sole responsibility is the correct
|
||||||
/// interpretation of the bytecode buffer. The handler is responsible for
|
/// interpretation of the bytecode buffer. The handler is responsible for
|
||||||
/// instantiating and keeping track of all values. As a convenience, the parser
|
/// instantiating and keeping track of all values. As a convenience, the parser
|
||||||
/// is responsible for materializing types and will pass them through the
|
/// is responsible for materializing types and will pass them through the
|
||||||
/// handler interface as necessary.
|
/// handler interface as necessary.
|
||||||
/// @see BytecodeHandler
|
/// @see BytecodeHandler
|
||||||
@ -44,13 +44,13 @@ class BytecodeReader : public ModuleProvider {
|
|||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
/// @brief Default constructor. By default, no handler is used.
|
/// @brief Default constructor. By default, no handler is used.
|
||||||
BytecodeReader(BytecodeHandler* h = 0) {
|
BytecodeReader(BytecodeHandler* h = 0) {
|
||||||
decompressedBlock = 0;
|
decompressedBlock = 0;
|
||||||
Handler = h;
|
Handler = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BytecodeReader() {
|
~BytecodeReader() {
|
||||||
freeState();
|
freeState();
|
||||||
if (decompressedBlock) {
|
if (decompressedBlock) {
|
||||||
::free(decompressedBlock);
|
::free(decompressedBlock);
|
||||||
decompressedBlock = 0;
|
decompressedBlock = 0;
|
||||||
@ -104,7 +104,7 @@ public:
|
|||||||
/// @brief A 2 dimensional table of values
|
/// @brief A 2 dimensional table of values
|
||||||
typedef std::vector<ValueList*> ValueTable;
|
typedef std::vector<ValueList*> ValueTable;
|
||||||
|
|
||||||
/// This map is needed so that forward references to constants can be looked
|
/// This map is needed so that forward references to constants can be looked
|
||||||
/// up by Type and slot number when resolving those references.
|
/// up by Type and slot number when resolving those references.
|
||||||
/// @brief A mapping of a Type/slot pair to a Constant*.
|
/// @brief A mapping of a Type/slot pair to a Constant*.
|
||||||
typedef std::map<std::pair<unsigned,unsigned>, Constant*> ConstantRefsType;
|
typedef std::map<std::pair<unsigned,unsigned>, Constant*> ConstantRefsType;
|
||||||
@ -112,7 +112,7 @@ public:
|
|||||||
/// For lazy read-in of functions, we need to save the location in the
|
/// For lazy read-in of functions, we need to save the location in the
|
||||||
/// data stream where the function is located. This structure provides that
|
/// data stream where the function is located. This structure provides that
|
||||||
/// information. Lazy read-in is used mostly by the JIT which only wants to
|
/// information. Lazy read-in is used mostly by the JIT which only wants to
|
||||||
/// resolve functions as it needs them.
|
/// resolve functions as it needs them.
|
||||||
/// @brief Keeps pointers to function contents for later use.
|
/// @brief Keeps pointers to function contents for later use.
|
||||||
struct LazyFunctionInfo {
|
struct LazyFunctionInfo {
|
||||||
const unsigned char *Buf, *EndBuf;
|
const unsigned char *Buf, *EndBuf;
|
||||||
@ -160,7 +160,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This method is abstract in the parent ModuleProvider class. Its
|
/// This method is abstract in the parent ModuleProvider class. Its
|
||||||
/// implementation is identical to ParseAllFunctionBodies.
|
/// implementation is identical to ParseAllFunctionBodies.
|
||||||
/// @see ParseAllFunctionBodies
|
/// @see ParseAllFunctionBodies
|
||||||
/// @brief Make the whole module materialize
|
/// @brief Make the whole module materialize
|
||||||
virtual Module* materializeModule() {
|
virtual Module* materializeModule() {
|
||||||
@ -218,7 +218,7 @@ protected:
|
|||||||
unsigned ParseInstructionList(
|
unsigned ParseInstructionList(
|
||||||
Function* F ///< The function into which BBs will be inserted
|
Function* F ///< The function into which BBs will be inserted
|
||||||
);
|
);
|
||||||
|
|
||||||
/// @brief Parse a single instruction.
|
/// @brief Parse a single instruction.
|
||||||
void ParseInstruction(
|
void ParseInstruction(
|
||||||
std::vector<unsigned>& Args, ///< The arguments to be filled in
|
std::vector<unsigned>& Args, ///< The arguments to be filled in
|
||||||
@ -226,7 +226,7 @@ protected:
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// @brief Parse the whole constant pool
|
/// @brief Parse the whole constant pool
|
||||||
void ParseConstantPool(ValueTable& Values, TypeListTy& Types,
|
void ParseConstantPool(ValueTable& Values, TypeListTy& Types,
|
||||||
bool isFunction);
|
bool isFunction);
|
||||||
|
|
||||||
/// @brief Parse a single constant value
|
/// @brief Parse a single constant value
|
||||||
@ -245,7 +245,7 @@ protected:
|
|||||||
/// @name Data
|
/// @name Data
|
||||||
/// @{
|
/// @{
|
||||||
private:
|
private:
|
||||||
char* decompressedBlock; ///< Result of decompression
|
char* decompressedBlock; ///< Result of decompression
|
||||||
BufPtr MemStart; ///< Start of the memory buffer
|
BufPtr MemStart; ///< Start of the memory buffer
|
||||||
BufPtr MemEnd; ///< End of the memory buffer
|
BufPtr MemEnd; ///< End of the memory buffer
|
||||||
BufPtr BlockStart; ///< Start of current block being parsed
|
BufPtr BlockStart; ///< Start of current block being parsed
|
||||||
@ -291,14 +291,14 @@ private:
|
|||||||
bool hasLongBlockHeaders;
|
bool hasLongBlockHeaders;
|
||||||
|
|
||||||
/// LLVM 1.2 and earlier wrote type slot numbers as vbr_uint32. In LLVM 1.3
|
/// LLVM 1.2 and earlier wrote type slot numbers as vbr_uint32. In LLVM 1.3
|
||||||
/// this has been reduced to vbr_uint24. It shouldn't make much difference
|
/// this has been reduced to vbr_uint24. It shouldn't make much difference
|
||||||
/// since we haven't run into a module with > 24 million types, but for safety
|
/// since we haven't run into a module with > 24 million types, but for safety
|
||||||
/// the 24-bit restriction has been enforced in 1.3 to free some bits in
|
/// the 24-bit restriction has been enforced in 1.3 to free some bits in
|
||||||
/// various places and to ensure consistency. In particular, global vars are
|
/// various places and to ensure consistency. In particular, global vars are
|
||||||
/// restricted to 24-bits.
|
/// restricted to 24-bits.
|
||||||
bool has32BitTypes;
|
bool has32BitTypes;
|
||||||
|
|
||||||
/// LLVM 1.2 and earlier did not provide a target triple nor a list of
|
/// LLVM 1.2 and earlier did not provide a target triple nor a list of
|
||||||
/// libraries on which the bytecode is dependent. LLVM 1.3 provides these
|
/// libraries on which the bytecode is dependent. LLVM 1.3 provides these
|
||||||
/// features, for use in future versions of LLVM.
|
/// features, for use in future versions of LLVM.
|
||||||
bool hasNoDependentLibraries;
|
bool hasNoDependentLibraries;
|
||||||
@ -321,8 +321,8 @@ private:
|
|||||||
// unreachable instruction.
|
// unreachable instruction.
|
||||||
bool hasNoUnreachableInst;
|
bool hasNoUnreachableInst;
|
||||||
|
|
||||||
// In version 5, basic blocks have a minimum index of 0 whereas all the
|
// In version 5, basic blocks have a minimum index of 0 whereas all the
|
||||||
// other primitives have a minimum index of 1 (because 0 is the "null"
|
// other primitives have a minimum index of 1 (because 0 is the "null"
|
||||||
// value. In version 5, we made this consistent.
|
// value. In version 5, we made this consistent.
|
||||||
bool hasInconsistentBBSlotNums;
|
bool hasInconsistentBBSlotNums;
|
||||||
|
|
||||||
@ -388,11 +388,11 @@ private:
|
|||||||
// and its FunctionSlot.
|
// and its FunctionSlot.
|
||||||
LazyFunctionMap LazyFunctionLoadMap;
|
LazyFunctionMap LazyFunctionLoadMap;
|
||||||
|
|
||||||
/// This stores the parser's handler which is used for handling tasks other
|
/// This stores the parser's handler which is used for handling tasks other
|
||||||
/// just than reading bytecode into the IR. If this is non-null, calls on
|
/// just than reading bytecode into the IR. If this is non-null, calls on
|
||||||
/// the (polymorphic) BytecodeHandler interface (see llvm/Bytecode/Handler.h)
|
/// the (polymorphic) BytecodeHandler interface (see llvm/Bytecode/Handler.h)
|
||||||
/// will be made to report the logical structure of the bytecode file. What
|
/// will be made to report the logical structure of the bytecode file. What
|
||||||
/// the handler does with the events it receives is completely orthogonal to
|
/// the handler does with the events it receives is completely orthogonal to
|
||||||
/// the business of parsing the bytecode and building the IR. This is used,
|
/// the business of parsing the bytecode and building the IR. This is used,
|
||||||
/// for example, by the llvm-abcd tool for analysis of byte code.
|
/// for example, by the llvm-abcd tool for analysis of byte code.
|
||||||
/// @brief Handler for parsing events.
|
/// @brief Handler for parsing events.
|
||||||
@ -428,9 +428,9 @@ private:
|
|||||||
const Type *getGlobalTableType(unsigned TypeId);
|
const Type *getGlobalTableType(unsigned TypeId);
|
||||||
|
|
||||||
/// This is just like getTypeSlot, but when a compaction table is in use,
|
/// This is just like getTypeSlot, but when a compaction table is in use,
|
||||||
/// it is ignored.
|
/// it is ignored.
|
||||||
unsigned getGlobalTableTypeSlot(const Type *Ty);
|
unsigned getGlobalTableTypeSlot(const Type *Ty);
|
||||||
|
|
||||||
/// @brief Get a value from its typeid and slot number
|
/// @brief Get a value from its typeid and slot number
|
||||||
Value* getValue(unsigned TypeID, unsigned num, bool Create = true);
|
Value* getValue(unsigned TypeID, unsigned num, bool Create = true);
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ private:
|
|||||||
/// @brief Insert the arguments of a function.
|
/// @brief Insert the arguments of a function.
|
||||||
void insertArguments(Function* F );
|
void insertArguments(Function* F );
|
||||||
|
|
||||||
/// @brief Resolve all references to the placeholder (if any) for the
|
/// @brief Resolve all references to the placeholder (if any) for the
|
||||||
/// given constant.
|
/// given constant.
|
||||||
void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
|
void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
|
||||||
|
|
||||||
@ -534,7 +534,7 @@ private:
|
|||||||
|
|
||||||
/// @brief A function for creating a BytecodeAnalzer as a handler
|
/// @brief A function for creating a BytecodeAnalzer as a handler
|
||||||
/// for the Bytecode reader.
|
/// for the Bytecode reader.
|
||||||
BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca,
|
BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca,
|
||||||
std::ostream* output );
|
std::ostream* output );
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//===- ReaderWrappers.cpp - Parse bytecode from file or buffer -----------===//
|
//===- ReaderWrappers.cpp - Parse bytecode from file or buffer -----------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// 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.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file implements loading and parsing a bytecode file and parsing a
|
// This file implements loading and parsing a bytecode file and parsing a
|
||||||
@ -43,7 +43,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
|
BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
|
||||||
llvm::BytecodeHandler* H )
|
llvm::BytecodeHandler* H )
|
||||||
: BytecodeReader(H)
|
: BytecodeReader(H)
|
||||||
, mapFile( sys::Path(Filename))
|
, mapFile( sys::Path(Filename))
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ BytecodeBufferReader::~BytecodeBufferReader() {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// BytecodeStdinReader - parses a bytecode file from stdin
|
/// BytecodeStdinReader - parses a bytecode file from stdin
|
||||||
///
|
///
|
||||||
class BytecodeStdinReader : public BytecodeReader {
|
class BytecodeStdinReader : public BytecodeReader {
|
||||||
private:
|
private:
|
||||||
std::vector<unsigned char> FileData;
|
std::vector<unsigned char> FileData;
|
||||||
@ -127,7 +127,7 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeStdinReader::BytecodeStdinReader( BytecodeHandler* H )
|
BytecodeStdinReader::BytecodeStdinReader( BytecodeHandler* H )
|
||||||
: BytecodeReader(H)
|
: BytecodeReader(H)
|
||||||
{
|
{
|
||||||
char Buffer[4096*4];
|
char Buffer[4096*4];
|
||||||
@ -156,7 +156,7 @@ BytecodeStdinReader::BytecodeStdinReader( BytecodeHandler* H )
|
|||||||
// new style varargs for backwards compatibility.
|
// new style varargs for backwards compatibility.
|
||||||
static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
||||||
Module *M = MP->getModule();
|
Module *M = MP->getModule();
|
||||||
|
|
||||||
// Check to see if va_start takes arguments...
|
// Check to see if va_start takes arguments...
|
||||||
Function *F = M->getNamedFunction("llvm.va_start");
|
Function *F = M->getNamedFunction("llvm.va_start");
|
||||||
if (F == 0) return MP; // No varargs use, just return.
|
if (F == 0) return MP; // No varargs use, just return.
|
||||||
@ -172,11 +172,11 @@ static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
|||||||
// the user.
|
// the user.
|
||||||
if (Function *F = M->getNamedFunction("llvm.va_start")) {
|
if (Function *F = M->getNamedFunction("llvm.va_start")) {
|
||||||
assert(F->arg_size() == 1 && "Obsolete va_start takes 1 argument!");
|
assert(F->arg_size() == 1 && "Obsolete va_start takes 1 argument!");
|
||||||
|
|
||||||
const Type *RetTy = F->getFunctionType()->getParamType(0);
|
const Type *RetTy = F->getFunctionType()->getParamType(0);
|
||||||
RetTy = cast<PointerType>(RetTy)->getElementType();
|
RetTy = cast<PointerType>(RetTy)->getElementType();
|
||||||
Function *NF = M->getOrInsertFunction("llvm.va_start", RetTy, 0);
|
Function *NF = M->getOrInsertFunction("llvm.va_start", RetTy, 0);
|
||||||
|
|
||||||
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
||||||
Value *V = new CallInst(NF, "", CI);
|
Value *V = new CallInst(NF, "", CI);
|
||||||
@ -192,7 +192,7 @@ static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
|||||||
ArgTy = cast<PointerType>(ArgTy)->getElementType();
|
ArgTy = cast<PointerType>(ArgTy)->getElementType();
|
||||||
Function *NF = M->getOrInsertFunction("llvm.va_end", Type::VoidTy,
|
Function *NF = M->getOrInsertFunction("llvm.va_end", Type::VoidTy,
|
||||||
ArgTy, 0);
|
ArgTy, 0);
|
||||||
|
|
||||||
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
||||||
Value *V = new LoadInst(CI->getOperand(1), "", CI);
|
Value *V = new LoadInst(CI->getOperand(1), "", CI);
|
||||||
@ -201,14 +201,14 @@ static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
|||||||
}
|
}
|
||||||
F->setName("");
|
F->setName("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Function *F = M->getNamedFunction("llvm.va_copy")) {
|
if (Function *F = M->getNamedFunction("llvm.va_copy")) {
|
||||||
assert(F->arg_size() == 2 && "Obsolete va_copy takes 2 argument!");
|
assert(F->arg_size() == 2 && "Obsolete va_copy takes 2 argument!");
|
||||||
const Type *ArgTy = F->getFunctionType()->getParamType(0);
|
const Type *ArgTy = F->getFunctionType()->getParamType(0);
|
||||||
ArgTy = cast<PointerType>(ArgTy)->getElementType();
|
ArgTy = cast<PointerType>(ArgTy)->getElementType();
|
||||||
Function *NF = M->getOrInsertFunction("llvm.va_copy", ArgTy,
|
Function *NF = M->getOrInsertFunction("llvm.va_copy", ArgTy,
|
||||||
ArgTy, 0);
|
ArgTy, 0);
|
||||||
|
|
||||||
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; )
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
if (CallInst *CI = dyn_cast<CallInst>(*I++)) {
|
||||||
Value *V = new CallInst(NF, CI->getOperand(2), "", CI);
|
Value *V = new CallInst(NF, CI->getOperand(2), "", CI);
|
||||||
@ -226,7 +226,7 @@ static ModuleProvider *CheckVarargs(ModuleProvider *MP) {
|
|||||||
|
|
||||||
/// getBytecodeBufferModuleProvider - lazy function-at-a-time loading from a
|
/// getBytecodeBufferModuleProvider - lazy function-at-a-time loading from a
|
||||||
/// buffer
|
/// buffer
|
||||||
ModuleProvider*
|
ModuleProvider*
|
||||||
llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
|
llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
|
||||||
unsigned Length,
|
unsigned Length,
|
||||||
const std::string &ModuleID,
|
const std::string &ModuleID,
|
||||||
@ -313,7 +313,7 @@ Module* llvm::AnalyzeBytecodeBuffer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
|
bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
|
||||||
Module::LibraryListType& deplibs) {
|
Module::LibraryListType& deplibs) {
|
||||||
try {
|
try {
|
||||||
std::auto_ptr<ModuleProvider> AMP( getBytecodeModuleProvider(fname));
|
std::auto_ptr<ModuleProvider> AMP( getBytecodeModuleProvider(fname));
|
||||||
@ -346,7 +346,7 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) {
|
|||||||
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
||||||
std::vector<std::string>& symbols) {
|
std::vector<std::string>& symbols) {
|
||||||
try {
|
try {
|
||||||
std::auto_ptr<ModuleProvider> AMP(
|
std::auto_ptr<ModuleProvider> AMP(
|
||||||
getBytecodeModuleProvider(fName.toString()));
|
getBytecodeModuleProvider(fName.toString()));
|
||||||
|
|
||||||
// Get the module from the provider
|
// Get the module from the provider
|
||||||
@ -363,7 +363,7 @@ bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleProvider*
|
ModuleProvider*
|
||||||
llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
||||||
const std::string& ModuleID,
|
const std::string& ModuleID,
|
||||||
std::vector<std::string>& symbols) {
|
std::vector<std::string>& symbols) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user