#define LLVM_IMEMORY_H
#include "llvm/Instruction.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/ConstPoolVals.h"
-
-class ConstPoolType;
+class PointerType;
+//===----------------------------------------------------------------------===//
+// AllocationInst Class
+//===----------------------------------------------------------------------===//
+//
+// AllocationInst - This class is the common base class of MallocInst and
+// AllocaInst.
+//
class AllocationInst : public Instruction {
protected:
- UseTy<ConstPoolType> TyVal;
- Use ArraySize;
+ AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
+ const std::string &Name = "", Instruction *InsertBefore = 0);
public:
- AllocationInst(ConstPoolType *tyVal, Value *arrSize, unsigned iTy,
- const string &Name = "")
- : Instruction(tyVal->getValue(), iTy, Name),
- TyVal(tyVal, this), ArraySize(arrSize, this) {
- // Make sure they didn't try to specify a size for an invalid type...
- assert(arrSize == 0 ||
- (getType()->getValueType()->isArrayType() &&
- ((const ArrayType*)getType()->getValueType())->isUnsized()) &&
- "Trying to allocate something other than unsized array, with size!");
+ // isArrayAllocation - Return true if there is an allocation size parameter
+ // to the allocation instruction that is not 1.
+ //
+ bool isArrayAllocation() const;
- // Make sure that if a size is specified, that it is a uint!
- assert(arrSize == 0 || arrSize->getType() == Type::UIntTy &&
- "Malloc SIZE is not a 'uint'!");
- }
- inline ~AllocationInst() {}
+ // getArraySize - Get the number of element allocated, for a simple allocation
+ // of a single element, this will return a constant 1 value.
+ //
+ inline const Value *getArraySize() const { return Operands[0]; }
+ inline Value *getArraySize() { return Operands[0]; }
// getType - Overload to return most specific pointer type...
inline const PointerType *getType() const {
return (const PointerType*)Instruction::getType();
}
+ // getAllocatedType - Return the type that is being allocated by the
+ // instruction.
+ //
+ const Type *getAllocatedType() const;
+
virtual Instruction *clone() const = 0;
- inline virtual void dropAllReferences() { TyVal = 0; ArraySize = 0; }
- virtual bool setOperand(unsigned i, Value *Val) {
- if (i == 0) {
- assert(!Val || Val->getValueType() == Value::ConstantVal);
- TyVal = (ConstPoolType*)Val;
- return true;
- } else if (i == 1) {
- // Make sure they didn't try to specify a size for an invalid type...
- assert(Val == 0 ||
- (getType()->getValueType()->isArrayType() &&
- ((const ArrayType*)getType()->getValueType())->isUnsized()) &&
- "Trying to allocate something other than unsized array, with size!");
-
- // Make sure that if a size is specified, that it is a uint!
- assert(Val == 0 || Val->getType() == Type::UIntTy &&
- "Malloc SIZE is not a 'uint'!");
-
- ArraySize = Val;
- return true;
- }
- return false;
- }
-
- virtual unsigned getNumOperands() const { return 2; }
-
- virtual const Value *getOperand(unsigned i) const {
- return i == 0 ? TyVal : (i == 1 ? ArraySize : 0);
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const AllocationInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Alloca ||
+ I->getOpcode() == Instruction::Malloc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
+
+//===----------------------------------------------------------------------===//
+// MallocInst Class
+//===----------------------------------------------------------------------===//
+
class MallocInst : public AllocationInst {
+ MallocInst(const MallocInst &MI);
public:
- MallocInst(ConstPoolType *tyVal, Value *ArraySize = 0,
- const string &Name = "")
- : AllocationInst(tyVal, ArraySize, Instruction::Malloc, Name) {}
- inline ~MallocInst() {}
+ MallocInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Malloc, Name, InsertBefore) {}
virtual Instruction *clone() const {
- return new MallocInst(TyVal, ArraySize);
+ return new MallocInst(*this);
}
- virtual string getOpcode() const { return "malloc"; }
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MallocInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Malloc);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
};
+
+//===----------------------------------------------------------------------===//
+// AllocaInst Class
+//===----------------------------------------------------------------------===//
+
class AllocaInst : public AllocationInst {
+ AllocaInst(const AllocaInst &);
public:
- AllocaInst(ConstPoolType *tyVal, Value *ArraySize = 0,
- const string &Name = "")
- : AllocationInst(tyVal, ArraySize, Instruction::Alloca, Name) {}
- inline ~AllocaInst() {}
+ AllocaInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Alloca, Name, InsertBefore) {}
virtual Instruction *clone() const {
- return new AllocaInst(TyVal, ArraySize);
+ return new AllocaInst(*this);
}
- virtual string getOpcode() const { return "alloca"; }
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const AllocaInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Alloca);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
};
+//===----------------------------------------------------------------------===//
+// FreeInst Class
+//===----------------------------------------------------------------------===//
-class FreeInst : public Instruction {
-protected:
- Use Pointer;
+struct FreeInst : public Instruction {
+ FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
+
+ virtual Instruction *clone() const { return new FreeInst(Operands[0]); }
+
+ virtual bool mayWriteToMemory() const { return true; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FreeInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Free);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// LoadInst Class
+//===----------------------------------------------------------------------===//
+
+class LoadInst : public Instruction {
+ LoadInst(const LoadInst &LI) : Instruction(LI.getType(), Load) {
+ Operands.reserve(1);
+ Operands.push_back(Use(LI.Operands[0], this));
+ }
public:
- FreeInst(Value *Ptr, const string &Name = "")
- : Instruction(Type::VoidTy, Instruction::Free, Name),
- Pointer(Ptr, this) {
+ LoadInst(Value *Ptr, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+
+ virtual Instruction *clone() const { return new LoadInst(*this); }
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ static unsigned getPointerOperandIndex() { return 0U; }
- assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!");
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const LoadInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Load);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// StoreInst Class
+//===----------------------------------------------------------------------===//
+
+class StoreInst : public Instruction {
+ StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store) {
+ Operands.reserve(2);
+ Operands.push_back(Use(SI.Operands[0], this));
+ Operands.push_back(Use(SI.Operands[1], this));
+ }
+public:
+ StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore = 0);
+ virtual Instruction *clone() const { return new StoreInst(*this); }
+
+ virtual bool mayWriteToMemory() const { return true; }
+
+ Value *getPointerOperand() { return getOperand(1); }
+ const Value *getPointerOperand() const { return getOperand(1); }
+ static unsigned getPointerOperandIndex() { return 1U; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const StoreInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Store);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
- inline ~FreeInst() {}
+};
- virtual Instruction *clone() const { return new FreeInst(Pointer); }
- inline virtual void dropAllReferences() { Pointer = 0; }
+//===----------------------------------------------------------------------===//
+// GetElementPtrInst Class
+//===----------------------------------------------------------------------===//
- virtual bool setOperand(unsigned i, Value *Val) {
- if (i == 0) {
- assert(!Val || Val->getType()->isPointerType() &&
- "Can't free nonpointer!");
- Pointer = Val;
- return true;
- }
- return false;
+class GetElementPtrInst : public Instruction {
+ GetElementPtrInst(const GetElementPtrInst &EPI)
+ : Instruction((Type*)EPI.getType(), GetElementPtr) {
+ Operands.reserve(EPI.Operands.size());
+ for (unsigned i = 0, E = EPI.Operands.size(); i != E; ++i)
+ Operands.push_back(Use(EPI.Operands[i], this));
+ }
+public:
+ GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
+ const std::string &Name = "", Instruction *InsertBefore =0);
+ virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
+
+ // getType - Overload to return most specific pointer type...
+ inline const PointerType *getType() const {
+ return (PointerType*)Instruction::getType();
}
- virtual unsigned getNumOperands() const { return 1; }
- virtual const Value *getOperand(unsigned i) const {
- return i == 0 ? Pointer : 0;
+ /// 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.
+ ///
+ static const Type *getIndexedType(const Type *Ptr,
+ const std::vector<Value*> &Indices,
+ bool AllowStructLeaf = false);
+
+ inline op_iterator idx_begin() {
+ return op_begin()+1;
}
+ inline const_op_iterator idx_begin() const {
+ return op_begin()+1;
+ }
+ inline op_iterator idx_end() { return op_end(); }
+ inline const_op_iterator idx_end() const { return op_end(); }
- virtual string getOpcode() const { return "free"; }
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ inline unsigned getNumIndices() const { // Note: always non-negative
+ return getNumOperands() - 1;
+ }
+
+ inline bool hasIndices() const {
+ return getNumOperands() > 1;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const GetElementPtrInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::GetElementPtr);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
};
#endif // LLVM_IMEMORY_H