summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-05-06 19:42:57 +0000
committerChris Lattner <sabre@nondot.org>2007-05-06 19:42:57 +0000
commita066e378e92805ca7468a721468180587923abdf (patch)
tree767a36463e5ac0afd8fa8a161e1eb0464f9d8c32
parentb11f1a9ee167d278923e741cd11ccd0bfe58f816 (diff)
downloadllvm-a066e378e92805ca7468a721468180587923abdf.tar.gz
llvm-a066e378e92805ca7468a721468180587923abdf.tar.bz2
llvm-a066e378e92805ca7468a721468180587923abdf.tar.xz
remove bytecode reader
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36882 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Bytecode/Reader/Analyzer.cpp673
-rw-r--r--lib/Bytecode/Reader/Makefile14
-rw-r--r--lib/Bytecode/Reader/Reader.cpp2212
-rw-r--r--lib/Bytecode/Reader/Reader.h491
-rw-r--r--lib/Bytecode/Reader/ReaderWrappers.cpp256
5 files changed, 0 insertions, 3646 deletions
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp
deleted file mode 100644
index 2d90c93826..0000000000
--- a/lib/Bytecode/Reader/Analyzer.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-//===-- Analyzer.cpp - Analysis and Dumping of Bytecode ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by Reid Spencer and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the AnalyzerHandler class and PrintBytecodeAnalysis
-// function which together comprise the basic functionality of the llmv-abcd
-// tool. The AnalyzerHandler collects information about the bytecode file into
-// the BytecodeAnalysis structure. The PrintBytecodeAnalysis function prints
-// out the content of that structure.
-// @see include/llvm/Bytecode/Analysis.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "Reader.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Bytecode/BytecodeHandler.h"
-#include "llvm/Assembly/Writer.h"
-#include <iomanip>
-#include <sstream>
-#include <ios>
-using namespace llvm;
-
-namespace {
-
-/// @brief Bytecode reading handler for analyzing bytecode.
-class AnalyzerHandler : public BytecodeHandler {
- BytecodeAnalysis& bca; ///< The structure in which data is recorded
- std::ostream* os; ///< A convenience for osing data.
- /// @brief Keeps track of current function
- BytecodeAnalysis::BytecodeFunctionInfo* currFunc;
- Module* M; ///< Keeps track of current module
-
-/// @name Constructor
-/// @{
-public:
- /// The only way to construct an AnalyzerHandler. All that is needed is a
- /// reference to the BytecodeAnalysis structure where the output will be
- /// placed.
- AnalyzerHandler(BytecodeAnalysis& TheBca, std::ostream* output)
- : bca(TheBca)
- , os(output)
- , currFunc(0)
- { }
-
-/// @}
-/// @name BytecodeHandler Implementations
-/// @{
-public:
- virtual void handleError(const std::string& str ) {
- if (os)
- *os << "ERROR: " << str << "\n";
- }
-
- virtual void handleStart( Module* Mod, unsigned theSize ) {
- M = Mod;
- if (os)
- *os << "Bytecode {\n";
- bca.byteSize = theSize;
- bca.ModuleId.clear();
- bca.numBlocks = 0;
- bca.numTypes = 0;
- bca.numValues = 0;
- bca.numFunctions = 0;
- bca.numConstants = 0;
- bca.numGlobalVars = 0;
- bca.numInstructions = 0;
- bca.numBasicBlocks = 0;
- bca.numOperands = 0;
- bca.numCmpctnTables = 0;
- bca.numSymTab = 0;
- bca.numLibraries = 0;
- bca.libSize = 0;
- bca.maxTypeSlot = 0;
- bca.maxValueSlot = 0;
- bca.numAlignment = 0;
- bca.fileDensity = 0.0;
- bca.globalsDensity = 0.0;
- bca.functionDensity = 0.0;
- bca.instructionSize = 0;
- bca.longInstructions = 0;
- bca.FunctionInfo.clear();
- bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse] = 0;
- bca.BlockSizes[BytecodeFormat::ModuleBlockID] = theSize;
- bca.BlockSizes[BytecodeFormat::FunctionBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::ValueSymbolTableBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::InstructionListBlockID] = 0;
- bca.BlockSizes[BytecodeFormat::TypeSymbolTableBlockID] = 0;
- }
-
- virtual void handleFinish() {
- if (os)
- *os << "} End Bytecode\n";
-
- bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues );
- double globalSize = 0.0;
- globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]);
- globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]);
- globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]);
- bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants +
- bca.numGlobalVars );
- bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]) /
- double(bca.numFunctions);
-
- if (bca.progressiveVerify) {
- std::string msg;
- if (verifyModule(*M, ReturnStatusAction, &msg))
- bca.VerifyInfo += "Verify@Finish: " + msg + "\n";
- }
- }
-
- virtual void handleModuleBegin(const std::string& id) {
- if (os)
- *os << " Module " << id << " {\n";
- bca.ModuleId = id;
- }
-
- virtual void handleModuleEnd(const std::string& id) {
- if (os)
- *os << " } End Module " << id << "\n";
- if (bca.progressiveVerify) {
- std::string msg;
- if (verifyModule(*M, ReturnStatusAction, &msg))
- bca.VerifyInfo += "Verify@EndModule: " + msg + "\n";
- }
- }
-
- virtual void handleVersionInfo(
- unsigned char RevisionNum ///< Byte code revision number
- ) {
- if (os)
- *os << " RevisionNum: " << int(RevisionNum) << "\n";
- bca.version = RevisionNum;
- }
-
- virtual void handleModuleGlobalsBegin() {
- if (os)
- *os << " BLOCK: ModuleGlobalInfo {\n";
- }
-
- virtual void handleGlobalVariable(
- const Type* ElemType,
- bool isConstant,
- GlobalValue::LinkageTypes Linkage,
- GlobalValue::VisibilityTypes Visibility,
- unsigned SlotNum,
- unsigned initSlot,
- bool isThreadLocal
- ) {
- if (os) {
- *os << " GV: "
- << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, "
- << ( isConstant? "Constant, " : "Variable, ")
- << " Thread Local = " << ( isThreadLocal? "yes, " : "no, ")
- << " Linkage=" << Linkage
- << " Visibility="<< Visibility
- << " Type=";
- //WriteTypeSymbolic(*os, ElemType, M);
- *os << " Slot=" << SlotNum << " InitSlot=" << initSlot
- << "\n";
- }
-
- bca.numGlobalVars++;
- bca.numValues++;
- if (SlotNum > bca.maxValueSlot)
- bca.maxValueSlot = SlotNum;
- if (initSlot > bca.maxValueSlot)
- bca.maxValueSlot = initSlot;
-
- }
-
- virtual void handleGlobalAlias(
- const Type* ElemType,
- GlobalValue::LinkageTypes Linkage,
- unsigned TypeSlotNum,
- unsigned AliaseeSlot) {
- if (os) {
- *os << " GA: "
- << " Linkage=" << Linkage
- << " Type=";
- //WriteTypeSymbolic(*os, ElemType, M);
- *os << " Slot=" << TypeSlotNum << " AliaseeSlot=" << AliaseeSlot
- << "\n";
- }
-
- bca.numValues++;
- if (TypeSlotNum > bca.maxValueSlot)
- bca.maxValueSlot = TypeSlotNum;
- if (AliaseeSlot > bca.maxValueSlot)
- bca.maxValueSlot = AliaseeSlot;
- }
-
- virtual void handleTypeList(unsigned numEntries) {
- bca.maxTypeSlot = numEntries - 1;
- }
-
- virtual void handleType( const Type* Ty ) {
- bca.numTypes++;
- if (os) {
- *os << " Type: ";
- //WriteTypeSymbolic(*os,Ty,M);
- *os << "\n";
- }
- }
-
- virtual void handleFunctionDeclaration(
- Function* Func ///< The function
- ) {
- bca.numFunctions++;
- bca.numValues++;
- if (os) {
- *os << " Function Decl: ";
- //WriteTypeSymbolic(*os,Func->getType(),M);
- *os <<", Linkage=" << Func->getLinkage();
- *os <<", Visibility=" << Func->getVisibility();
- *os << "\n";
- }
- }
-
- virtual void handleGlobalInitializer(GlobalVariable* GV, Constant* CV) {
- if (os) {
- *os << " Initializer: GV=";
- GV->print(*os);
- *os << " CV=";
- CV->print(*os);
- *os << "\n";
- }
- }
-
- virtual void handleDependentLibrary(const std::string& libName) {
- bca.numLibraries++;
- bca.libSize += libName.size() + (libName.size() < 128 ? 1 : 2);
- if (os)
- *os << " Library: '" << libName << "'\n";
- }
-
- virtual void handleModuleGlobalsEnd() {
- if (os)
- *os << " } END BLOCK: ModuleGlobalInfo\n";
- if (bca.progressiveVerify) {
- std::string msg;
- if (verifyModule(*M, ReturnStatusAction, &msg))
- bca.VerifyInfo += "Verify@EndModuleGlobalInfo: " + msg + "\n";
- }
- }
-
- virtual void handleTypeSymbolTableBegin(TypeSymbolTable* ST) {
- bca.numSymTab++;
- if (os)
- *os << " BLOCK: TypeSymbolTable {\n";
- }
- virtual void handleValueSymbolTableBegin(Function* CF, ValueSymbolTable* ST) {
- bca.numSymTab++;
- if (os)
- *os << " BLOCK: ValueSymbolTable {\n";
- }
-
- virtual void handleSymbolTableType(unsigned i, unsigned TypSlot,
- const std::string& name ) {
- if (os)
- *os << " Type " << i << " Slot=" << TypSlot
- << " Name: " << name << "\n";
- }
-
- virtual void handleSymbolTableValue(unsigned TySlot, unsigned ValSlot,
- const char *Name, unsigned NameLen) {
- if (os)
- *os << " Value " << TySlot << " Slot=" << ValSlot
- << " Name: " << std::string(Name, Name+NameLen) << "\n";
- if (ValSlot > bca.maxValueSlot)
- bca.maxValueSlot = ValSlot;
- }
-
- virtual void handleValueSymbolTableEnd() {
- if (os)
- *os << " } END BLOCK: ValueSymbolTable\n";
- }
-
- virtual void handleTypeSymbolTableEnd() {
- if (os)
- *os << " } END BLOCK: TypeSymbolTable\n";
- }
-
- virtual void handleFunctionBegin(Function* Func, unsigned Size) {
- if (os) {
- *os << " BLOCK: Function {\n"
- << " Linkage: " << Func->getLinkage() << "\n"
- << " Visibility: " << Func->getVisibility() << "\n"
- << " Type: ";
- //WriteTypeSymbolic(*os,Func->getType(),M);
- *os << "\n";
- }
-
- currFunc = &bca.FunctionInfo[Func];
- std::ostringstream tmp;
- //WriteTypeSymbolic(tmp,Func->getType(),M);
- currFunc->description = tmp.str();
- currFunc->name = Func->getName();
- currFunc->byteSize = Size;
- currFunc->numInstructions = 0;
- currFunc->numBasicBlocks = 0;
- currFunc->numPhis = 0;
- currFunc->numOperands = 0;
- currFunc->density = 0.0;
- currFunc->instructionSize = 0;
- currFunc->longInstructions = 0;
-
- }
-
- virtual void handleFunctionEnd( Function* Func) {
- if (os)
- *os << " } END BLOCK: Function\n";
- currFunc->density = double(currFunc->byteSize) /
- double(currFunc->numInstructions);
-
- if (bca.progressiveVerify) {
- std::string msg;
- if (verifyModule(*M, ReturnStatusAction, &msg))
- bca.VerifyInfo += "Verify@EndFunction: " + msg + "\n";
- }
- }
-
- virtual void handleBasicBlockBegin( unsigned blocknum) {
- if (os)
- *os << " BLOCK: BasicBlock #" << blocknum << "{\n";
- bca.numBasicBlocks++;
- bca.numValues++;
- if ( currFunc ) currFunc->numBasicBlocks++;
- }
-
- virtual bool handleInstruction( unsigned Opcode, const Type* iType,
- unsigned *Operands, unsigned NumOps,
- Instruction *Inst,
- unsigned Size){
- if (os) {
- *os << " INST: OpCode="
- << Instruction::getOpcodeName(Opcode);
- for (unsigned i = 0; i != NumOps; ++i)
- *os << " Op(" << Operands[i] << ")";
- *os << *Inst;
- }
-
- bca.numInstructions++;
- bca.numValues++;
- bca.instructionSize += Size;
- if (Size > 4 ) bca.longInstructions++;
- bca.numOperands += NumOps;
- for (unsigned i = 0; i != NumOps; ++i)
- if (Operands[i] > bca.maxValueSlot)
- bca.maxValueSlot = Operands[i];
- if ( currFunc ) {
- currFunc->numInstructions++;
- currFunc->instructionSize += Size;
- if (Size > 4 ) currFunc->longInstructions++;
- if (Opcode == Instruction::PHI) currFunc->numPhis++;
- }
- return Instruction::isTerminator(Opcode);
- }
-
- virtual void handleBasicBlockEnd(unsigned blocknum) {
- if (os)
- *os << " } END BLOCK: BasicBlock #" << blocknum << "\n";
- }
-
- virtual void handleGlobalConstantsBegin() {
- if (os)
- *os << " BLOCK: GlobalConstants {\n";
- }
-
- virtual void handleConstantExpression(unsigned Opcode,
- Constant**ArgVec, unsigned NumArgs, Constant* C) {
- if (os) {
- *os << " EXPR: " << Instruction::getOpcodeName(Opcode) << "\n";
- for ( unsigned i = 0; i != NumArgs; ++i ) {
- *os << " Arg#" << i << " "; ArgVec[i]->print(*os);
- *os << "\n";
- }
- *os << " Value=";
- C->print(*os);
- *os << "\n";
- }
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantValue( Constant * c ) {
- if (os) {
- *os << " VALUE: ";
- c->print(*os);
- *os << "\n";
- }
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantArray( const ArrayType* AT,
- Constant**Elements, unsigned NumElts,
- unsigned TypeSlot,
- Constant* ArrayVal ) {
- if (os) {
- *os << " ARRAY: ";
- //WriteTypeSymbolic(*os,AT,M);
- *os << " TypeSlot=" << TypeSlot << "\n";
- for (unsigned i = 0; i != NumElts; ++i) {
- *os << " #" << i;
- Elements[i]->print(*os);
- *os << "\n";
- }
- *os << " Value=";
- ArrayVal->print(*os);
- *os << "\n";
- }
-
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantStruct(
- const StructType* ST,
- Constant**Elements, unsigned NumElts,
- Constant* StructVal)
- {
- if (os) {
- *os << " STRUC: ";
- //WriteTypeSymbolic(*os,ST,M);
- *os << "\n";
- for ( unsigned i = 0; i != NumElts; ++i) {
- *os << " #" << i << " "; Elements[i]->print(*os);
- *os << "\n";
- }
- *os << " Value=";
- StructVal->print(*os);
- *os << "\n";
- }
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantVector(
- const VectorType* PT,
- Constant**Elements, unsigned NumElts,
- unsigned TypeSlot,
- Constant* VectorVal)
- {
- if (os) {
- *os << " PACKD: ";
- //WriteTypeSymbolic(*os,PT,M);
- *os << " TypeSlot=" << TypeSlot << "\n";
- for ( unsigned i = 0; i != NumElts; ++i ) {
- *os << " #" << i;
- Elements[i]->print(*os);
- *os << "\n";
- }
- *os << " Value=";
- VectorVal->print(*os);
- *os << "\n";
- }
-
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantPointer( const PointerType* PT,
- unsigned Slot, GlobalValue* GV ) {
- if (os) {
- *os << " PNTR: ";
- //WriteTypeSymbolic(*os,PT,M);
- *os << " Slot=" << Slot << " GlobalValue=";
- GV->print(*os);
- *os << "\n";
- }
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleConstantString( const ConstantArray* CA ) {
- if (os) {
- *os << " STRNG: ";
- CA->print(*os);
- *os << "\n";
- }
- bca.numConstants++;
- bca.numValues++;
- }
-
- virtual void handleGlobalConstantsEnd() {
- if (os)
- *os << " } END BLOCK: GlobalConstants\n";
-
- if (bca.progressiveVerify) {
- std::string msg;
- if (verifyModule(*M, ReturnStatusAction, &msg))
- bca.VerifyInfo += "Verify@EndGlobalConstants: " + msg + "\n";
- }
- }
-
- virtual void handleAlignment(unsigned numBytes) {
- bca.numAlignment += numBytes;
- }
-
- virtual void handleBlock(
- unsigned BType, const unsigned char* StartPtr, unsigned Size) {
- bca.numBlocks++;
- assert(BType >= BytecodeFormat::ModuleBlockID);
- assert(BType < BytecodeFormat::NumberOfBlockIDs);
- bca.BlockSizes[
- llvm::BytecodeFormat::BytecodeBlockIdentifiers(BType)] += Size;
-
- if (bca.version < 3) // Check for long block headers versions
- bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 8;
- else
- bca.BlockSizes[llvm::BytecodeFormat::Reserved_DoNotUse] += 4;
- }
-
-};
-} // end anonymous namespace
-
-/// @brief Utility for printing a titled unsigned value with
-/// an aligned colon.
-inline static void print(std::ostream& Out, const char*title,
- unsigned val, bool nl = true ) {
- Out << std::setw(30) << std::right << title
- << std::setw(0) << ": "
- << std::setw(9) << val << "\n";
-}
-
-/// @brief Utility for printing a titled double value with an
-/// aligned colon
-inline static void print(std::ostream&Out, const char*title,
- double val ) {
- Out << std::setw(30) << std::right << title
- << std::setw(0) << ": "
- << std::setw(9) << std::setprecision(6) << val << "\n" ;
-}
-
-/// @brief Utility for printing a titled double value with a
-/// percentage and aligned colon.
-inline static void print(std::ostream&Out, const char*title,
- double top, double bot ) {
- Out << std::setw(30) << std::right << title
- << std::setw(0) << ": "
- << std::setw(9) << std::setprecision(6) << top
- << " (" << std::left << std::setw(0) << std::setprecision(4)
- << (top/bot)*100.0 << "%)\n";
-}
-
-/// @brief Utility for printing a titled string value with
-/// an aligned colon.
-inline static void print(std::ostream&Out, const char*title,
- std::string val, bool nl = true) {
- Out << std::setw(30) << std::right << title
- << std::setw(0) << ": "
- << std::left << val << (nl ? "\n" : "");
-}
-
-/// This function prints the contents of rhe BytecodeAnalysis structure in
-/// a human legible form.
-/// @brief Print BytecodeAnalysis structure to an ostream
-void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out )
-{
- Out << "\nSummary Analysis Of " << bca.ModuleId << ": \n\n";
- print(Out, "Bytecode Analysis Of Module", bca.ModuleId);
- print(Out, "Bytecode Version Number", bca.version);
- print(Out, "File Size", bca.byteSize);
- print(Out, "Module Bytes",
- double(bca.BlockSizes[BytecodeFormat::ModuleBlockID]),
- double(bca.byteSize));
- print(Out, "Function Bytes",
- double(bca.BlockSizes[BytecodeFormat::FunctionBlockID]),
- double(bca.byteSize));
- print(Out, "Global Types Bytes",
- double(bca.BlockSizes[BytecodeFormat::GlobalTypePlaneBlockID]),
- double(bca.byteSize));
- print(Out, "Constant Pool Bytes",
- double(bca.BlockSizes[BytecodeFormat::ConstantPoolBlockID]),
- double(bca.byteSize));
- print(Out, "Module Globals Bytes",
- double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfoBlockID]),
- double(bca.byteSize));
- print(Out, "Instruction List Bytes",
- double(bca.BlockSizes[BytecodeFormat::InstructionListBlockID]),
- double(bca.byteSize));
- print(Out, "Value Symbol Table Bytes",
- double(bca.BlockSizes[BytecodeFormat::ValueSymbolTableBlockID]),
- double(bca.byteSize));
- print(Out, "Type Symbol Table Bytes",
- double(bca.BlockSizes[BytecodeFormat::TypeSymbolTableBlockID]),
- double(bca.byteSize));
- print(Out, "Alignment Bytes",
- double(bca.numAlignment), double(bca.byteSize));
- print(Out, "Block Header Bytes",
- double(bca.BlockSizes[BytecodeFormat::Reserved_DoNotUse]),
- double(bca.byteSize));
- print(Out, "Dependent Libraries Bytes", double(bca.libSize),
- double(bca.byteSize));
- print(Out, "Number Of Bytecode Blocks", bca.numBlocks);
- print(Out, "Number Of Functions", bca.numFunctions);
- print(Out, "Number Of Types", bca.numTypes);
- print(Out, "Number Of Constants", bca.numConstants);
- print(Out, "Number Of Global Variables", bca.numGlobalVars);
- print(Out, "Number Of Values", bca.numValues);
- print(Out, "Number Of Basic Blocks", bca.numBasicBlocks);
- print(Out, "Number Of Instructions", bca.numInstructions);
- print(Out, "Number Of Long Instructions", bca.longInstructions);
- print(Out, "Number Of Operands", bca.numOperands);
- print(Out, "Number Of Symbol Tables", bca.numSymTab);
- print(Out, "Number Of Dependent Libs", bca.numLibraries);
- print(Out, "Total Instruction Size", bca.instructionSize);
- print(Out, "Average Instruction Size",
- double(bca.instructionSize)/double(bca.numInstructions));
-
- print(Out, "Maximum Type Slot Number", bca.maxTypeSlot);
- print(Out, "Maximum Value Slot Number", bca.maxValueSlot);
- print(Out, "Bytes Per Value ", bca.fileDensity);
- print(Out, "Bytes Per Global", bca.globalsDensity);
- print(Out, "Bytes Per Function", bca.functionDensity);
-
- if (bca.detailedResults) {
- Out << "\nDetailed Analysis Of " << bca.ModuleId << " Functions:\n";
-
- std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I =
- bca.FunctionInfo.begin();
- std::map<const Function*,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E =
- bca.FunctionInfo.end();
-
- while ( I != E ) {
- Out << std::left << std::setw(0) << "\n";
- if (I->second.numBasicBlocks == 0) Out << "External ";
- Out << "Function: " << I->second.name << "\n";
- print(Out, "Type:", I->second.description);
- print(Out, "Byte Size", I->second.byteSize);
- if (I->second.numBasicBlocks) {
- print(Out, "Basic Blocks", I->second.numBasicBlocks);
- print(Out, "Instructions", I->second.numInstructions);
- print(Out, "Long Instructions", I->second.longInstructions);
- print(Out, "Operands", I->second.numOperands);
- print(Out, "Instruction Size", I->second.instructionSize);
- print(Out, "Average Instruction Size",
- double(I->second.instructionSize) / I->second.numInstructions);
- print(Out, "Bytes Per Instruction", I->second.density);
- }
- ++I;
- }
- }
-
- if ( bca.progressiveVerify )
- Out << bca.VerifyInfo;
-}
-
-// AnalyzeBytecodeFile - analyze one file
-Module* llvm::AnalyzeBytecodeFile(const std::string &Filename, ///< File to analyze
- BytecodeAnalysis& bca, ///< Statistical output
- BCDecompressor_t *BCDC,
- std::string *ErrMsg, ///< Error output
- std::ostream* output ///< Dump output
- ) {
- BytecodeHandler* AH = new AnalyzerHandler(bca, output);
- ModuleProvider* MP = getBytecodeModuleProvider(Filename, BCDC, ErrMsg, AH);
- if (!MP) return 0;
- Module *M = MP->releaseModule(ErrMsg);
- delete MP;
- return M;
-}
diff --git a/lib/Bytecode/Reader/Makefile b/lib/Bytecode/Reader/Makefile
deleted file mode 100644
index a86d008715..0000000000
--- a/lib/Bytecode/Reader/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Bytecode/Reader/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file was developed by the LLVM research group and is distributed under
-# the University of Illinois Open Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-LIBRARYNAME = LLVMBCReader
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
deleted file mode 100644
index e75f0fcd61..0000000000
--- a/lib/Bytecode/Reader/Reader.cpp
+++ /dev/null
@@ -1,2212 +0,0 @@
-//===- Reader.cpp - Code to read bytecode files ---------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This library implements the functionality defined in llvm/Bytecode/Reader.h
-//
-// Note that this library should be as fast as possible, reentrant, and
-// threadsafe!!
-//
-// TODO: Allow passing in an option to ignore the symbol table
-//
-//===----------------------------------------------------------------------===//
-
-#include "Reader.h"
-#include "llvm/Bytecode/BytecodeHandler.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/ParameterAttributes.h"
-#include "llvm/TypeSymbolTable.h"
-#include "llvm/Bytecode/Format.h"
-#include "llvm/Config/alloca.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include <sstream>
-#include <algorithm>
-using namespace llvm;
-
-namespace {
- /// @brief A class for maintaining the slot number definition
- /// as a placeholder for the actual definition for forward constants defs.
- class ConstantPlaceHolder : public ConstantExpr {
- ConstantPlaceHolder(); // DO NOT IMPLEMENT
- void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
- public:
- Use Op;
- ConstantPlaceHolder(const Type *Ty)
- : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
- Op(UndefValue::get(Type::Int32Ty), this) {
- }
- };
-}
-
-// Provide some details on error
-inline void BytecodeReader::error(const std::string& err) {
- ErrorMsg = err + " (Vers=" + itostr(RevisionNum) + ", Pos="
- + itostr(At-MemStart) + ")";
- if (Handler) Handler->handleError(ErrorMsg);
- longjmp(context,1);
-}
-
-//===----------------------------------------------------------------------===//
-// Bytecode Reading Methods
-//===----------------------------------------------------------------------===//
-
-/// Determine if the current block being read contains any more data.
-inline bool BytecodeReader::moreInBlock() {
- return At < BlockEnd;
-}
-
-/// Throw an error if we've read past the end of the current block
-inline void BytecodeReader::checkPastBlockEnd(const char * block_name) {
- if (At > BlockEnd)
- error(std::string("Attempt to read past the end of ") + block_name +
- " block.");
-}
-
-/// Read a whole unsigned integer
-inline unsigned BytecodeReader::read_uint() {
- if (At+4 > BlockEnd)
- error("Ran out of data reading uint!");
- At += 4;
- return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24);
-}
-
-/// Read a variable-bit-rate encoded unsigned integer
-inline unsigned BytecodeReader::read_vbr_uint() {
- unsigned Shift = 0;
- unsigned Result = 0;
-
- do {
- if (At == BlockEnd)
- error("Ran out of data reading vbr_uint!");
- Result |= (unsigned)((*At++) & 0x7F) << Shift;
- Shift += 7;
- } while (At[-1] & 0x80);
- return Result;
-}
-
-/// Read a variable-bit-rate encoded unsigned 64-bit integer.
-inline uint64_t BytecodeReader::read_vbr_uint64() {
- unsigned Shift = 0;
- uint64_t Result = 0;
-
- do {
- if (At == BlockEnd)
- error("Ran out of data reading vbr_uint64!");
- Result |= (uint64_t)((*At++) & 0x7F) << Shift;
- Shift += 7;
- } while (At[-1] & 0x80);
- return Result;
-}
-
-/// Read a variable-bit-rate encoded signed 64-bit integer.
-inline int64_t BytecodeReader::read_vbr_int64() {
- uint64_t R = read_vbr_uint64();
- if (R & 1) {
- if (R != 1)
- return -(int64_t)(R >> 1);
- else // There is no such thing as -0 with integers. "-0" really means
- // 0x8000000000000000.
- return 1LL << 63;
- } else
- return (int64_t)(R >> 1);
-}
-
-/// Read a pascal-style string (length followed by text)
-inline std::string BytecodeReader::read_str() {
- unsigned Size = read_vbr_uint();
- const unsigned char *OldAt = At;
- At += Size;
- if (At > BlockEnd) // Size invalid?
- error("Ran out of data reading a string!");
- return std::string((char*)OldAt, Size);
-}
-
-void BytecodeReader::read_str(SmallVectorImpl<char> &StrData) {
- StrData.clear();
- unsigned Size = read_vbr_uint();
- const unsigned char *OldAt = At;
- At += Size;
- if (At > BlockEnd) // Size invalid?
- error("Ran out of data reading a string!");
- StrData.append(OldAt, At);
-}
-
-
-/// Read an arbitrary block of data
-inline void BytecodeReader::read_data(void *Ptr, void *End) {
- unsigned char *Start = (unsigned char *)Ptr;
- unsigned Amount = (unsigned char *)End - Start;
- if (At+Amount > BlockEnd)
- error("Ran out of data!");
- std::copy(At, At+Amount, Start);
- At += Amount;
-}
-
-/// Read a float value in little-endian order
-inline void BytecodeReader::read_float(float& FloatVal) {
- /// FIXME: This isn't optimal, it has size problems on some platforms
- /// where FP is not IEEE.
- FloatVal = BitsToFloat(At[0] | (At[1] << 8) | (At[2] << 16) | (At[3] << 24));
- At+=sizeof(uint32_t);
-}
-
-/// Read a double value in little-endian order
-inline void BytecodeReader::read_double(double& DoubleVal) {
- /// FIXME: This isn't optimal, it has size problems on some platforms
- /// where FP is not IEEE.
- DoubleVal = BitsToDouble((uint64_t(At[0]) << 0) | (uint64_t(At[1]) << 8) |
- (uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
- (uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
- (uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56));
- At+=sizeof(uint64_t);
-}
-
-/// Read a block header and obtain its type and size
-inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
- Size = read_uint(); // Read the header
- Type = Size & 0x1F; // mask low order five bits to get type
- Size >>= 5; // high order 27 bits is the size
- BlockStart = At;
- if (At + Size > BlockEnd)
- error("Attempt to size a block past end of memory");
- BlockEnd = At + Size;
- if (Handler) Handler->handleBlock(Type, BlockStart, Size);
-}
-
-//===----------------------------------------------------------------------===//
-// IR Lookup Methods
-//===----------------------------------------------------------------------===//
-
-/// Determine if a type id has an implicit null value
-inline bool BytecodeReader::hasImplicitNull(unsigned TyID) {
- return TyID != Type::LabelTyID && TyID != Type::VoidTyID;
-}
-
-/// Obtain a type given a typeid and account for things like function level vs
-/// module level, and the offsetting for the primitive types.
-const Type *BytecodeReader::getType(unsigned ID) {
- if (ID <= Type::LastPrimitiveTyID)
- if (const Type *T = Type::getPrimitiveType((Type::TypeID)ID))
- return T; // Asked for a primitive type...
-
- // Otherwise, derived types need offset...
- ID -= Type::FirstDerivedTyID;
-
- // Is it a module-level type?
- if (ID < ModuleTypes.size())
- return ModuleTypes[ID].get();
-
- // Nope, is it a function-level type?
- ID -= ModuleTypes.size();
- if (ID < FunctionTypes.size())
- return FunctionTypes[ID].get();
-
- error("Illegal type reference!");
- return Type::VoidTy;
-}
-
-/// This method just saves some coding. It uses read_vbr_uint to read in a
-/// type id, errors that its not the type type, and then calls getType to
-/// return the type value.
-inline const Type* BytecodeReader::readType() {
- return getType(read_vbr_uint());
-}
-
-/// Get the slot number associated with a type accounting for primitive
-/// types and function level vs module level.
-unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
- if (Ty->isPrimitiveType())
- return Ty->getTypeID();
-
- // Check the function level types first...
- TypeListTy::iterator I = std::find(FunctionTypes.begin(),
- FunctionTypes.end(), Ty);
-
- if (I != FunctionTypes.end())
- return Type::FirstDerivedTyID + ModuleTypes.size() +
- (&*I - &FunctionTypes[0]);
-
- // If we don't have our cache yet, build it now.
- if (ModuleTypeIDCache.empty()) {
- unsigned N = 0;
- ModuleTypeIDCache.reserve(ModuleTypes.size());
- for (TypeListTy::iterator I = ModuleTypes.begin(), E = ModuleTypes.end();
- I != E; ++I, ++N)
- ModuleTypeIDCache.push_back(std::make_pair(*I, N));
-
- std::sort(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end());
- }
-
- // Binary search the cache for the entry.
- std::vector<std::pair<const Type*, unsigned> >::iterator IT =
- std::lower_bound(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end(),
- std::make_pair(Ty, 0U));
- if (IT == ModuleTypeIDCache.end() || IT->first != Ty)
- error("Didn't find type in ModuleTypes.");
-
- return Type::FirstDerivedTyID + IT->second;
-}
-
-/// Retrieve a value of a given type and slot number, possibly creating
-/// it if it doesn't already exist.
-Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
- assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
- unsigned Num = oNum;
-
- // By default, the global type id is the type id passed in
- unsigned GlobalTyID = type;
-
- if (hasImplicitNull(GlobalTyID)) {
- const Type *Ty = getType(type);
- if (!isa<OpaqueType>(Ty)) {
- if (Num == 0)
- return Constant::getNullValue(Ty);
- --Num;
- }
- }
-
- if (GlobalTyID < ModuleValues.size())
- if (ValueList *Globals = ModuleValues[GlobalTyID]) {
- if (Num < Globals->size())
- return Globals->getOperand(Num);
- Num -= Globals->size();
- }
-
- if (type < FunctionValues.size())
- if (ValueList *Locals = FunctionValues[type])
- if (Num < Locals->size())
- return Locals->getOperand(Num);
-
- // We did not find the value.
-
- if (!Create) return 0; // Do not create a placeholder?
-
- // Did we already create a place holder?
- std::pair<unsigned,unsigned> KeyValue(type, oNum);
- ForwardReferenceMap::iterator I = ForwardReferences.lower_bound(KeyValue);
- if (I != ForwardReferences.end() && I->first == KeyValue)
- return I->second; // We have already created this placeholder
-
- // If the type exists (it should)
- if (const Type* Ty = getType(type)) {
- // Create the place holder
- Value *Val = new Argument(Ty);
- ForwardReferences.insert(I, std::make_pair(KeyValue, Val));
- return Val;
- }
- error("Can't create placeholder for value of type slot #" + utostr(type));
- return 0; // just silence warning, error calls longjmp
-}
-
-
-/// Just like getValue, except that it returns a null pointer
-/// 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
-/// constant hasn't been parsed yet, a placeholder is defined and used.
-/// Later, after the real value is parsed, the placeholder is eliminated.
-Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
- if (Value *V = getValue(TypeSlot, Slot, false))
- if (Constant *C = dyn_cast<Constant>(V))
- return C; // If we already have the value parsed, just return it
- else
- error("Value for slot " + utostr(Slot) +
- " is expected to be a constant!");
-
- std::pair<unsigned, unsigned> Key(TypeSlot, Slot);
- ConstantRefsType::iterator I = ConstantFwdRefs.lower_bound(Key);
-
- if (I != ConstantFwdRefs.end() && I->first == Key) {
- return I->second;
- } else {
- // Create a placeholder for the constant reference and
- // keep track of the fact that we have a forward ref to recycle it
- Constant *C = new ConstantPlaceHolder(getType(TypeSlot));
-
- // Keep track of the fact that we have a forward ref to recycle it
- ConstantFwdRefs.insert(I, std::make_pair(Key, C));
- return C;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// IR Construction Methods
-//===----------------------------------------------------------------------===//
-
-/// As values are created, they are inserted into the appropriate place
-/// with this method. The ValueTable argument must be one of ModuleValues
-/// or FunctionValues data members of this class.
-unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
- ValueTable &ValueTab) {
- if (ValueTab.size() <= type)
- ValueTab.resize(type+1);
-
- if (!ValueTab[type]) ValueTab[type] = new ValueList();
-
- ValueTab[type]->push_back(Val);
-
- bool HasOffset = hasImplicitNull(type) && !isa<OpaqueType>(Val->getType());
- return ValueTab[type]->size()-1 + HasOffset;
-}
-
-/// Insert the arguments of a function as new values in the reader.
-void BytecodeReader::insertArguments(Function* F) {
- const FunctionType *FT = F->getFunctionType();
- Function::arg_iterator AI = F->arg_begin();
- for (FunctionType::param_iterator It = FT->param_begin();
- It != FT->param_end(); ++It, ++AI)
- insertValue(AI, getTypeSlot(AI->getType()), FunctionValues);
-}
-
-//===----------------------------------------------------------------------===//
-// Bytecode Parsing Methods
-//===----------------------------------------------------------------------===//
-
-/// This method parses a single instruction. The instruction is
-/// inserted at the end of the \p BB provided. The arguments of
-/// the instruction are provided in the \p Oprnds vector.
-void BytecodeReader::ParseInstruction(SmallVector<unsigned, 8> &Oprnds,
- BasicBlock* BB) {
- BufPtr SaveAt = At;
-
- // Clear instruction data
- Oprnds.clear();
- unsigned iType = 0;
- unsigned Opcode = 0;
- unsigned Op = read_uint();
-
- // bits Instruction format: Common to all formats
- // --------------------------
- // 01-00: Opcode type, fixed to 1.
- // 07-02: Opcode
- Opcode = (Op >> 2) & 63;
- Oprnds.resize((Op >> 0) & 03);
-
- // Extract the operands
- switch (Oprnds.size()) {
- case 1:
- // bits Instruction format:
- // --------------------------
- // 19-08: Resulting type plane
- // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
- //
- iType = (Op >> 8) & 4095;
- Oprnds[0] = (Op >> 20) & 4095;
- if (Oprnds[0] == 4095) // Handle special encoding for 0 operands...
- Oprnds.resize(0);
- break;
- case 2:
- // bits Instruction format:
- // --------------------------
- // 15-08: Resulting type plane
- // 23-16: Operand #1
- // 31-24: Operand #2
- //
- iType = (Op >> 8) & 255;
- Oprnds[0] = (Op >> 16) & 255;
- Oprnds[1] = (Op >> 24) & 255;
- break;
- case 3:
- // bits Instruction format:
- // --------------------------
- // 13-08: Resulting type plane
- // 19-14: Operand #1
- // 25-20: Operand #2
- // 31-26: Operand #3
- //
- iType = (Op >> 8) & 63;
- Oprnds[0] = (Op >> 14) & 63;
- Oprnds[1] = (Op >> 20) & 63;
- Oprnds[2] = (Op >> 26) & 63;
- break;
- case 0:
- At -= 4; // Hrm, try this again...
- Opcode = read_vbr_uint();
- Opcode >>= 2;
- iType = read_vbr_uint();
-
- unsigned NumOprnds = read_vbr_uint();
- Oprnds.resize(NumOprnds);
-
- if (NumOprnds == 0)
- error("Zero-argument instruction found; this is invalid.");
-
- for (unsigned i = 0; i != NumOprnds; ++i)
- Oprnds[i] = read_vbr_uint();
- break;
- }
-
- const Type *InstTy = getType(iType);
-
- // Make the necessary adjustments for dealing with backwards compatibility
- // of opcodes.
- Instruction* Result = 0;
-
- // First, handle the easy binary operators case
- if (Opcode >= Instruction::BinaryOpsBegin &&
- Opcode < Instruction::BinaryOpsEnd && Oprnds.size() == 2) {
- Result = BinaryOperator::create(Instruction::BinaryOps(Opcode),
- getValue(iType, Oprnds[0]),
- getValue(iType, Oprnds[1]));
- } else {
- // Indicate that we don't think this is a call instruction (yet).
- // Process based on the Opcode read
- switch (Opcode) {
- default: // There was an error, this shouldn't happen.
- if (Result == 0)
- error("Illegal instruction read!");
- break;
- case Instruction::VAArg:
- if (Oprnds.size() != 2)
- error("Invalid VAArg instruction!");
- Result = new VAArgInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::ExtractElement: {
- if (Oprnds.size() != 2)
- error("Invalid extractelement instruction!");
- Value *V1 = getValue(iType, Oprnds[0]);
- Value *V2 = getValue(Int32TySlot, Oprnds[1]);
-
- if (!ExtractElementInst::isValidOperands(V1, V2))
- error("Invalid extractelement instruction!");
-
- Result = new ExtractElementInst(V1, V2);
- break;
- }
- case Instruction::InsertElement: {
- const VectorType *VectorTy = dyn_cast<VectorType>(InstTy);
- if (!VectorTy || Oprnds.size() != 3)
- error("Invalid insertelement instruction!");
-
- Value *V1 = getValue(iType, Oprnds[0]);
- Value *V2 = getValue(getTypeSlot(VectorTy->getElementType()),Oprnds[1]);
- Value *V3 = getValue(Int32TySlot, Oprnds[2]);
-
- if (!InsertElementInst::isValidOperands(V1, V2, V3))
- error("Invalid insertelement instruction!");
- Result = new InsertElementInst(V1, V2, V3);
- break;
- }
- case Instruction::ShuffleVector: {
- const VectorType *VectorTy = dyn_cast<VectorType>(InstTy);
- if (!VectorTy || Oprnds.size() != 3)
- error("Invalid shufflevector instruction!");
- Value *V1 = getValue(iType, Oprnds[0]);
- Value *V2 = getValue(iType, Oprnds[1]);
- const VectorType *EltTy =
- VectorType::get(Type::Int32Ty, VectorTy->getNumElements());
- Value *V3 = getValue(getTypeSlot(EltTy), Oprnds[2]);
- if (!ShuffleVectorInst::isValidOperands(V1, V2, V3))
- error("Invalid shufflevector instruction!");
- Result = new ShuffleVectorInst(V1, V2, V3);
- break;
- }
- case Instruction::Trunc:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new TruncInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::ZExt:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new ZExtInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::SExt:
- if (Oprnds.size() != 2)
- error("Invalid Cast instruction!");
- Result = new SExtInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::FPTrunc:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new FPTruncInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::FPExt:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new FPExtInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::UIToFP:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new UIToFPInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::SIToFP:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new SIToFPInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::FPToUI:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new FPToUIInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::FPToSI:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new FPToSIInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::IntToPtr:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new IntToPtrInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::PtrToInt:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new PtrToIntInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::BitCast:
- if (Oprnds.size() != 2)
- error("Invalid cast instruction!");
- Result = new BitCastInst(getValue(iType, Oprnds[0]),
- getType(Oprnds[1]));
- break;
- case Instruction::Select:
- if (Oprnds.size() != 3)
- error("Invalid Select instruction!");
- Result = new SelectInst(getValue(BoolTySlot, Oprnds[0]),
- getValue(iType, Oprnds[1]),
- getValue(iType, Oprnds[2]));
- break;
- case Instruction::PHI: {
- if (Oprnds.size() == 0 || (Oprnds.size() & 1))
- error("Invalid phi node encountered!");
-
- PHINode *PN = new PHINode(InstTy);
- PN->reserveOperandSpace(Oprnds.size());
- for (unsigned i = 0, e = Oprnds.size(); i != e; i += 2)
- PN->addIncoming(
- getValue(iType, Oprnds[i]), getBasicBlock(Oprnds[i+1]));
- Result = PN;
- break;
- }
- case Instruction::ICmp:
- case Instruction::FCmp:
- if (Oprnds.size() != 3)
- error("Cmp instructions requires 3 operands");
- // These instructions encode the comparison predicate as the 3rd operand.
- Result = CmpInst::create(Instruction::OtherOps(Opcode),
- static_cast<unsigned short>(Oprnds[2]),
- getValue(iType, Oprnds[0]), getValue(iType, Oprnds[1]));
- break;
- case Instruction::Ret:
- if (Oprnds.size() == 0)
- Result = new ReturnInst();
- else if (Oprnds.size() == 1)
- Result = new ReturnInst(getValue(iType, Oprnds[0]));
- else
- error("Unrecognized instruction!");
- break;
-
- case Instruction::Br:
- if (Oprnds.size() == 1)
- Result = new BranchInst(getBasicBlock(Oprnds[0]));
- else if (Oprnds.size() == 3)
- Result = new BranchInst(getBasicBlock(Oprnds[0]),
- getBasicBlock(Oprnds[1]), getValue(BoolTySlot, Oprnds[2]));
- else
- error("Invalid number of operands for a 'br' instruction!");
- break;
- case Instruction::Switch: {
- if (Oprnds.size() & 1)
- error("Switch statement with odd number of arguments!");
-
- SwitchInst *I = new SwitchInst(getValue(iType, Oprnds[0]),
- getBasicBlock(Oprnds[1]),
- Oprnds.size()/2-1);
- for (unsigned i = 2, e = Oprnds.size(); i != e; i += 2)
- I->addCase(cast<ConstantInt>(getValue(iType, Oprnds[i])),
- getBasicBlock(Oprnds[i+1]));
- Result = I;
- break;
- }
- case 58: // Call with extra operand for calling conv
- case 59: // tail call, Fast CC
- case 60: // normal call, Fast CC
- case 61: // tail call, C Calling Conv
- case Instruction::Call: { // Normal Call, C Calling Convention
- if (Oprnds.size() == 0)
- error("Invalid call instruction encountered!");
- Value *F = getValue(iType, Oprnds[0]);
-
- unsigned CallingConv = CallingConv::C;
- bool isTailCall = false;
-
- if (Opcode == 61 || Opcode == 59)
- isTailCall = true;
-
- if (Opcode == 58) {
- isTailCall = Oprnds.back() & 1;
- CallingConv = Oprnds.back() >> 1;
- Oprnds.pop_back();
- } else if (Opcode == 59 || Opcode == 60) {
- CallingConv = CallingConv::Fast;
- }
-
- // Check to make sure we have a pointer to function type
- const PointerType *PTy = dyn_cast<PointerType>(F->getType());
- if (PTy == 0) error("Call to non function pointer value!");
- const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
- if (FTy == 0) error("Call to non function pointer value!");
-
- SmallVector<Value *, 8> Params;
- if (!FTy->isVarArg()) {
- FunctionType::param_iterator It = FTy->param_begin();
-
- for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
- if (It == FTy->param_end())
- error("Invalid call instruction!");
- Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
- }
- if (It != FTy->param_end())
- error("Invalid call instruction!");
- } else {
- Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
-
- unsigned FirstVariableOperand;
- if (Oprnds.size() < FTy->getNumParams())
- error("Call instruction missing operands!");
-
- // Read all of the fixed arguments
- for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
- Params.push_back(
- getValue(getTypeSlot(FTy->getParamType(i)),Oprnds[i]));
-
- FirstVariableOperand = FTy->getNumParams();
-
- if ((Oprnds.size()-FirstVariableOperand) & 1)
- error("Invalid call instruction!"); // Must be pairs of type/value
-
- for (unsigned i = FirstVariableOperand, e = Oprnds.size();
- i != e; i += 2)
- Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
- }
-
- Result = new CallInst(F, &Params[0], Params.size());
- if (isTailCall) cast<CallInst>(Result)->setTailCall();
- if (CallingConv) cast<CallInst>(Result)->setCallingConv(CallingConv);
- break;
- }
- case Instruction::Invoke: { // Invoke C CC
- if (Oprnds.size() < 3)
- error("Invalid invoke instruction!");
- Value *F = getValue(iType, Oprnds[0]);
-
- // Check to make sure we have a pointer to function type
- const PointerType *PTy = dyn_cast<PointerType>(F->getType());
- if (PTy == 0)
- error("Invoke to non function pointer value!");
- const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
- if (FTy == 0)
- error("Invoke to non function pointer value!");
-
- SmallVector<Value *, 8> Params;
- BasicBlock *Normal, *Except;
- unsigned CallingConv = Oprnds.back();
- Oprnds.pop_back();
-
- if (!FTy->isVarArg()) {
- Normal = getBasicBlock(Oprnds[1]);
- Except = getBasicBlock(Oprnds[2]);
-
- FunctionType::param_iterator It = FTy->param_begin();
- for (unsigned i = 3, e = Oprnds.size(); i != e; ++i) {
- if (It == FTy->param_end())
- error("Invalid invoke instruction!");
- Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
- }
- if (It != FTy->param_end())
- error("Invalid invoke instruction!");
- } else {
- Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
-
- Normal = getBasicBlock(Oprnds[0]);
- Except = getBasicBlock(Oprnds[1]);
-
- unsigned FirstVariableArgument = FTy->getNumParams()+2;
- for (unsigned i = 2; i != FirstVariableArgument; ++i)
- Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
- Oprnds[i]));
-
- // Must be type/value pairs. If not, error out.
- if (Oprnds.size()-FirstVariableArgument & 1)
- error("Invalid invoke instruction!");
-
- for (unsigned i = FirstVariableArgument; i < Oprnds.size(); i += 2)
- Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
- }
-
- Result = new InvokeInst(F, Normal, Except, &Params[0], Params.size());
- if (CallingConv) cast<InvokeInst>(Result)->setCallingConv(CallingConv);
- break;
- }
- case Instruction::Malloc: {
- unsigned Align = 0;
- if (Oprnds.size() == 2)
- Align = (1 << Oprnds[1]) >> 1;
- else if (Oprnds.size() > 2)
- error("Invalid malloc instruction!");
- if (!isa<PointerType>(InstTy))
- error("Invalid malloc instruction!");
-
- Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
- getValue(Int32TySlot, Oprnds[0]), Align);
- break;
- }
- case Instruction::Alloca: {
- unsigned Align = 0;
- if (Oprnds.size() == 2)
- Align = (1 << Oprnds[1]) >> 1;
- else if (Oprnds.size() > 2)
- error("Invalid alloca instruction!");
- if (!isa<PointerType>(InstTy))
- error("Invalid alloca instruction!");
-
- Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
- getValue(Int32TySlot, Oprnds[0]), Align);
- break;
- }
- case Instruction::Free:
- if (!isa<PointerType>(InstTy))
- error("Invalid free instruction!");
- Result = new FreeInst(getValue(iType, Oprnds[0]));
- break;
- case Instruction::GetElementPtr: {
- if (Oprnds.size() == 0 || !isa<PointerType>(InstTy))
- error("Invalid getelementptr instruction!");
-
- SmallVector<Value*, 8> Idx;
-
- const Type *NextTy = InstTy;
- for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
- const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
- if (!TopTy)
- error("Invalid getelementptr instruction!");
-
- unsigned ValIdx = Oprnds[i];
- unsigned IdxTy = 0;
- // Struct indices are always uints, sequential type indices can be
- // any of the 32 or 64-bit integer types. The actual choice of
- // type is encoded in the low bit of the slot number.
- if (isa<StructType>(TopTy))
- IdxTy = Int32TySlot;
- else {
- switch (ValIdx & 1) {
- default:
- case 0: IdxTy = Int32TySlot; break;
- case 1: IdxTy = Int64TySlot; break;
- }
- ValIdx >>= 1;
- }
- Idx.push_back(getValue(IdxTy, ValIdx));
- NextTy = GetElementPtrInst::getIndexedType(InstTy, &Idx[0], Idx.size(),
- true);
- }
-
- Result = new GetElementPtrInst(getValue(iType, Oprnds[0]),
- &Idx[0], Idx.size());
- break;
- }
- case 62: { // attributed load
- if (Oprnds.size() != 2 || !isa<PointerType>(InstTy))
- error("Invalid attributed load instruction!");
- Result = new LoadInst(getValue(iType, Oprnds[0]), "", (Oprnds[1] & 1),
- (1 << (Oprnds[1]>>1)) >> 1);
- break;
- }
- case Instruction::Load:
- if (Oprnds.size() != 1 || !isa<PointerType>(InstTy))
- error("Invalid load instruction!");
- Result = new LoadInst(getValue(iType, Oprnds[0]), "");
- break;
- case 63: { // attributed store
- if (!isa<PointerType>(InstTy) || Oprnds.size() != 3)
- error("Invalid attributed store instruction!");
-
- Value *Ptr = getValue(iType, Oprnds[1]);
- const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
- Result = new StoreInst(getValue(getTypeSlot(ValTy), Oprnds[0]), Ptr,
- (Oprnds[2] & 1),
- (1 << (Oprnds[2]>>1)) >> 1);
- break;
- }
- case Instruction::Store: {
- if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
- error("Invalid store instruction!");
-
- Value *Ptr = getValue(iType, Oprnds[1]);
- const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
- Result = new StoreInst(getValue(getTypeSlot(ValTy), Oprnds[0]), Ptr,
- Opcode == 63);
- break;
- }
- case Instruction::Unwind:
- if (Oprnds.size() != 0) error("Invalid unwind instruction!");
- Result = new UnwindInst();
- break;
- case Instruction::Unreachable:
- if (Oprnds.size() != 0) error("Invalid unreachable instruction!");
- Result = new UnreachableInst();
- break;
- } // end switch(Opcode)
- } // end if !Result
-
- BB->getInstList().push_back(Result);
-
- unsigned TypeSlot;
- if (Result->getType() == InstTy)
- TypeSlot = iType;
- else
- TypeSlot = getTypeSlot(Result->getType());
-
- // We have enough info to inform the handler now.
- if (Handler)
- Handler->handleInstruction(Opcode, InstTy, &Oprnds[0], Oprnds.size(),
- Result, At-SaveAt);
-
- insertValue(Result, TypeSlot, FunctionValues);
-}
-
-/// Get a particular numbered basic block, which might be a forward reference.
-/// This works together with ParseInstructionList to handle these forward
-/// references in a clean manner. This function is used when constructing
-/// phi, br, switch, and other instructions that reference basic blocks.
-/// Blocks are numbered sequentially as they appear in the function.
-BasicBlock *BytecodeReader::getBasicBlock(unsigned ID) {
- // Make sure there is room in the table...
- if (ParsedBasicBlocks.size() <= ID) ParsedBasicBlocks.resize(ID+1);
-
- // First check to see if this is a backwards reference, i.e. this block
- // has already been created, or if the forward reference has already
- // been created.
- if (ParsedBasicBlocks[ID])
- return ParsedBasicBlocks[ID];
-
- // Otherwise, the basic block has not yet been created. Do so and add it to
- // the ParsedBasicBlocks list.
- return ParsedBasicBlocks[ID] = new BasicBlock();
-}
-
-/// 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 order to avoid per-basic-block overhead.
-/// @returns the number of basic blocks encountered.
-unsigned BytecodeReader::ParseInstructionList(Function* F) {
- unsigned BlockNo = 0;
- SmallVector<unsigned, 8> Args;
-
- while (moreInBlock()) {
- if (Handler) Handler->handleBasicBlockBegin(BlockNo);
- BasicBlock *BB;
- if (ParsedBasicBlocks.size() == BlockNo)
- ParsedBasicBlocks.push_back(BB = new BasicBlock());
- else if (ParsedBasicBlocks[BlockNo] == 0)
- BB = ParsedBasicBlocks[BlockNo] = new BasicBlock();
- else
- BB = ParsedBasicBlocks[BlockNo];
- ++BlockNo;
- F->getBasicBlockList().push_back(BB);
-
- // Read instructions into this basic block until we get to a terminator
- while (moreInBlock() && !BB->getTerminator())
- ParseInstruction(Args, BB);
-
- if (!BB->getTerminator())
- error("Non-terminated basic block found!");
-
- if (Handler) Handler->handleBasicBlockEnd(BlockNo-1);
- }
-
- return BlockNo;
-}
-
-/// Parse a type symbol table.
-void BytecodeReader::ParseTypeSymbolTable(TypeSymbolTable *TST) {
- // Type Symtab block header: [num entries]
- unsigned NumEntries = read_vbr_uint();
- for (unsigned i = 0; i < NumEntries; ++i) {
- // Symtab entry: [type slot #][name]
- unsigned slot = read_vbr_uint();
- std::string Name = read_str();
- const Type* T = getType(slot);
- TST->insert(Name, T);
- }
-}
-
-/// Parse a value symbol table. This works for both module level and function
-/// level symbol tables. For function level symbol tables, the CurrentFunction
-/// parameter must be non-zero and the ST parameter must correspond to
-/// CurrentFunction's symbol table. For Module level symbol tables, the
-/// CurrentFunction argument must be zero.
-void BytecodeReader::ParseValueSymbolTable(Function *CurrentFunction,
- ValueSymbolTable *VST) {
-
- if (Handler) Handler->handleValueSymbolTableBegin(CurrentFunction,VST);
-
- // Allow efficient basic block lookup by number.
- SmallVector<BasicBlock*, 32> BBMap;
- if (CurrentFunction)
- for (Function::iterator I = CurrentFunction->begin(),
- E = CurrentFunction->end(); I != E; ++I)
- BBMap.push_back(I);
-
- SmallVector<char, 32> NameStr;
-
- while (moreInBlock()) {
- // Symtab block header: [num entries][type id number]
- unsigned NumEntries = read_vbr_uint();
- unsigned Typ = read_vbr_uint();
-
- for (unsigned i = 0; i != NumEntries; ++i) {
- // Symtab entry: [def slot #][name]
- unsigned slot = read_vbr_uint();
- read_str(NameStr);
- Value *V = 0;
- if (Typ == LabelTySlot) {
- V = (slot < BBMap.size()) ? BBMap[slot] : 0;
- } else {
- V = getValue(Typ, slot, false); // Find mapping.
- }
- if (Handler) Handler->handleSymbolTableValue(Typ, slot,
- &NameStr[0], NameStr.size());
- if (V == 0)
- error("Failed value look-up for name '" +
- std::string(NameStr.begin(), NameStr.end()) + "', type #" +
- utostr(Typ) + " slot #" + utostr(slot));
- V->setName(&NameStr[0], NameStr.size());
-
- NameStr.clear();
- }
- }
- checkPastBlockEnd("Symbol Table");
- if (Handler) Handler->handleValueSymbolTableEnd();
-}
-
-// 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
-// a derived type, then additional data is read to fill out the type
-// definition.
-const Type *BytecodeReader::ParseType() {
- unsigned PrimType = read_vbr_uint();
- const Type *Result = 0;
- if ((Result = Type::getPrimitiveType((Type::TypeID)PrimType)))
- return Result;
-
- switch (PrimType) {
- case Type::IntegerTyID: {
- unsigned NumBits = read_vbr_uint();
- Result = IntegerType::get(NumBits);
- break;
- }
- case Type::FunctionTyID: {
- const Type *RetType = readType();
- unsigned NumParams = read_vbr_uint();
-
- std::vector<const Type*> Params;
- while (NumParams--) {
- Params.push_back(readType());
- }
-
- bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
- if (isVarArg)
- Params.pop_back();
-
- ParamAttrsList *Attrs = ParseParamAttrsList();
-
- Result = FunctionType::get(RetType, Params, isVarArg, Attrs);
- break;
- }
- case Type::ArrayTyID: {
- const Type *ElementType = readType();
- unsigned NumElements = read_vbr_uint();
- Result = ArrayType::get(ElementType, NumElements);
- break;
- }
- case Type::VectorTyID: {
- const Type *ElementType = readType();
- unsigned NumElements = read_vbr_uint();
- Result = VectorType::get(ElementType, NumElements);
- break;
- }
- case Type::StructTyID: {
- std::vector<const Type*> Elements;
- unsigned Typ = read_vbr_uint();
- while (Typ) { // List is terminated by void/0 typeid
- Elements.push_back(getType(Typ));
- Typ = read_vbr_uint();
- }
-
- Result = StructType::get(Elements, false);
- break;
- }
- case Type::PackedStructTyID: {
- std::vector<const Type*> Elements;
- unsigned Typ = read_vbr_uint();
- while (Typ) { // List is terminated by void/0 typeid
- Elements.push_back(getType(Typ));
- Typ = read_vbr_uint();
- }
-
- Result = StructType::get(Elements, true);
- break;
- }
- case Type::PointerTyID: {
- Result = PointerType::get(readType());
- break;
- }
-
- case Type::OpaqueTyID: {
- Result = OpaqueType::get();
- break;
- }
-
- default:
- error("Don't know how to deserialize primitive type " + utostr(PrimType));
- break;
- }
- if (Handler) Handler->handleType(Result);
- return Result;
-}
-
-ParamAttrsList *BytecodeReader::ParseParamAttrsList() {
- unsigned NumAttrs = read_vbr_uint();
- ParamAttrsList *PAL = 0;
- if (NumAttrs) {
- ParamAttrsVector Attrs;
- ParamAttrsWithIndex PAWI;
- while (NumAttrs--) {
- PAWI.index = read_vbr_uint();
- PAWI.attrs = read_vbr_uint();
- Attrs.push_back(PAWI);
- }
- PAL = ParamAttrsList::get(Attrs);
- }
- return PAL;
-}
-
-
-// ParseTypes - We have to use this weird code to handle recursive
-// types. We know that recursive types will only reference the current slab of
-// values in the type plane, but they can forward reference types before they
-// have been read. For example, Type #0 might be '{ Ty#1 }' and Type #1 might
-// be 'Ty#0*'. When reading Type #0, type number one doesn't exist. To fix
-// this ugly problem, we pessimistically insert an opaque type for each type we
-// are about to read. This means that forward references will resolve to
-// something and when we reread the type later, we can replace the opaque type
-// with a new resolved concrete type.
-//
-void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
- assert(Tab.size() == 0 && "should not have read type constants in before!");
-
- // Insert a bunch of opaque types to be resolved later...
- Tab.reserve(NumEntries);
- for (unsigned i = 0; i != NumEntries; ++i)
- Tab.push_back(OpaqueType::get());
-
- if (Handler)
- Handler->handleTypeList(NumEntries);
-
- // If we are about to resolve types, make sure the type cache is clear.
- if (NumEntries)
- ModuleTypeIDCache.clear();
-
- // Loop through reading all of the types. Forward types will make use of the
- // opaque types just inserted.
- //
- for (unsigned i = 0; i != NumEntries; ++i) {
- const Type* NewTy = ParseType();
- const Type* OldTy = Tab[i].get();
- if (NewTy == 0)
- error("Couldn't parse type!");
-
- // 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
- // approach helps with forward references to types. The refinement from the
- // abstract (opaque) type to the new type causes all uses of the abstract
- // type to use the concrete type (NewTy). This will also cause the opaque
- // type to be deleted.
- cast<DerivedType>(const_cast<Type*>(OldTy))->refineAbstractTypeTo(NewTy);
-
- // This should have replaced the old opaque type with the new type in the
- // value table... or with a preexisting type that was already in the system.
- // Let's just make sure it did.
- assert(Tab[i] != OldTy && "refineAbstractType didn't work!");
- }
-}
-
-/// Parse a single constant value
-Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
- // We must check for a ConstantExpr before switching by type because
- // a ConstantExpr can be of any type, and has no explicit value.
- //
- // 0 if not expr; numArgs if is expr
- unsigned isExprNumArgs = read_vbr_uint();
-
- if (isExprNumArgs) {
- // 'undef' is encoded with 'exprnumargs' == 1.
- if (isExprNumArgs == 1)
- return UndefValue::get(getType(TypeID));
-
- // Inline asm is encoded with exprnumargs == ~0U.
- if (isExprNumArgs == ~0U) {
- std::string AsmStr = read_str();
- std::string ConstraintStr = read_str();
- unsigned Flags = read_vbr_uint();
-
- const PointerType *PTy = dyn_cast<PointerType>(getType(TypeID));
- const FunctionType *FTy =
- PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
-
- if (!FTy || !InlineAsm::Verify(FTy, ConstraintStr))
- error("Invalid constraints for inline asm");
- if (Flags & ~1U)
- error("Invalid flags for inline asm");
- bool HasSideEffects = Flags & 1;
- return InlineAsm::get(FTy, AsmStr, ConstraintStr, HasSideEffects);
- }
-
- --isExprNumArgs;
-
- // FIXME: Encoding of constant exprs could be much more compact!
- SmallVector<Constant*, 8> ArgVec;
- ArgVec.reserve(isExprNumArgs);
- unsigned Opcode = read_vbr_uint();
-
- // Read the slot number and types of each of the arguments
- for (unsigned i = 0; i != isExprNumArgs; ++i) {
- unsigned ArgValSlot = read_vbr_uint();
- unsigned ArgTypeSlot = read_vbr_uint();
-
- // Get the arg value from its slot if it exists, otherwise a placeholder
- ArgVec.push_back(getConstantValue(ArgTypeSlot, ArgValSlot));
- }
-
- // Construct a ConstantExpr of the appropriate kind
- if (isExprNumArgs == 1) { // All one-operand expressions
- if (!Instruction::isCast(Opcode))
- error("Only cast instruction has one argument for ConstantExpr");
-
- Constant *Result = ConstantExpr::getCast(Opcode, ArgVec[0],
- getType(TypeID));
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr
- Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], &ArgVec[1],
- ArgVec.size()-1);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::Select) {
- if (ArgVec.size() != 3)
- error("Select instruction must have three arguments.");
- Constant* Result = ConstantExpr::getSelect(ArgVec[0], ArgVec[1],
- ArgVec[2]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::ExtractElement) {
- if (ArgVec.size() != 2 ||
- !ExtractElementInst::isValidOperands(ArgVec[0], ArgVec[1]))
- error("Invalid extractelement constand expr arguments");
- Constant* Result = ConstantExpr::getExtractElement(ArgVec[0], ArgVec[1]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::InsertElement) {
- if (ArgVec.size() != 3 ||
- !InsertElementInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
- error("Invalid insertelement constand expr arguments");
-
- Constant *Result =
- ConstantExpr::getInsertElement(ArgVec[0], ArgVec[1], ArgVec[2]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::ShuffleVector) {
- if (ArgVec.size() != 3 ||
- !ShuffleVectorInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
- error("Invalid shufflevector constant expr arguments.");
- Constant *Result =
- ConstantExpr::getShuffleVector(ArgVec[0], ArgVec[1], ArgVec[2]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::ICmp) {
- if (ArgVec.size() != 2)
- error("Invalid ICmp constant expr arguments.");
- unsigned predicate = read_vbr_uint();
- Constant *Result = ConstantExpr::getICmp(predicate, ArgVec[0], ArgVec[1]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else if (Opcode == Instruction::FCmp) {
- if (ArgVec.size() != 2)
- error("Invalid FCmp constant expr arguments.");
- unsigned predicate = read_vbr_uint();
- Constant *Result = ConstantExpr::getFCmp(predicate, ArgVec[0], ArgVec[1]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- } else { // All other 2-operand expressions
- Constant* Result = ConstantExpr::get(Opcode, ArgVec[0], ArgVec[1]);
- if (Handler) Handler->handleConstantExpression(Opcode, &ArgVec[0],
- ArgVec.size(), Result);
- return Result;
- }
- }
-
- // Ok, not an ConstantExpr. We now know how to read the given type...
- const Type *Ty = getType(TypeID);
- Constant *Result = 0;
- switch (Ty->getTypeID()) {
- case Type::IntegerTyID: {
- const IntegerType *IT = cast<IntegerType>(Ty);
- if (IT->getBitWidth() <= 32) {
- uint32_t Val = read_vbr_uint();
- if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
- error("Integer value read is invalid for type.");
- Result = ConstantInt::get(IT, Val);
- if (Handler) Handler->handleConstantValue(Result);
- } else if (IT->getBitWidth() <= 64) {
- uint64_t Val = read_vbr_uint64();
- if (!ConstantInt::isValueValidForType(Ty, Val))
- error("Invalid constant integer read.");
- Result = ConstantInt::get(IT, Val);
- if (Handler) Handler->handleConstantValue(Result);
- } else {
- uint32_t NumWords = read_vbr_uint();
- SmallVector<uint64_t, 8> Words;
- Words.resize(NumWords);
- for (uint32_t i = 0; i < NumWords; ++i)
- Words[i] = read_vbr_uint64();
- Result = ConstantInt::get(APInt(IT->getBitWidth(), NumWords, &Words[0]));
- if (Handler) Handler->handleConstantValue(Result);
- }
- break;
- }
- case Type::FloatTyID: {
- float Val;
- read_float(Val);
- Result = ConstantFP::get(Ty, Val);
- if (Handler) Handler->handleConstantValue(Result);
- break;
- }
-
- case Type::DoubleTyID: {
- double Val;
- read_double(Val);
- Result = ConstantFP::get(Ty, Val);
- if (Handler) Handler->handleConstantValue(Result);
- break;
- }
-
- case Type::ArrayTyID: {
- const ArrayType *AT = cast<ArrayType>(Ty);
- unsigned NumElements = AT->getNumElements();
- unsigned TypeSlot = getTypeSlot(AT->getElementType());
- std::vector<Constant*> Elements;
- Elements.reserve(NumElements);
- while (NumElements--) // Read all of the elements of the constant.
- Elements.push_back(getConstantValue(TypeSlot,
- read_vbr_uint()));
- Result = ConstantArray::get(AT, Elements);
- if (Handler) Handler->handleConstantArray(AT, &Elements[0], Elements.size(),
- TypeSlot, Result);
- break;
- }
-
- case Type::StructTyID: {
- const StructType *ST = cast<StructType>(Ty);
-
- std::vector<Constant *> Elements;
- Elements.reserve(ST->getNumElements());
- for (unsigned i = 0; i != ST->getNumElements(); ++i)
- Elements.push_back(getConstantValue(ST->getElementType(i),
- read_vbr_uint()));
-
- Result = ConstantStruct::get(ST, Elements);
- if (Handler) Handler->handleConstantStruct(ST, &Elements[0],Elements.size(),
- Result);
- break;
- }
-
- case Type::VectorTyID: {
- const VectorType *PT = cast<VectorType>(Ty);
- unsigned NumElements = PT->getNumElements();
- unsigned TypeSlot = getTypeSlot(PT->getElementType());
- std::vector<Constant*> Elements;
- Elements.reserve(NumElements);
- while (NumElements--) // Read all of the elements of the constant.
- Elements.push_back(getConstantValue(TypeSlot,
- read_vbr_uint()));
- Result = ConstantVector::get(PT, Elements);
- if (Handler) Handler->handleConstantVector(PT, &Elements[0],Elements.size(),
- TypeSlot, Result);
- break;
- }
-
- case Type::PointerTyID: { // ConstantPointerRef value (backwards compat).
- const PointerType *PT = cast<PointerType>(Ty);
- unsigned Slot = read_vbr_uint();
-
- // Check to see if we have already read this global variable...
- Value *Val = getValue(TypeID, Slot, false);
- if (Val) {
- GlobalValue *GV = dyn_cast<GlobalValue>(Val);
- if (!GV) error("GlobalValue not in ValueTable!");
- if (Handler) Handler->handleConstantPointer(PT, Slot, GV);
- return GV;
- } else {
- error("Forward references are not allowed here.");
- }
- }
-
- default:
- error("Don't know how to deserialize constant value of type '" +
- Ty->getDescription());
- break;
- }
-
- // Check that we didn't read a null constant if they are implicit for this
- // type plane. Do not do this check for constantexprs, as they may be folded
- // to a null value in a way that isn't predicted when a .bc file is initially
- // produced.
- assert((!isa<Constant>(Result) || !cast<Constant>(Result)->isNullValue()) ||
- !hasImplicitNull(TypeID) && "Cannot read null values from bytecode!");
- return Result;
-}
-
-/// Resolve references for constants. This function resolves the forward
-/// referenced constants in the ConstantFwdRefs map. It uses the
-/// replaceAllUsesWith method of Value class to substitute the placeholder
-/// instance with the actual instance.
-void BytecodeReader::ResolveReferencesToConstant(Constant *NewV, unsigned Typ,
- unsigned Slot) {
- ConstantRefsType::iterator I =
- ConstantFwdRefs.find(std::make_pair(Typ, Slot));
- if (I == ConstantFwdRefs.end()) return; // Never forward referenced?
-
- Value *PH = I->second; // Get the placeholder...
- PH->replaceAllUsesWith(NewV);
- delete PH; // Delete the old placeholder
- ConstantFwdRefs.erase(I); // Remove the map entry for it
-}
-
-/// Parse the constant strings section.
-void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
- for (; NumEntries; --NumEntries) {
- unsigned Typ = read_vbr_uint();
- const Type *Ty = getType(Typ);
- if (!isa<ArrayType>(Ty))
- error("String constant data invalid!");
-
- const ArrayType *ATy = cast<ArrayType>(Ty);
- if (ATy->getElementType() != Type::Int8Ty &&
- ATy->getElementType() != Type::Int8Ty)
- error("String constant data invalid!");
-
- // Read character data. The type tells us how long the string is.
- char *Data = reinterpret_cast<char *>(alloca(ATy->getNumElements()));
- read_data(Data, Data+ATy->getNumElements());
-
- std::vector<Constant*> Elements(ATy->getNumElements());
- const Type* ElemType = ATy->getElementType();
- for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
- Elements[i] = ConstantInt::get(ElemType, (unsigned char)Data[i]);
-
- // Create the constant, inserting it as needed.
- Constant *C = ConstantArray::get(ATy, Elements);
- unsigned Slot = insertValue(C, Typ, Tab);
- ResolveReferencesToConstant(C, Typ, Slot);
- if (Handler) Handler->handleConstantString(cast<ConstantArray>(C));
- }
-}
-
-/// Parse the constant pool.
-void BytecodeReader::ParseConstantPool(ValueTable &Tab,
- TypeListTy &TypeTab,
- bool isFunction) {
- if (Handler) Handler->handleGlobalConstantsBegin();
-
- /// In LLVM 1.3 Type does not derive from Value so the types
- /// do not occupy a plane. Consequently, we read the types
- /// first in the constant pool.
- if (isFunction) {
- unsigned NumEntries = read_vbr_uint();
- ParseTypes(TypeTab, NumEntries);
- }
-
- while (moreInBlock()) {
- unsigned NumEntries = read_vbr_uint();
- unsigned Typ = read_vbr_uint();
-
- if (Typ == Type::VoidTyID) {
- /// Use of Type::VoidTyID is a misnomer. It actually means
- /// that the following plane is constant strings
- assert(&Tab == &ModuleValues && "Cannot read strings in functions!");
- ParseStringConstants(NumEntries, Tab);
- } else {
- for (unsigned i = 0; i < NumEntries; ++i) {
- Value *V = ParseConstantPoolValue(Typ);
- assert(V && "ParseConstantPoolValue returned NULL!");
- unsigned Slot = insertValue(V, Typ, Tab);
-
- // If we are reading a function constant table, make sure that we adjust
- // the slot number to be the real global constant number.
- //
- if (&Tab != &ModuleValues && Typ < ModuleValues.size() &&
- ModuleValues[Typ])
- Slot += ModuleValues[Typ]->size();
- if (Constant *C = dyn_cast<Constant>(V))
- ResolveReferencesToConstant(C, Typ, Slot);
- }
- }
- }
-
- // After we have finished parsing the constant pool, we had better not have
- // any dangling references left.
- if (!ConstantFwdRefs.empty()) {
- ConstantRefsType::const_iterator I = ConstantFwdRefs.begin();
- Constant* missingConst = I->second;
- error(utostr(ConstantFwdRefs.size()) +
- " unresolved constant reference exist. First one is '" +
- missingConst->getName() + "' of type '" +
- missingConst->getType()->getDescription() + "'.");
- }
-
- checkPastBlockEnd("Constant Pool");
- if (Handler) Handler->handleGlobalConstantsEnd();
-}
-
-/// Parse the contents of a function. Note that this function can be
-/// called lazily by materializeFunction
-/// @see materializeFunction
-void BytecodeReader::ParseFunctionBody(Function* F) {
-
- unsigned FuncSize = BlockEnd - At;
- GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
- GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
-
- unsigned rWord = read_vbr_uint();
- unsigned LinkageID = rWord & 65535;
- unsigned VisibilityID = rWord >> 16;
- switch (LinkageID) {
- case 0: Linkage = GlobalValue::ExternalLinkage; break;
- case 1: Linkage = GlobalValue::WeakLinkage; break;
- case 2: Linkage = GlobalValue::AppendingLinkage; break;
- case 3: Linkage = GlobalValue::InternalLinkage; break;
- case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
- case 5: Linkage = GlobalValue::DLLImportLinkage; break;
- case 6: Linkage = GlobalValue::DLLExportLinkage; break;
- case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
- default:
- error("Invalid linkage type for Function.");
- Linkage = GlobalValue::InternalLinkage;
- break;
- }
- switch (VisibilityID) {
- case 0: Visibility = GlobalValue::DefaultVisibility; break;
- case 1: Visibility = GlobalValue::HiddenVisibility; break;
- case 2: Visibility = GlobalValue::ProtectedVisibility; break;
- default:
- error("Unknown visibility type: " + utostr(VisibilityID));
- Visibility = GlobalValue::DefaultVisibility;
- break;
- }
-
- F->setLinkage(Linkage);
- F->setVisibility(Visibility);
- if (Handler) Handler->handleFunctionBegin(F,FuncSize);
-
- // Keep track of how many basic blocks we have read in...
- unsigned BlockNum = 0;
- bool InsertedArguments = false;
-
- BufPtr MyEnd = BlockEnd;
- while (At < MyEnd) {
- unsigned Type, Size;
- BufPtr OldAt = At;
- read_block(Type, Size);
-
- switch (Type) {
- case BytecodeFormat::ConstantPoolBlockID:
- if (!InsertedArguments) {
- // Insert arguments into the value table before we parse the first basic
- // block in the function
- insertArguments(F);
- InsertedArguments = true;
- }
-
- ParseConstantPool(FunctionValues, FunctionTypes, true);
- break;
-
- case BytecodeFormat::InstructionListBlockID: {
- // Insert arguments into the value table before we parse the instruction
- // list for the function
- if (!InsertedArguments) {
- insertArguments(F);
- InsertedArguments = true;
- }
-
- if (BlockNum)
- error("Already parsed basic blocks!");
- BlockNum = ParseInstructionList(F);
- break;
- }
-
- case BytecodeFormat::ValueSymbolTableBlockID:
- ParseValueSymbolTable(F, &F->getValueSymbolTable());
- break;
-
- case BytecodeFormat::TypeSymbolTableBlockID:
- error("Functions don't have type symbol tables");
- break;
-
- default:
- At += Size;
- if (OldAt > At)
- error("Wrapped around reading bytecode.");
- break;
- }
- BlockEnd = MyEnd;
- }
-
- // Make sure there were no references to non-existant basic blocks.
- if (BlockNum != ParsedBasicBlocks.size())
- error("Illegal basic block operand reference");
-
- ParsedBasicBlocks.clear();
-
- // Resolve forward references. Replace any uses of a forward reference value
- // with the real value.
- while (!ForwardReferences.empty()) {
- std::map<std::pair<unsigned,unsigned>, Value*>::iterator
- I = ForwardReferences.begin();
- Value *V = getValue(I->first.first, I->first.second, false);
- Value *PlaceHolder = I->second;
- PlaceHolder->replaceAllUsesWith(V);
- ForwardReferences.erase(I);
- delete PlaceHolder;
- }
-
- // Clear out function-level types...
- FunctionTypes.clear();
- freeTable(FunctionValues);
-
- if (Handler) Handler->handleFunctionEnd(F);
-}
-
-/// This function parses LLVM functions lazily. It obtains the type of the
-/// function and records where the body of the function is in the bytecode
-/// buffer. The caller can then use the ParseNextFunction and
-/// ParseAllFunctionBodies to get handler events for the functions.
-void BytecodeReader::ParseFunctionLazily() {
- if (FunctionSignatureList.empty())
- error("FunctionSignatureList empty!");
-
- Function *Func = FunctionSignatureList.back();
- FunctionSignatureList.pop_back();
-
- // Save the information for future reading of the function
- LazyFunctionLoadMap[Func] = LazyFunctionInfo(BlockStart, BlockEnd);
-
- // This function has a body but it's not loaded so it appears `External'.
- // Mark it as a `Ghost' instead to notify the users that it has a body.
- Func->setLinkage(GlobalValue::GhostLinkage);
-
- // Pretend we've `parsed' this function
- At = BlockEnd;
-}
-
-/// The ParserFunction method lazily parses one function. Use this method to
-/// 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
-/// ParseAllFunctionBodies.
-/// @see ParseAllFunctionBodies
-/// @see ParseBytecode
-bool BytecodeReader::ParseFunction(Function* Func, std::string* ErrMsg) {
-
- if (setjmp(context)) {
- // Set caller's error message, if requested
- if (ErrMsg)
- *ErrMsg = ErrorMsg;
- // Indicate an error occurred
- return true;
- }
-
- // Find {start, end} pointers and slot in the map. If not there, we're done.
- LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(Func);
-
- // Make sure we found it
- if (Fi == LazyFunctionLoadMap.end()) {
- error("Unrecognized function of type " + Func->getType()->getDescription());
- return true;
- }
-
- BlockStart = At = Fi->second.Buf;
- BlockEnd = Fi->second.EndBuf;
- assert(Fi->first == Func && "Found wrong function?");
-
- this->ParseFunctionBody(Func);
- return false;
-}
-
-/// The ParseAllFunctionBodies method parses through all the previously
-/// unparsed functions in the bytecode file. If you want to completely parse
-/// a bytecode file, this method should be called after Parsebytecode because
-/// Parsebytecode only records the locations in the bytecode file of where
-/// the function definitions are located. This function uses that information
-/// to materialize the functions.
-/// @see ParseBytecode
-bool BytecodeReader::ParseAllFunctionBodies(std::string* ErrMsg) {
- if (setjmp(context)) {
- // Set caller's error message, if requested
- if (ErrMsg)
- *ErrMsg = ErrorMsg;
- // Indicate an error occurred
- return true;
- }
-
- for (LazyFunctionMap::iterator I = LazyFunctionLoadMap.begin(),
- E = LazyFunctionLoadMap.end(); I != E; ++I) {
- Function *Func = I->first;
- if (Func->hasNotBeenReadFromBytecode()) {
- BlockStart = At = I->second.Buf;
- BlockEnd = I->second.EndBuf;
- ParseFunctionBody(Func);
- }
- }
- return false;
-}
-
-/// Parse the global type list
-void BytecodeReader::ParseGlobalTypes() {
- // Read the number of types
- unsigned NumEntries = read_vbr_uint();
- ParseTypes(ModuleTypes, NumEntries);
-}
-
-/// Parse the Global info (types, global vars, constants)
-void BytecodeReader::ParseModuleGlobalInfo() {
-
- if (Handler) Handler->handleModuleGlobalsBegin();
-
- // SectionID - If a global has an explicit section specified, this map
- // remembers the ID until we can translate it into a string.
- std::map<GlobalValue*, unsigned> SectionID;
-
- // Read global variables...
- unsigned VarType = read_vbr_uint();
- while (VarType != Type::VoidTyID) { // List is terminated by Void
- // VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 =
- // Linkage, bit5 = isThreadLocal, bit6+ = slot#
- unsigned SlotNo = VarType >> 6;
- unsigned LinkageID = (VarType >> 2) & 7;
- unsigned VisibilityID = 0;
- bool isConstant = VarType & 1;
- bool isThreadLocal = (VarType >> 5) & 1;
- bool hasInitializer = (VarType & 2) != 0;
- unsigned Alignment = 0;
- unsigned GlobalSectionID = 0;
-
- // An extension word is present when linkage = 3 (internal) and hasinit = 0.
- if (LinkageID == 3 && !hasInitializer) {
- unsigned ExtWord = read_vbr_uint();
- // The extension word has this format: bit 0 = has initializer, bit 1-3 =
- // linkage, bit 4-8 = alignment (log2), bit 9 = has section,
- // bits 10-12 = visibility, bits 13+ = future use.
- hasInitializer = ExtWord & 1;
- LinkageID = (ExtWord >> 1) & 7;
- Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1;
- VisibilityID = (ExtWord >> 10) & 7;
-
- if (ExtWord & (1 << 9)) // Has a section ID.
- GlobalSectionID = read_vbr_uint();
- }
-
- GlobalValue::LinkageTypes Linkage;
- switch (LinkageID) {
- case 0: Linkage = GlobalValue::ExternalLinkage; break;
- case 1: Linkage = GlobalValue::WeakLinkage; break;
- case 2: Linkage = GlobalValue::AppendingLinkage; break;
- case 3: Linkage = GlobalValue::InternalLinkage; break;
- case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
- case 5: Linkage = GlobalValue::DLLImportLinkage; break;
- case 6: Linkage = GlobalValue::DLLExportLinkage; break;
- case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
- default:
- error("Unknown linkage type: " + utostr(LinkageID));
- Linkage = GlobalValue::InternalLinkage;
- break;
- }
- GlobalValue::VisibilityTypes Visibility;
- switch (VisibilityID) {
- case 0: Visibility = GlobalValue::DefaultVisibility; break;
- case 1: Visibility = GlobalValue::HiddenVisibility; break;
- case 2: Visibility = GlobalValue::ProtectedVisibility; break;
- default:
- error("Unknown visibility type: " + utostr(VisibilityID));
- Visibility = GlobalValue::DefaultVisibility;
- break;
- }
-
- const Type *Ty = getType(SlotNo);
- if (!Ty)
- error("Global has no type! SlotNo=" + utostr(SlotNo));
-
- if (!isa<PointerType>(Ty))
- error("Global not a pointer type! Ty= " + Ty->getDescription());
-
- const Type *ElTy = cast<PointerType>(Ty)->getElementType();
-
- // Create the global variable...
- GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
- 0, "", TheModule, isThreadLocal);
- GV->setAlignment(Alignment);
- GV->setVisibility(Visibility);
- insertValue(GV, SlotNo, ModuleValues);
-
- if (GlobalSectionID != 0)
- SectionID[GV] = GlobalSectionID;
-
- unsigned initSlot = 0;
- if (hasInitializer) {
- initSlot = read_vbr_uint();
- GlobalInits.push_back(std::make_pair(GV, initSlot));
- }
-
- // Notify handler about the global value.
- if (Handler)
- Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
- SlotNo, initSlot, isThreadLocal);
-
- // Get next item
- VarType = read_vbr_uint();
- }
-
- // Read the function objects for all of the functions that are coming
- unsigned FnSignature = read_vbr_uint();
-
- // List is terminated by VoidTy.
- while (((FnSignature & (~0U >> 1)) >> 5) != Type::VoidTyID) {
- const Type *Ty = getType((FnSignature & (~0U >> 1)) >> 5);
- if (!isa<PointerType>(Ty) ||
- !isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
- error("Function not a pointer to function type! Ty = " +
- Ty->getDescription());
- }
-
- // We create functions by passing the underlying FunctionType to create...
- const FunctionType* FTy =
- cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
-
- // Insert the place holder.
- Function *Func = new Function(FTy, GlobalValue::ExternalLinkage,
- "", TheModule);
-
- insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues);
-
- // Flags are not used yet.
- unsigned Flags = FnSignature & 31;
-
- // Save this for later so we know type of lazily instantiated functions.
- // Note that known-external functions do not have FunctionInfo blocks, so we
- // do not add them to the FunctionSignatureList.
- if ((Flags & (1 << 4)) == 0)
- FunctionSignatureList.push_back(Func);
-
- // Get the calling convention from the low bits.
- unsigned CC = Flags & 15;
- unsigned Alignment = 0;
- if (FnSignature & (1 << 31)) { // Has extension word?
- unsigned ExtWord = read_vbr_uint();
- Alignment = (1 << (ExtWord & 31)) >> 1;
- CC |= ((ExtWord >> 5) & 15) << 4;
-
- if (ExtWord & (1 << 10)) // Has a section ID.
- SectionID[Func] = read_vbr_uint();
-
- // Parse external declaration linkage
- switch ((ExtWord >> 11) & 3) {
- case 0: break;
- case 1: Func->setLinkage(Function::DLLImportLinkage); break;
- case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;
- default: assert(0 && "Unsupported external linkage");
- }
- }
-
- Func->setCallingConv(CC-1);
- Func->setAlignment(Alignment);
-
- if (Handler) Handler->handleFunctionDeclaration(Func);
-
- // Get the next function signature.
- FnSignature = read_vbr_uint();
- }
-
- // Now that the function signature list is set up, reverse it so that we can
- // remove elements efficiently from the back of the vector.
- std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
-
- /// SectionNames - This contains the list of section names encoded in the
- /// moduleinfoblock. Functions and globals with an explicit section index
- /// into this to get their section name.
- std::vector<std::string> SectionNames;
-
- // Read in the dependent library information.
- unsigned num_dep_libs = read_vbr_uint();
- std::string dep_lib;
- while (num_dep_libs--) {
- dep_lib = read_str();
- TheModule->addLibrary(dep_lib);
- if (Handler)
- Handler->handleDependentLibrary(dep_lib);
- }
-
- // Read target triple and place into the module.
- std::string triple = read_str();
- TheModule->setTargetTriple(triple);
- if (Handler)
- Handler->handleTargetTriple(triple);
-
- // Read the data layout string and place into the module.
- std::string datalayout = read_str();
- TheModule->setDataLayout(datalayout);
- // FIXME: Implement
- // if (Handler)
- // Handler->handleDataLayout(datalayout);
-
- if (At != BlockEnd) {
- // If the file has section info in it, read the section names now.
- unsigned NumSections = read_vbr_uint();
- while (NumSections--)
- SectionNames.push_back(read_str());
- }
-
- // If the file has module-level inline asm, read it now.
- if (At != BlockEnd)
- TheModule->setModuleInlineAsm(read_str());
-
- // If any globals are in specified sections, assign them now.
- for (std::map<GlobalValue*, unsigned>::iterator I = SectionID.begin(), E =
- SectionID.end(); I != E; ++I)
- if (I->second) {
- if (I->second > SectionID.size())
- error("SectionID out of range for global!");
- I->first->setSection(SectionNames[I->second-1]);
- }
-
- if (At != BlockEnd) {
- // Read aliases...
- unsigned VarType = read_vbr_uint();
- while (VarType != Type::VoidTyID) { // List is terminated by Void
- unsigned TypeSlotNo = VarType >> 3;
- unsigned EncodedLinkage = VarType & 3;
- bool isConstantAliasee = (VarType >> 2) & 1;
- unsigned AliaseeSlotNo = read_vbr_uint();
-
- const Type *Ty = getType(TypeSlotNo);
- if (!Ty)
- error("Alias has no type! SlotNo=" + utostr(TypeSlotNo));
-
- if (!isa<PointerType>(Ty))
- error("Alias not a pointer type! Ty= " + Ty->getDescription());
-
- Value* V = getValue(TypeSlotNo, AliaseeSlotNo, false);
- if (!V && !isConstantAliasee)
- error("Invalid aliasee! TypeSlotNo=" + utostr(TypeSlotNo) +
- " SlotNo=" + utostr(AliaseeSlotNo));
- if (!isConstantAliasee && !isa<GlobalValue>(V))
- error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo));
-
- GlobalValue::LinkageTypes Linkage;
- switch (EncodedLinkage) {
- case 0:
- Linkage = GlobalValue::ExternalLinkage;
- break;
- case 1:
- Linkage = GlobalValue::InternalLinkage;
- break;
- case 2:
- Linkage = GlobalValue::WeakLinkage;
- break;
- default:
- assert(0 && "Unsupported encoded alias linkage");
- }
-
- GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "",
- dyn_cast_or_null<Constant>(V),
- TheModule);
- insertValue(GA, TypeSlotNo, ModuleValues);
- if (!V && isConstantAliasee)
- Aliasees.push_back(std::make_pair(GA, AliaseeSlotNo));
-
- if (Handler) Handler->handleGlobalAlias(Ty, Linkage,
- TypeSlotNo, AliaseeSlotNo);
- VarType = read_vbr_uint();
- }
- }
-
- // This is for future proofing... in the future extra fields may be added that
- // we don't understand, so we transparently ignore them.
- //
- At = BlockEnd;
-
- if (Handler) Handler->handleModuleGlobalsEnd();
-}
-
-/// Parse the version information and decode it by setting flags on the
-/// Reader that enable backward compatibility of the reader.
-void BytecodeReader::ParseVersionInfo() {
- unsigned RevisionNum = read_vbr_uint();
-
- // We don't provide backwards compatibility in the Reader any more. To
- // upgrade, the user should use llvm-upgrade.
- if (RevisionNum < 7)
- error("Bytecode formats < 7 are no longer supported. Use llvm-upgrade.");
-
- if (Handler) Handler->handleVersionInfo(RevisionNum);
-}
-
-/// Parse a whole module.
-void BytecodeReader::ParseModule() {
- unsigned Type, Size;
-
- FunctionSignatureList.clear(); // Just in case...
-
- // Read into instance variables...
- ParseVersionInfo();
-
- bool SeenModuleGlobalInfo = false;
- bool SeenGlobalTypePlane = false;
- BufPtr MyEnd = BlockEnd;
- while (At < MyEnd) {
- BufPtr OldAt = At;
- read_block(Type, Size);
-
- switch (Type) {
-
- case BytecodeFormat::GlobalTypePlaneBlockID:
- if (SeenGlobalTypePlane)
- error("Two GlobalTypePlane Blocks Encountered!");
-
- if (Size > 0)
- ParseGlobalTypes();
- SeenGlobalTypePlane = true;
- break;
-
- case BytecodeFormat::ModuleGlobalInfoBlockID:
- if (SeenModuleGlobalInfo)
- error("Two ModuleGlobalInfo Blocks Encountered!");
- ParseModuleGlobalInfo();
- SeenModuleGlobalInfo = true;
- break;
-
- case BytecodeFormat::ConstantPoolBlockID:
- ParseConstantPool(ModuleValues, ModuleTypes,false);
- break;
-
- case BytecodeFormat::FunctionBlockID:
- ParseFunctionLazily();
- break;
-
- case BytecodeFormat::ValueSymbolTableBlockID:
- ParseValueSymbolTable(0, &TheModule->getValueSymbolTable());
- break;
-
- case BytecodeFormat::TypeSymbolTableBlockID:
- ParseTypeSymbolTable(&TheModule->getTypeSymbolTable());
- break;
-
- default:
- At += Size;
- if (OldAt > At) {
- error("Unexpected Block of Type #" + utostr(Type) + " encountered!");
- }
- break;
- }
- BlockEnd = MyEnd;
- }
-
- // After the module constant pool has been read, we can safely initialize
- // global variables...
- while (!GlobalInits.empty()) {
- GlobalVariable *GV = GlobalInits.back().first;
- unsigned Slot = GlobalInits.back().second;
- GlobalInits.pop_back();
-
- // Look up the initializer value...
- // FIXME: Preserve this type ID!
-
- const llvm::PointerType* GVType = GV->getType();
- unsigned TypeSlot = getTypeSlot(GVType->getElementType());
- if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
- if (GV->hasInitializer())
- error("Global *already* has an initializer?!");
- if (Handler) Handler->handleGlobalInitializer(GV,CV);
- GV->setInitializer(CV);
- } else
- error("Cannot find initializer value.");
- }
-
- // And aliasees
- while (!Aliasees.empty()) {
- GlobalAlias *GA = Aliasees.back().first;
- unsigned Slot = Aliasees.back().second;
- Aliasees.pop_back();
-
- // Look up the aliasee value...
- const llvm::PointerType* GAType = GA->getType();
- unsigned TypeSlot = getTypeSlot(GAType);
- if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
- if (GA->getAliasee())
- error("Aliasee was *already* set?!");
- GA->setAliasee(CV);
- } else
- error("Cannot find aliasee value.");
- }
-
- if (!ConstantFwdRefs.empty())
- error("Use of undefined constants in a module");
-
- /// Make sure we pulled them all out. If we didn't then there's a declaration
- /// but a missing body. That's not allowed.
- if (!FunctionSignatureList.empty())
- error("Function declared, but bytecode stream ended before definition");
-}
-
-/// This function completely parses a bytecode buffer given by the \p Buf
-/// and \p Length parameters.
-bool BytecodeReader::ParseBytecode(volatile BufPtr Buf, unsigned Length,
- const std::string &ModuleID,
- BCDecompressor_t *Decompressor,
- std::string* ErrMsg) {
-
- /// We handle errors by
- if (setjmp(context)) {
- // Cleanup after error
- if (Handler) Handler->handleError(ErrorMsg);
- freeState();
- delete TheModule;
- TheModule = 0;
- if (decompressedBlock != 0 ) {
- ::free(decompressedBlock);
- decompressedBlock = 0;
- }
- // Set caller's error message, if requested
- if (ErrMsg)
- *ErrMsg = ErrorMsg;
- // Indicate an error occurred
- return true;
- }
-
- RevisionNum = 0;
- At = MemStart = BlockStart = Buf;
- MemEnd = BlockEnd = Buf + Length;
-
- // Create the module
- TheModule = new Module(ModuleID);
-
- if (Handler) Handler->handleStart(TheModule, Length);
-
- // Read the four bytes of the signature.
- unsigned Sig = read_uint();
-
- // If this is a compressed file
- if (Sig == ('l' | ('l' << 8) | ('v' << 16) | ('c' << 24))) {
- if (!Decompressor) {
- error("Compressed bytecode found, but not decompressor available");
- }
-
- // Invoke the decompression of the bytecode. Note that we have to skip the
- // file's magic number which is not part of the compressed block. Hence,
- // the Buf+4 and Length-4. The result goes into decompressedBlock, a data
- // member for retention until BytecodeReader is destructed.
- unsigned decompressedLength =
- Decompressor((char*)Buf+4,Length-4,decompressedBlock, 0);
-
- // We must adjust the buffer pointers used by the bytecode reader to point
- // into the new decompressed block. After decompression, the
- // decompressedBlock will point to a contiguous memory area that has
- // the decompressed data.
- At = MemStart = BlockStart = Buf = (BufPtr) decompressedBlock;
- MemEnd = BlockEnd = Buf + decompressedLength;
-
- // else if this isn't a regular (uncompressed) bytecode file, then its
- // and error, generate that now.
- } else if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) {
- error("Invalid bytecode signature: " + utohexstr(Sig));
- }
-
- // Tell the handler we're starting a module
- if (Handler) Handler->handleModuleBegin(ModuleID);
-
- // Get the module block and size and verify. This is handled specially
- // because the module block/size is always written in long format. Other
- // blocks are written in short format so the read_block method is used.
- unsigned Type, Size;
- Type = read_uint();
- Size = read_uint();
- if (Type != BytecodeFormat::ModuleBlockID) {
- error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
- + utostr(Size));
- }
-
- // It looks like the darwin ranlib program is broken, and adds trailing
- // garbage to the end of some bytecode files. This hack allows the bc
- // reader to ignore trailing garbage on bytecode files.
- if (At + Size < MemEnd)
- MemEnd = BlockEnd = At+Size;
-
- if (At + Size != MemEnd)
- error("Invalid Top Level Block Length! Type:" + utostr(Type)
- + ", Size:" + utostr(Size));
-
- // Parse the module contents
- this->ParseModule();
-
- // Check for missing functions
- if (hasFunctions())
- error("Function expected, but bytecode stream ended!");
-
- // Tell the handler we're done with the module
- if (Handler)
- Handler->handleModuleEnd(ModuleID);
-
- // Tell the handler we're finished the parse
- if (Handler) Handler->handleFinish();
-
- return false;
-
-}
-
-//===----------------------------------------------------------------------===//
-//=== Default Implementations of Handler Methods
-//===----------------------------------------------------------------------===//
-
-BytecodeHandler::~BytecodeHandler() {}
diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h
deleted file mode 100644
index 95cf58c2b3..0000000000
--- a/lib/Bytecode/Reader/Reader.h
+++ /dev/null
@@ -1,491 +0,0 @@
-//===-- Reader.h - Interface To Bytecode Reading ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by Reid Spencer and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file defines the interface to the Bytecode Reader which is
-// responsible for correctly interpreting bytecode files (backwards compatible)
-// and materializing a module from the bytecode read.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BYTECODE_PARSER_H
-#define BYTECODE_PARSER_H
-
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/ModuleProvider.h"
-#include "llvm/Bytecode/Analyzer.h"
-#include "llvm/ADT/SmallVector.h"
-#include <utility>
-#include <setjmp.h>
-
-namespace llvm {
-
-// Forward declarations
-class BytecodeHandler;
-class TypeSymbolTable;
-class ValueSymbolTable;
-
-/// This class defines the interface for parsing a buffer of bytecode. The
-/// parser itself takes no action except to call the various functions of
-/// the handler interface. The parser's sole responsibility is the correct
-/// interpretation of the bytecode buffer. The handler is responsible for
-/// instantiating and keeping track of all values. As a convenience, the parser
-/// is responsible for materializing types and will pass them through the
-/// handler interface as necessary.
-/// @see BytecodeHandler
-/// @brief Bytecode Reader interface
-class BytecodeReader : public ModuleProvider {
-
-/// @name Constructors
-/// @{
-public:
- /// @brief Default constructor. By default, no handler is used.
- BytecodeReader(BytecodeHandler* h = 0) {
- decompressedBlock = 0;
- Handler = h;
- }
-
- ~BytecodeReader() {
- freeState();
- if (decompressedBlock) {
- ::free(decompressedBlock);
- decompressedBlock = 0;
- }
- }
-
-/// @}
-/// @name Types
-/// @{
-public:
-
- /// @brief A convenience type for the buffer pointer
- typedef const unsigned char* BufPtr;
-
- /// @brief The type used for a vector of potentially abstract types
- typedef std::vector<PATypeHolder> TypeListTy;
-
- /// This type provides a vector of Value* via the User class for
- /// storage of Values that have been constructed when reading the
- /// bytecode. Because of forward referencing, constant replacement
- /// can occur so we ensure that our list of Value* is updated
- /// properly through those transitions. This ensures that the
- /// correct Value* is in our list when it comes time to associate
- /// constants with global variables at the end of reading the
- /// globals section.
- /// @brief A list of values as a User of those Values.
- class ValueList : public User {
- SmallVector<Use, 32> Uses;
- public:
- ValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) {}
-
- // vector compatibility methods
- unsigned size() const { return getNumOperands(); }
- void push_back(Value *V) {
- Uses.push_back(Use(V, this));
- OperandList = &Uses[0];
- ++NumOperands;
- }
- Value *back() const { return Uses.back(); }
- void pop_back() { Uses.pop_back(); --NumOperands; }
- bool empty() const { return NumOperands == 0; }
- virtual void print(std::ostream& os) const {
- for (unsigned i = 0; i < size(); ++i) {
- os << i << " ";
- getOperand(i)->print(os);
- os << "\n";
- }
- }
- };
-
- /// @brief A 2 dimensional table of values
- typedef std::vector<ValueList*> ValueTable;
-
- /// This map is needed so that forward references to constants can be looked
- /// up by Type and slot number when resolving those references.
- /// @brief A mapping of a Type/slot pair to a Constant*.
- typedef std::map<std::pair<unsigned,unsigned>, Constant*> ConstantRefsType;
-
- /// 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
- /// information. Lazy read-in is used mostly by the JIT which only wants to
- /// resolve functions as it needs them.
- /// @brief Keeps pointers to function contents for later use.
- struct LazyFunctionInfo {
- const unsigned char *Buf, *EndBuf;
- LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0)
- : Buf(B), EndBuf(EB) {}
- };
-
- /// @brief A mapping of functions to their LazyFunctionInfo for lazy reading.
- typedef std::map<Function*, LazyFunctionInfo> LazyFunctionMap;
-
- /// @brief A list of global variables and the slot number that initializes
- /// them.
- typedef std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitsList;
-
- /// @brief A list of global aliases and the slot number for constant aliasees
- typedef std::vector<std::pair<GlobalAlias*, unsigned> > AliaseeList;
-
- /// This type maps a typeslot/valueslot pair to the corresponding Value*.
- /// It is used for dealing with forward references as values are read in.
- /// @brief A map for dealing with forward references of values.
- typedef std::map<std::pair<unsigned,unsigned>,Value*> ForwardReferenceMap;
-
-/// @}
-/// @name Methods
-/// @{
-public:
- typedef size_t BCDecompressor_t(const char *, size_t, char*&, std::string*);
-
- /// @returns true if an error occurred
- /// @brief Main interface to parsing a bytecode buffer.
- bool ParseBytecode(
- volatile BufPtr Buf, ///< Beginning of the bytecode buffer
- unsigned Length, ///< Length of the bytecode buffer
- const std::string &ModuleID, ///< An identifier for the module constructed.
- BCDecompressor_t *Decompressor = 0, ///< Optional decompressor.
- std::string* ErrMsg = 0 ///< Optional place for error message
- );
-
- /// @brief Parse all function bodies
- bool ParseAllFunctionBodies(std::string* ErrMsg);
-
- /// @brief Parse the next function of specific type
- bool ParseFunction(Function* Func, std::string* ErrMsg);
-
- /// This method is abstract in the parent ModuleProvider class. Its
- /// implementation is identical to the ParseFunction method.
- /// @see ParseFunction
- /// @brief Make a specific function materialize.
- virtual bool materializeFunction(Function *F, std::string *ErrMsg = 0) {
- // If it already is material, ignore the request.
- if (!F->hasNotBeenReadFromBytecode()) return false;
-
- assert(LazyFunctionLoadMap.count(F) &&
- "not materialized but I don't know about it?");
- if (ParseFunction(F,ErrMsg))
- return true;
- return false;
- }
-
- /// dematerializeFunction - If the given function is read in, and if the
- /// module provider supports it, release the memory for the function, and set
- /// it up to be materialized lazily. If the provider doesn't support this
- /// capability, this method is a noop.
- ///
- virtual void dematerializeFunction(Function *F) {
- // If the function is not materialized, or if it is a prototype, ignore.
- if (F->hasNotBeenReadFromBytecode() ||
- F->isDeclaration())
- return;
-
- // Just forget the function body, we can remat it later.
- F->deleteBody();
- F->setLinkage(GlobalValue::GhostLinkage);
- }
-
- /// This method is abstract in the parent ModuleProvider class. Its
- /// implementation is identical to ParseAllFunctionBodies.
- /// @see ParseAllFunctionBodies
- /// @brief Make the whole module materialize
- virtual Module* materializeModule(std::string *ErrMsg = 0) {
- if (ParseAllFunctionBodies(ErrMsg))
- return 0;
- return TheModule;
- }
-
- /// This method is provided by the parent ModuleProvde class and overriden
- /// here. It simply releases the module from its provided and frees up our
- /// state.
- /// @brief Release our hold on the generated module
- Module* releaseModule(std::string *ErrInfo = 0) {
- // Since we're losing control of this Module, we must hand it back complete
- Module *M = ModuleProvider::releaseModule(ErrInfo);
- freeState();
- return M;
- }
-
-/// @}
-/// @name Parsing Units For Subclasses
-/// @{
-protected:
- /// @brief Parse whole module scope
- void ParseModule();
-
- /// @brief Parse the version information block
- void ParseVersionInfo();
-
- /// @brief Parse the ModuleGlobalInfo block
- void ParseModuleGlobalInfo();
-
- /// @brief Parse a value symbol table
- void ParseTypeSymbolTable(TypeSymbolTable *ST);
-
- /// @brief Parse a value symbol table
- void ParseValueSymbolTable(Function* Func, ValueSymbolTable *ST);
-
- /// @brief Parse functions lazily.
- void ParseFunctionLazily();
-
- /// @brief Parse a function body
- void ParseFunctionBody(Function* Func);
-
- /// @brief Parse global types
- void ParseGlobalTypes();
-
-
- /// @brief Parse a basic block (for LLVM 1.0 basic block blocks)
- BasicBlock* ParseBasicBlock(unsigned BlockNo);
-
- /// @brief parse an instruction list (for post LLVM 1.0 instruction lists
- /// with blocks differentiated by terminating instructions.
- unsigned ParseInstructionList(
- Function* F ///< The function into which BBs will be inserted
- );
-
- /// @brief Parse a single instruction.
- void ParseInstruction(
- SmallVector <unsigned, 8>& Args, ///< The arguments to be filled in
- BasicBlock* BB ///< The BB the instruction goes in
- );
-
- /// @brief Parse the whole constant pool
- void ParseConstantPool(ValueTable& Values, TypeListTy& Types,
- bool isFunction);
-
- /// @brief Parse a single constant pool value
- Value *ParseConstantPoolValue(unsigned TypeID);
-
- /// @brief Parse a block of types constants
- void ParseTypes(TypeListTy &Tab, unsigned NumEntries);
-
- /// @brief Parse a single type constant
- const Type *ParseType();
-
- /// @brief Parse a list of parameter attributes
- ParamAttrsList *ParseParamAttrsList();
-
- /// @brief Parse a string constants block
- void ParseStringConstants(unsigned NumEntries, ValueTable &Tab);
-
- /// @brief Release our memory.
- void freeState() {
- freeTable(FunctionValues);
- freeTable(ModuleValues);
- }
-
-/// @}
-/// @name Data
-/// @{
-private:
- std::string ErrorMsg; ///< A place to hold an error message through longjmp
- jmp_buf context; ///< Where to return to if an error occurs.
- char* decompressedBlock; ///< Result of decompression
- BufPtr MemStart; ///< Start of the memory buffer
- BufPtr MemEnd; ///< End of the memory buffer
- BufPtr BlockStart; ///< Start of current block being parsed
- BufPtr BlockEnd; ///< End of current block being parsed
- BufPtr At; ///< Where we're currently parsing at
-
- /// Information about the module, extracted from the bytecode revision number.
- ///
- unsigned char RevisionNum; // The rev # itself
-
- /// @brief This vector is used to deal with forward references to types in
- /// a module.
- TypeListTy ModuleTypes;
-
- /// @brief This is an inverse mapping of ModuleTypes from the type to an
- /// index. Because refining types causes the index of this map to be
- /// invalidated, any time we refine a type, we clear this cache and recompute
- /// it next time we need it. These entries are ordered by the pointer value.
- std::vector<std::pair<const Type*, unsigned> > ModuleTypeIDCache;
-
- /// @brief This vector is used to deal with forward references to types in
- /// a function.
- TypeListTy FunctionTypes;
-
- /// When the ModuleGlobalInfo section is read, we create a Function object
- /// for each function in the module. When the function is loaded, after the
- /// module global info is read, this Function is populated. Until then, the
- /// functions in this vector just hold the function signature.
- std::vector<Function*> FunctionSignatureList;
-
- /// @brief This is the table of values belonging to the current function
- ValueTable FunctionValues;
-
- /// @brief This is the table of values belonging to the module (global)
- ValueTable ModuleValues;
-
- /// @brief This keeps track of function level forward references.
- ForwardReferenceMap ForwardReferences;
-
- /// @brief The basic blocks we've parsed, while parsing a function.
- std::vector<BasicBlock*> ParsedBasicBlocks;
-
- /// This maintains a mapping between <Type, Slot #>'s and forward references
- /// to constants. Such values may be referenced before they are defined, and
- /// if so, the temporary object that they represent is held here. @brief
- /// Temporary place for forward references to constants.
- ConstantRefsType ConstantFwdRefs;
-
- /// Constant values are read in after global variables. Because of this, we
- /// must defer setting the initializers on global variables until after module
- /// level constants have been read. In the mean time, this list keeps track
- /// of what we must do.
- GlobalInitsList GlobalInits;
-
- /// Constant values are read in after global aliases. Because of this, we must
- /// defer setting the constant aliasees until after module level constants
- /// have been read. In the mean time, this list keeps track of what we must
- /// do.
- AliaseeList Aliasees;
-
- // For lazy reading-in of functions, we need to save away several pieces of
- // information about each function: its begin and end pointer in the buffer
- // and its FunctionSlot.
- LazyFunctionMap LazyFunctionLoadMap;
-
- /// 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
- /// the (polymorphic) BytecodeHandler interface (see llvm/Bytecode/Handler.h)
- /// 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 business of parsing the bytecode and building the IR. This is used,
- /// for example, by the llvm-abcd tool for analysis of byte code.
- /// @brief Handler for parsing events.
- BytecodeHandler* Handler;
-
-
-/// @}
-/// @name Implementation Details
-/// @{
-private:
- /// @brief Determines if this module has a function or not.
- bool hasFunctions() { return ! FunctionSignatureList.empty(); }
-
- /// @brief Determines if the type id has an implicit null value.
- bool hasImplicitNull(unsigned TyID );
-
- /// @brief Converts a type slot number to its Type*
- const Type *getType(unsigned ID);
-
- /// @brief Read in a type id and turn it into a Type*
- inline const Type* readType();
-
- /// @brief Converts a Type* to its type slot number
- unsigned getTypeSlot(const Type *Ty);
-
- /// @brief Gets the global type corresponding to the TypeId
- const Type *getGlobalTableType(unsigned TypeId);
-
- /// @brief Get a value from its typeid and slot number
- Value* getValue(unsigned TypeID, unsigned num, bool Create = true);
-
- /// @brief Get a basic block for current function
- BasicBlock *getBasicBlock(unsigned ID);
-
- /// @brief Get a constant value from its typeid and value slot.
- Constant* getConstantValue(unsigned typeSlot, unsigned valSlot);
-
- /// @brief Convenience function for getting a constant value when
- /// the Type has already been resolved.
- Constant* getConstantValue(const Type *Ty, unsigned valSlot) {
- return getConstantValue(getTypeSlot(Ty), valSlot);
- }
-
- /// @brief Insert a newly created value
- unsigned insertValue(Value *V, unsigned Type, ValueTable &Table);
-
- /// @brief Insert the arguments of a function.
- void insertArguments(Function* F );
-
- /// @brief Resolve all references to the placeholder (if any) for the
- /// given constant.
- void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
-
- /// @brief Free a table, making sure to free the ValueList in the table.
- void freeTable(ValueTable &Tab) {
- while (!Tab.empty()) {
- delete Tab.back();
- Tab.pop_back();
- }
- }
-
- inline void error(const std::string& errmsg);
-
- BytecodeReader(const BytecodeReader &); // DO NOT IMPLEMENT
- void operator=(const BytecodeReader &); // DO NOT IMPLEMENT
-
- // This enum provides the values of the well-known type slots that are always
- // emitted as the first few types in the table by the BytecodeWriter class.
- enum WellKnownTypeSlots {
- VoidTypeSlot = 0, ///< TypeID == VoidTyID
- FloatTySlot = 1, ///< TypeID == FloatTyID
- DoubleTySlot = 2, ///< TypeID == DoubleTyID
- LabelTySlot = 3, ///< TypeID == LabelTyID
- BoolTySlot = 4, ///< TypeID == IntegerTyID, width = 1
- Int8TySlot = 5, ///< TypeID == IntegerTyID, width = 8
- Int16TySlot = 6, ///< TypeID == IntegerTyID, width = 16
- Int32TySlot = 7, ///< TypeID == IntegerTyID, width = 32
- Int64TySlot = 8 ///< TypeID == IntegerTyID, width = 64
- };
-
-/// @}
-/// @name Reader Primitives
-/// @{
-private:
-
- /// @brief Is there more to parse in the current block?
- inline bool moreInBlock();
-
- /// @brief Have we read past the end of the block
- inline void checkPastBlockEnd(const char * block_name);
-
- /// @brief Align to 32 bits
- inline void align32();
-
- /// @brief Read an unsigned integer as 32-bits
- inline unsigned read_uint();
-
- /// @brief Read an unsigned integer with variable bit rate encoding
- inline unsigned read_vbr_uint();
-
- /// @brief Read an unsigned integer of no more than 24-bits with variable
- /// bit rate encoding.
- inline unsigned read_vbr_uint24();
-
- /// @brief Read an unsigned 64-bit integer with variable bit rate encoding.
- inline uint64_t read_vbr_uint64();
-
- /// @brief Read a signed 64-bit integer with variable bit rate encoding.
- inline int64_t read_vbr_int64();
-
- /// @brief Read a string
- inline std::string read_str();
- inline void read_str(SmallVectorImpl<char> &StrData);
-
- /// @brief Read a float value
- inline void read_float(float& FloatVal);
-
- /// @brief Read a double value
- inline void read_double(double& DoubleVal);
-
- /// @brief Read an arbitrary data chunk of fixed length
- inline void read_data(void *Ptr, void *End);
-
- /// @brief Read a bytecode block header
- inline void read_block(unsigned &Type, unsigned &Size);
-/// @}
-};
-
-} // End llvm namespace
-
-// vim: sw=2
-#endif
diff --git a/lib/Bytecode/Reader/ReaderWrappers.cpp b/lib/Bytecode/Reader/ReaderWrappers.cpp
deleted file mode 100644
index ea1495ecc5..0000000000
--- a/lib/Bytecode/Reader/ReaderWrappers.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-//===- ReaderWrappers.cpp - Parse bytecode from file or buffer -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements loading and parsing a bytecode file and parsing a
-// bytecode module from a given buffer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Bytecode/Analyzer.h"
-#include "llvm/Bytecode/Reader.h"
-#include "Reader.h"
-#include "llvm/Module.h"
-#include "llvm/Instructions.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/System/MappedFile.h"
-#include "llvm/System/Program.h"
-#include <cerrno>
-#include <memory>
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// BytecodeFileReader - Read from an mmap'able file descriptor.
-//
-
-namespace {
- /// BytecodeFileReader - parses a bytecode file from a file
- ///
- class BytecodeFileReader : public BytecodeReader {
- private:
- std::string fileName;
- BCDecompressor_t *Decompressor;
- sys::MappedFile mapFile;
-
- BytecodeFileReader(const BytecodeFileReader&); // Do not implement
- void operator=(const BytecodeFileReader &BFR); // Do not implement
-
- public:
- BytecodeFileReader(const std::string &Filename, BCDecompressor_t *BCDC,
- llvm::BytecodeHandler* H=0);
- bool read(std::string* ErrMsg);
-
- void freeState() {
- BytecodeReader::freeState();
- mapFile.close();
- }
- };
-}
-
-BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
- BCDecompressor_t *BCDC,
- llvm::BytecodeHandler* H)
- : BytecodeReader(H), fileName(Filename), Decompressor(BCDC) {
-}
-
-bool BytecodeFileReader::read(std::string* ErrMsg) {
- if (mapFile.open(sys::Path(fileName), sys::MappedFile::READ_ACCESS, ErrMsg))
- return true;
- if (!mapFile.map(ErrMsg)) {
- mapFile.close();
- return true;
- }
- unsigned char* buffer = reinterpret_cast<unsigned char*>(mapFile.base());
- return ParseBytecode(buffer, mapFile.size(), fileName,
- Decompressor, ErrMsg);
-}
-
-//===----------------------------------------------------------------------===//
-// BytecodeBufferReader - Read from a memory buffer
-//
-
-namespace {
- /// BytecodeBufferReader - parses a bytecode file from a buffer
- ///
- class BytecodeBufferReader : public BytecodeReader {
- private:
- const unsigned char *Buffer;
- const unsigned char *Buf;
- unsigned Length;
- std::string ModuleID;
- BCDecompressor_t *Decompressor;
- bool MustDelete;
-
- BytecodeBufferReader(const BytecodeBufferReader&); // Do not implement
- void operator=(const BytecodeBufferReader &BFR); // Do not implement
-
- public:
- BytecodeBufferReader(const unsigned char *Buf, unsigned Length,
- const std::string &ModuleID, BCDecompressor_t *BCDC,
- llvm::BytecodeHandler* Handler = 0);
- ~BytecodeBufferReader();
-
- bool read(std::string* ErrMsg);
-
- };
-}
-
-BytecodeBufferReader::BytecodeBufferReader(const unsigned char *buf,
- unsigned len,
- const std::string &modID,
- BCDecompressor_t *BCDC,
- llvm::BytecodeHandler *H)
- : BytecodeReader(H), Buffer(0), Buf(buf), Length(len), ModuleID(modID)
- , Decompressor(BCDC), MustDelete(false) {
-}
-
-BytecodeBufferReader::~BytecodeBufferReader() {
- if (MustDelete) delete [] Buffer;
-}
-
-bool
-BytecodeBufferReader::read(std::string* ErrMsg) {
- // If not aligned, allocate a new buffer to hold the bytecode...
- const unsigned char *ParseBegin = 0;
- if (reinterpret_cast<uint64_t>(Buf) & 3) {
- Buffer = new unsigned char[Length+4];
- unsigned Offset = 4 - ((intptr_t)Buffer & 3); // Make sure it's aligned
- ParseBegin = Buffer + Offset;
- memcpy((unsigned char*)ParseBegin, Buf, Length); // Copy it over
- MustDelete = true;
- } else {
- // If we don't need to copy it over, just use the caller's copy
- ParseBegin = Buffer = Buf;
- MustDelete = false;
- }
- if (ParseBytecode(ParseBegin, Length, ModuleID, Decompressor, ErrMsg)) {
- if (MustDelete) delete [] Buffer;
- return true;
- }
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// BytecodeStdinReader - Read bytecode from Standard Input
-//
-
-namespace {
- /// BytecodeStdinReader - parses a bytecode file from stdin
- ///
- class BytecodeStdinReader : public BytecodeReader {
- private:
- std::vector<unsigned char> FileData;
- BCDecompressor_t *Decompressor;
- unsigned char *FileBuf;
-
- BytecodeStdinReader(const BytecodeStdinReader&); // Do not implement
- void operator=(const BytecodeStdinReader &BFR); // Do not implement
-
- public:
- BytecodeStdinReader(BCDecompressor_t *BCDC, llvm::BytecodeHandler* H = 0);
- bool read(std::string* ErrMsg);
- };
-}
-
-BytecodeStdinReader::BytecodeStdinReader(BCDecompressor_t *BCDC,
- BytecodeHandler* H)
- : BytecodeReader(H), Decompressor(BCDC) {
-}
-
-bool BytecodeStdinReader::read(std::string* ErrMsg) {
- sys::Program::ChangeStdinToBinary();
- char Buffer[4096*4];
-
- // Read in all of the data from stdin, we cannot mmap stdin...
- while (cin.stream()->good()) {
- cin.stream()->read(Buffer, 4096*4);
- int BlockSize = cin.stream()->gcount();
- if (0 >= BlockSize)
- break;
- FileData.insert(FileData.end(), Buffer, Buffer+BlockSize);
- }
-
- if (FileData.empty()) {
- if (ErrMsg)
- *ErrMsg = "Standard Input is empty!";
- return true;
- }
-
- FileBuf = &FileData[0];
- if (ParseBytecode(FileBuf, FileData.size(), "<stdin>", Decompressor, ErrMsg))
- return true;
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Wrapper functions
-//===----------------------------------------------------------------------===//
-
-/// getBytecodeBufferModuleProvider - lazy function-at-a-time loading from a
-/// buffer
-ModuleProvider*
-llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
- unsigned Length,
- const std::string &ModuleID,
- BCDecompressor_t *BCDC,
- std::string *ErrMsg,
- BytecodeHandler *H) {
- BytecodeBufferReader *rdr =
- new BytecodeBufferReader(Buffer, Length, ModuleID, BCDC, H);
- if (rdr->read(ErrMsg))
- return 0;
- return rdr;
-}
-
-/// ParseBytecodeBuffer - Parse a given bytecode buffer
-///
-Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
- const std::string &ModuleID,
- BCDecompressor_t *BCDC,
- std::string *ErrMsg) {
- ModuleProvider *MP =
- getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, BCDC, ErrMsg, 0);
- if (!MP) return 0;
- Module *M = MP->releaseModule(ErrMsg);
- delete MP;
- return M;
-}
-
-/// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
-///
-ModuleProvider *
-llvm::getBytecodeModuleProvider(const std::string &Filename,
- BCDecompressor_t *BCDC,
- std::string* ErrMsg,
- BytecodeHandler* H) {
- // Read from a file
- if (Filename != std::string("-")) {
- BytecodeFileReader *rdr = new BytecodeFileReader(Filename, BCDC, H);
- if (rdr->read(ErrMsg))
- return 0;
- return rdr;
- }
-
- // Read from stdin
- BytecodeStdinReader *rdr = new BytecodeStdinReader(BCDC, H);
- if (rdr->read(ErrMsg))
- return 0;
- return rdr;
-}
-
-/// ParseBytecodeFile - Parse the given bytecode file
-///
-Module *llvm::ParseBytecodeFile(const std::string &Filename,
- BCDecompressor_t *BCDC,
- std::string *ErrMsg) {
- ModuleProvider* MP = getBytecodeModuleProvider(Filename, BCDC, ErrMsg);
- if (!MP) return 0;
- Module *M = MP->releaseModule(ErrMsg);
- delete MP;
- return M;
-}