Kill warning when compiling in optimized mode
[oota-llvm.git] / include / llvm / iMemory.h
index 4e50f30bebc00823b284d66dbd9b357121406153..d3dd9fd811694c93ba7634b42018a44ecf42f995 100644 (file)
@@ -1,7 +1,7 @@
-//===-- llvm/iMemory.h - Memory Operator node definitions --------*- C++ -*--=//
+//===-- llvm/iMemory.h - Memory Operator node definitions -------*- C++ -*-===//
 //
 // This file contains the declarations of all of the memory related operators.
-// This includes: malloc, free, alloca, load, store, getfield, putfield
+// This includes: malloc, free, alloca, load, store, and getelementptr
 //
 //===----------------------------------------------------------------------===//
 
@@ -9,7 +9,7 @@
 #define LLVM_IMEMORY_H
 
 #include "llvm/Instruction.h"
-#include "llvm/DerivedTypes.h"
+class PointerType;
 
 //===----------------------------------------------------------------------===//
 //                             AllocationInst Class
 // AllocaInst.
 //
 class AllocationInst : public Instruction {
-public:
+protected:
   AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
-                const string &Name = "")
-    : Instruction(Ty, iTy, Name) {
-    assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
-
-    if (ArraySize) {
-      // Make sure they didn't try to specify a size for !(unsized array) type
-      assert(getType()->getValueType()->isArrayType() && 
-             cast<ArrayType>(getType()->getValueType())->isUnsized() && 
-           "Trying to allocate something other than unsized array, with size!");
-
-      Operands.reserve(1);
-      Operands.push_back(Use(ArraySize, this));
-    } else {
-      // Make sure that the pointer is not to an unsized array!
-      assert(!getType()->getValueType()->isArrayType() ||
-            cast<const ArrayType>(getType()->getValueType())->isSized() && 
-            "Trying to allocate unsized array without size!");
-    }
-  }
+                const std::string &Name = "", Instruction *InsertBefore = 0);
+public:
 
   // isArrayAllocation - Return true if there is an allocation size parameter
-  // to the allocation instruction.
+  // to the allocation instruction that is not 1.
   //
-  inline bool isArrayAllocation() const { return Operands.size() == 1; }
+  bool isArrayAllocation() const;
 
-  inline const Value *getArraySize() const {
-    assert(isArrayAllocation()); return Operands[0];
-  }
-  inline Value *getArraySize() {
-    assert(isArrayAllocation()); return Operands[0];
-  }
+  // 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 {
@@ -60,11 +42,20 @@ public:
 
   // getAllocatedType - Return the type that is being allocated by the
   // instruction.
-  inline const Type *getAllocatedType() const {
-    return getType()->getValueType();
-  }
+  //
+  const Type *getAllocatedType() const;
 
   virtual Instruction *clone() const = 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));
+  }
 };
 
 
@@ -73,17 +64,16 @@ public:
 //===----------------------------------------------------------------------===//
 
 class MallocInst : public AllocationInst {
+  MallocInst(const MallocInst &MI);
 public:
-  MallocInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
-    : AllocationInst(Ty, ArraySize, Malloc, Name) {}
+  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(getType(), 
-                         Operands.size() ? (Value*)Operands[1].get() : 0);
+    return new MallocInst(*this);
   }
 
