diff options
Diffstat (limited to 'lib/Bytecode/Reader/Reader.cpp')
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 2212 |
1 files changed, 0 insertions, 2212 deletions
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 argum |