//===-- 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/Constants.h" #include "llvm/DerivedTypes.h" AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, const std::string &Name, Instruction *InsertBef) : Instruction(PointerType::get(Ty), iTy, Name, InsertBef) { // ArraySize defaults to 1. if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1); Operands.reserve(1); assert(ArraySize->getType() == Type::UIntTy && "Malloc/Allocation array size != UIntTy!"); Operands.push_back(Use(ArraySize, this)); } bool AllocationInst::isArrayAllocation() const { 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) { } //===----------------------------------------------------------------------===// // FreeInst Implementation //===----------------------------------------------------------------------===// FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) : Instruction(Type::VoidTy, Free, "", InsertBefore) { assert(isa(Ptr->getType()) && "Can't free nonpointer!"); Operands.reserve(1); Operands.push_back(Use(Ptr, this)); } //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) : Instruction(cast(Ptr->getType())->getElementType(), Load, Name, InsertBef), Volatile(false) { Operands.reserve(1); Operands.push_back(Use(Ptr, this)); } LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, Instruction *InsertBef) : Instruction(cast(Ptr->getType())->getElementType(), Load, Name, InsertBef), Volatile(isVolatile) { Operands.reserve(1); Operands.push_back(Use(Ptr, this)); } //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore) : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(false) { Operands.reserve(2); Operands.push_back(Use(Val, this)); Operands.push_back(Use(Ptr, this)); } StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, Instruction *InsertBefore) : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) { Operands.reserve(2); Operands.push_back(Use(Val, this)); Operands.push_back(Use(Ptr, this)); } //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// // 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; } 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) { 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)); } // 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()) 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!?!? } 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); } return CurIdx == Idx.size() ? Ptr : 0; }