X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FiMemory.cpp;h=6e6d0e5f2cd93396c95ec3032d4d026e6e096854;hb=33af23d902e8403ad6d470b2a0b6e814a596e037;hp=79c697edc8fbd0440ff5db752d8e9494c191cc80;hpb=d59b0af98b8da068f345299a3fc68e151b46fbd7;p=oota-llvm.git diff --git a/lib/VMCore/iMemory.cpp b/lib/VMCore/iMemory.cpp index 79c697edc8f..6e6d0e5f2cd 100644 --- a/lib/VMCore/iMemory.cpp +++ b/lib/VMCore/iMemory.cpp @@ -1,22 +1,22 @@ -//===-- iMemory.cpp - Implement Memory instructions --------------*- C++ -*--=// +//===-- iMemory.cpp - Implement Memory instructions -----------------------===// +// +// 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 the various memory related classes defined in iMemory.h // //===----------------------------------------------------------------------===// #include "llvm/iMemory.h" -#include "llvm/ConstantVals.h" - -static inline const Type *checkType(const Type *Ty) { - assert(Ty && "Invalid indices for type!"); - return Ty; -} - -AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name = "") - : Instruction(Ty, iTy, Name) { - assert(Ty->isPointerType() && "Can't allocate a non pointer type!"); +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +using namespace llvm; +void AllocationInst::init(const Type *Ty, Value *ArraySize, unsigned iTy) { // ArraySize defaults to 1. if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1); @@ -27,41 +27,57 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, Operands.push_back(Use(ArraySize, this)); } +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const std::string &Name, + Instruction *InsertBefore) + : Instruction(PointerType::get(Ty), iTy, Name, InsertBefore) { + init(Ty, ArraySize, iTy); +} + +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(PointerType::get(Ty), iTy, Name, InsertAtEnd) { + init(Ty, ArraySize, iTy); +} + bool AllocationInst::isArrayAllocation() const { - return getNumOperands() == 1 && - getOperand(0) != ConstantUInt::get(Type::UIntTy, 1); + return getOperand(0) != ConstantUInt::get(Type::UIntTy, 1); +} + +const Type *AllocationInst::getAllocatedType() const { + return getType()->getElementType(); +} + +AllocaInst::AllocaInst(const AllocaInst &AI) + : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0), + Instruction::Alloca) { +} + +MallocInst::MallocInst(const MallocInst &MI) + : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0), + Instruction::Malloc) { } //===----------------------------------------------------------------------===// -// MemAccessInst Implementation +// FreeInst Implementation //===----------------------------------------------------------------------===// -// getIndexedType - Returns the type of the element that would be loaded with -// a load instruction with the specified parameters. -// -// A null type is returned if the indices are invalid for the specified -// pointer type. -// -const Type* MemAccessInst::getIndexedType(const Type *Ptr, - const std::vector &Idx, - bool AllowCompositeLeaf = false) { - if (!Ptr->isPointerType()) return 0; // Type isn't a pointer type! +void FreeInst::init(Value *Ptr) +{ + assert(Ptr && isa(Ptr->getType()) && "Can't free nonpointer!"); + Operands.reserve(1); + Operands.push_back(Use(Ptr, this)); +} - // Handle the special case of the empty set index set... - if (Idx.empty()) return cast(Ptr)->getElementType(); - - unsigned CurIDX = 0; - while (const CompositeType *CT = dyn_cast(Ptr)) { - if (Idx.size() == CurIDX) { - if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr; - return 0; // Can't load a whole structure or array!?!? - } +FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) + : Instruction(Type::VoidTy, Free, "", InsertBefore) { + init(Ptr); +} - Value *Index = Idx[CurIDX++]; - if (!CT->indexValid(Index)) return 0; - Ptr = CT->getTypeAtIndex(Index); - } - return CurIDX == Idx.size() ? Ptr : 0; +FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Free, "", InsertAtEnd) { + init(Ptr); } @@ -69,23 +85,37 @@ const Type* MemAccessInst::getIndexedType(const Type *Ptr, // LoadInst Implementation //===----------------------------------------------------------------------===// -LoadInst::LoadInst(Value *Ptr, const std::vector &Idx, - const std::string &Name = "") - : MemAccessInst(checkType(getIndexedType(Ptr->getType(), Idx)), Load, Name) { - assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!"); - Operands.reserve(1+Idx.size()); +void LoadInst::init(Value *Ptr) { + assert(Ptr && isa(Ptr->getType()) && + "Ptr must have pointer type."); + Operands.reserve(1); Operands.push_back(Use(Ptr, this)); - - for (unsigned i = 0, E = Idx.size(); i != E; ++i) - Operands.push_back(Use(Idx[i], this)); - } -LoadInst::LoadInst(Value *Ptr, const std::string &Name = "") - : MemAccessInst(cast(Ptr->getType())->getElementType(), - Load, Name) { - Operands.reserve(1); - Operands.push_back(Use(Ptr, this)); +LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertBef), Volatile(false) { + init(Ptr); +} + +LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertAE), Volatile(false) { + init(Ptr); +} + +LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, + Instruction *InsertBef) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertBef), Volatile(isVolatile) { + init(Ptr); +} + +LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, + BasicBlock *InsertAE) + : Instruction(cast(Ptr->getType())->getElementType(), + Load, Name, InsertAE), Volatile(isVolatile) { + init(Ptr); } @@ -93,40 +123,155 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name = "") // StoreInst Implementation //===----------------------------------------------------------------------===// -StoreInst::StoreInst(Value *Val, Value *Ptr, const std::vector &Idx) - : MemAccessInst(Type::VoidTy, Store, "") { - assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!"); - - Operands.reserve(2+Idx.size()); - Operands.push_back(Use(Val, this)); - Operands.push_back(Use(Ptr, this)); +StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore) + : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(false) { + init(Val, Ptr); +} - for (unsigned i = 0, E = Idx.size(); i != E; ++i) - Operands.push_back(Use(Idx[i], this)); +StoreInst::StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(false) { + init(Val, Ptr); +} + +StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, + Instruction *InsertBefore) + : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) { + init(Val, Ptr); } -StoreInst::StoreInst(Value *Val, Value *Ptr) - : MemAccessInst(Type::VoidTy, Store, "") { - +StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, + BasicBlock *InsertAtEnd) + : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(isVolatile) { + init(Val, Ptr); +} + +void StoreInst::init(Value *Val, Value *Ptr) { + assert(isa(Ptr->getType()) && + Val->getType() == cast(Ptr->getType())->getElementType() + && "Ptr must have pointer type."); + Operands.reserve(2); Operands.push_back(Use(Val, this)); Operands.push_back(Use(Ptr, this)); } - //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// -GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name = "") - : MemAccessInst(PointerType::get(checkType(getIndexedType(Ptr->getType(), - Idx, true))), - GetElementPtr, Name) { - assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!"); +// checkType - Simple wrapper function to give a better assertion failure +// message on bad indexes for a gep instruction. +// +static inline const Type *checkType(const Type *Ty) { + assert(Ty && "Invalid indices for type!"); + return Ty; +} + +void GetElementPtrInst::init(Value *Ptr, const std::vector &Idx) +{ Operands.reserve(1+Idx.size()); Operands.push_back(Use(Ptr, this)); for (unsigned i = 0, E = Idx.size(); i != E; ++i) Operands.push_back(Use(Idx[i], this)); } + +void GetElementPtrInst::init(Value *Ptr, Value *Idx0, Value *Idx1) { + Operands.reserve(3); + Operands.push_back(Use(Ptr, this)); + Operands.push_back(Use(Idx0, this)); + Operands.push_back(Use(Idx1, this)); +} + +GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, + const std::string &Name, Instruction *InBe) + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), + Idx, true))), + GetElementPtr, Name, InBe) { + init(Ptr, Idx); +} + +GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, + const std::string &Name, BasicBlock *IAE) + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), + Idx, true))), + GetElementPtr, Name, IAE) { + init(Ptr, Idx); +} + +GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, + const std::string &Name, Instruction *InBe) + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), + Idx0, Idx1, true))), + GetElementPtr, Name, InBe) { + init(Ptr, Idx0, Idx1); +} + +GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, + const std::string &Name, BasicBlock *IAE) + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), + Idx0, Idx1, true))), + GetElementPtr, Name, IAE) { + init(Ptr, Idx0, Idx1); +} + +// getIndexedType - Returns the type of the element that would be loaded with +// a load instruction with the specified parameters. +// +// A null type is returned if the indices are invalid for the specified +// pointer type. +// +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, + const std::vector &Idx, + bool AllowCompositeLeaf) { + if (!isa(Ptr)) return 0; // Type isn't a pointer type! + + // Handle the special case of the empty set index set... + if (Idx.empty()) + if (AllowCompositeLeaf || + cast(Ptr)->getElementType()->isFirstClassType()) + return cast(Ptr)->getElementType(); + else + return 0; + + unsigned CurIdx = 0; + while (const CompositeType *CT = dyn_cast(Ptr)) { + if (Idx.size() == CurIdx) { + if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr; + return 0; // Can't load a whole structure or array!?!? + } + + Value *Index = Idx[CurIdx++]; + if (isa(CT) && CurIdx != 1) + return 0; // Can only index into pointer types at the first index! + if (!CT->indexValid(Index)) return 0; + Ptr = CT->getTypeAtIndex(Index); + + // If the new type forwards to another type, then it is in the middle + // of being refined to another type (and hence, may have dropped all + // references to what it was using before). So, use the new forwarded + // type. + if (const Type * Ty = Ptr->getForwardedType()) { + Ptr = Ty; + } + } + return CurIdx == Idx.size() ? Ptr : 0; +} + +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, + Value *Idx0, Value *Idx1, + bool AllowCompositeLeaf) { + const PointerType *PTy = dyn_cast(Ptr); + if (!PTy) return 0; // Type isn't a pointer type! + + // Check the pointer index. + if (!PTy->indexValid(Idx0)) return 0; + + const CompositeType *CT = dyn_cast(PTy->getElementType()); + if (!CT || !CT->indexValid(Idx1)) return 0; + + const Type *ElTy = CT->getTypeAtIndex(Idx1); + if (AllowCompositeLeaf || ElTy->isFirstClassType()) + return ElTy; + return 0; +}