First cut at the Code Generator using the TableGen methodology.
[oota-llvm.git] / include / llvm / iMemory.h
index 077266de94cb58d7a87ed995b00935389b51884d..09c94a2c77db62203120acfa34f89a2d66a5b43a 100644 (file)
 #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