-  virtual const char *getOpcodeName() 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) {
@@ -100,17 +90,16 @@ public:
 //===----------------------------------------------------------------------===//
 
 class AllocaInst : public AllocationInst {
+  AllocaInst(const AllocaInst &);
 public:
-  AllocaInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
-    : AllocationInst(Ty, ArraySize, Alloca, Name) {}
+  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(getType(),
-                         Operands.size() ? (Value*)Operands[1].get() : 0);
+    return new AllocaInst(*this);
   }
 
-  virtual const char *getOpcodeName() 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) {
@@ -126,20 +115,12 @@ public:
 //                                 FreeInst Class
 //===----------------------------------------------------------------------===//
 
-class FreeInst : public Instruction {
-public:
-  FreeInst(Value *Ptr, const string &Name = "") 
-    : Instruction(Type::VoidTy, Free, Name) {
-    assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!");
-    Operands.reserve(1);
-    Operands.push_back(Use(Ptr, this));
-  }
+struct FreeInst : public Instruction {
+  FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
 
   virtual Instruction *clone() const { return new FreeInst(Operands[0]); }
 
-  virtual const char *getOpcodeName() const { return "free"; }
-
-  virtual bool hasSideEffects() const { return true; }
+  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; }
@@ -153,69 +134,41 @@ public:
 
 
 //===----------------------------------------------------------------------===//
-//                              MemAccessInst Class
+//                                LoadInst Class
 //===----------------------------------------------------------------------===//
-//
-// MemAccessInst - Common base class of LoadInst, StoreInst, and
-// GetElementPtrInst...
-//
-class MemAccessInst : public Instruction {
-protected:
-  inline MemAccessInst(const Type *Ty, unsigned Opcode,
-                      const vector<ConstPoolVal*> &Idx,
-                      const string &Nam = "")
-    : Instruction(Ty, Opcode, Nam),
-      indexVec(Idx)
-  {}
-  
-protected:
-  vector<ConstPoolVal*> indexVec;
-  
+
+class LoadInst : public Instruction {
+  LoadInst(const LoadInst &LI) : Instruction(LI.getType(), Load) {
+    Volatile = LI.isVolatile();
+    Operands.reserve(1);
+    Operands.push_back(Use(LI.Operands[0], this));
+  }
+  bool Volatile;   // True if this is a volatile load
 public:
-  // 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 vector<ConstPoolVal*> &Indices,
-                                   bool AllowStructLeaf = false);
-  
-  const vector<ConstPoolVal*>& getIndexVec() const { return indexVec; }
+  LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore);
+  LoadInst(Value *Ptr, const std::string &Name = "", bool isVolatile = false,
+           Instruction *InsertBefore = 0);
 
-  inline bool hasIndices() const { return !indexVec.empty(); }
-  
-  virtual Value* getPtrOperand() = 0;
-  
-  virtual int  getFirstOffsetIdx() const = 0;
-};
+  /// isVolatile - Return true if this is a load from a volatile memory
+  /// location.
+  bool isVolatile() const { return Volatile; }
 
+  /// setVolatile - Specify whether this is a volatile load or not.
+  ///
+  void setVolatile(bool V) { Volatile = V; }
 
-//===----------------------------------------------------------------------===//
-//                                LoadInst Class
-//===----------------------------------------------------------------------===//
+  virtual Instruction *clone() const { return new LoadInst(*this); }
 
-class LoadInst : public MemAccessInst {
-  LoadInst(const LoadInst &LI) : MemAccessInst(LI.getType(), Load, LI.getIndexVec()) {
-    Operands.reserve(LI.Operands.size());
-    for (unsigned i = 0, E = LI.Operands.size(); i != E; ++i)
-      Operands.push_back(Use(LI.Operands[i], this));
-  }
-public:
-  LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
-          const string &Name = "");
-  LoadInst(Value *Ptr, const string &Name = "");
+  virtual bool mayWriteToMemory() const { return isVolatile(); }
 
-  virtual Instruction* clone() const { return new LoadInst(*this); }
-  virtual const char*  getOpcodeName() const { return "load"; }  
-  virtual Value*       getPtrOperand() { return this->getOperand(0); }
-  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
+  Value *getPointerOperand() { return getOperand(0); }
+  const Value *getPointerOperand() const { return getOperand(0); }
+  static unsigned getPointerOperandIndex() { return 0U; }
 
   // 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);
+    return I->getOpcode() == Instruction::Load;
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -227,28 +180,40 @@ public:
 //                                StoreInst Class
 //===----------------------------------------------------------------------===//
 
-class StoreInst : public MemAccessInst {
-  StoreInst(const StoreInst &SI) : MemAccessInst(SI.getType(), Store, SI.getIndexVec()) {
-    Operands.reserve(SI.Operands.size());
-    for (unsigned i = 0, E = SI.Operands.size(); i != E; ++i)
-      Operands.push_back(Use(SI.Operands[i], this));
+class StoreInst : public Instruction {
+  StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store) {
+    Volatile = SI.isVolatile();
+    Operands.reserve(2);
+    Operands.push_back(Use(SI.Operands[0], this));
+    Operands.push_back(Use(SI.Operands[1], this));
   }
+  bool Volatile;   // True if this is a volatile store
 public:
-  StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
-           const string &Name = "");
-  StoreInst(Value *Val, Value *Ptr, const string &Name = "");
+  StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
+            Instruction *InsertBefore = 0);
+
+
+  /// isVolatile - Return true if this is a load from a volatile memory
+  /// location.
+  bool isVolatile() const { return Volatile; }
+
+  /// setVolatile - Specify whether this is a volatile load or not.
+  ///
+  void setVolatile(bool V) { Volatile = V; }
+
   virtual Instruction *clone() const { return new StoreInst(*this); }
 
-  virtual const char *getOpcodeName() const { return "store"; }  
-  
-  virtual bool hasSideEffects() const { return true; }
-  virtual Value*       getPtrOperand() { return this->getOperand(1); }
-  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 2)? 2 : -1;}
+  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);
+    return I->getOpcode() == Instruction::Store;
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -260,27 +225,58 @@ public:
 //                             GetElementPtrInst Class
 //===----------------------------------------------------------------------===//
 
-class GetElementPtrInst : public MemAccessInst {
+class GetElementPtrInst : public Instruction {
   GetElementPtrInst(const GetElementPtrInst &EPI)
-    : MemAccessInst(EPI.getType(), GetElementPtr, EPI.getIndexVec()) {
+    : 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 vector<ConstPoolVal*> &Idx,
-                   const string &Name = "");
+  GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
+                   const std::string &Name = "", Instruction *InsertBefore =0);
   virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
-  virtual const char *getOpcodeName() const { return "getelementptr"; }  
-  virtual Value*       getPtrOperand() { return this->getOperand(0); }
-  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
   
-  inline bool isArraySelector() const { return !isStructSelector(); }
-  bool isStructSelector() const;
-
   // getType - Overload to return most specific pointer type...
   inline const PointerType *getType() const {
-    return cast<const PointerType>(Instruction::getType());
+    return (PointerType*)Instruction::getType();
+  }
+
+  /// 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(); }
+
+  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: