Add some useful accessors
[oota-llvm.git] / include / llvm / iMemory.h
1 //===-- llvm/iMemory.h - Memory Operator node definitions --------*- C++ -*--=//
2 //
3 // This file contains the declarations of all of the memory related operators.
4 // This includes: malloc, free, alloca, load, store, getfield, putfield
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_IMEMORY_H
9 #define LLVM_IMEMORY_H
10
11 #include "llvm/Instruction.h"
12 #include "llvm/DerivedTypes.h"
13
14 //===----------------------------------------------------------------------===//
15 //                             AllocationInst Class
16 //===----------------------------------------------------------------------===//
17 //
18 // AllocationInst - This class is the common base class of MallocInst and
19 // AllocaInst.
20 //
21 class AllocationInst : public Instruction {
22 public:
23   AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
24                  const string &Name = "")
25     : Instruction(Ty, iTy, Name) {
26     assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
27
28     if (ArraySize) {
29       // Make sure they didn't try to specify a size for !(unsized array) type
30       assert(getType()->getValueType()->isArrayType() && 
31              cast<ArrayType>(getType()->getValueType())->isUnsized() && 
32            "Trying to allocate something other than unsized array, with size!");
33
34       Operands.reserve(1);
35       Operands.push_back(Use(ArraySize, this));
36     } else {
37       // Make sure that the pointer is not to an unsized array!
38       assert(!getType()->getValueType()->isArrayType() ||
39              cast<const ArrayType>(getType()->getValueType())->isSized() && 
40              "Trying to allocate unsized array without size!");
41     }
42   }
43
44   // isArrayAllocation - Return true if there is an allocation size parameter
45   // to the allocation instruction.
46   //
47   inline bool isArrayAllocation() const { return Operands.size() == 1; }
48
49   inline const Value *getArraySize() const {
50     assert(isArrayAllocation()); return Operands[0];
51   }
52   inline Value *getArraySize() {
53     assert(isArrayAllocation()); return Operands[0];
54   }
55
56   // getType - Overload to return most specific pointer type...
57   inline const PointerType *getType() const {
58     return (const PointerType*)Instruction::getType(); 
59   }
60
61   // getAllocatedType - Return the type that is being allocated by the
62   // instruction.
63   inline const Type *getAllocatedType() const {
64     return getType()->getValueType();
65   }
66
67   virtual Instruction *clone() const = 0;
68 };
69
70
71 //===----------------------------------------------------------------------===//
72 //                                MallocInst Class
73 //===----------------------------------------------------------------------===//
74
75 class MallocInst : public AllocationInst {
76 public:
77   MallocInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
78     : AllocationInst(Ty, ArraySize, Malloc, Name) {}
79
80   virtual Instruction *clone() const { 
81     return new MallocInst(getType(), 
82                           Operands.size() ? (Value*)Operands[1].get() : 0);
83   }
84
85   virtual const char *getOpcodeName() const { return "malloc"; }
86
87   // Methods for support type inquiry through isa, cast, and dyn_cast:
88   static inline bool classof(const MallocInst *) { return true; }
89   static inline bool classof(const Instruction *I) {
90     return (I->getOpcode() == Instruction::Malloc);
91   }
92   static inline bool classof(const Value *V) {
93     return isa<Instruction>(V) && classof(cast<Instruction>(V));
94   }
95 };
96
97
98 //===----------------------------------------------------------------------===//
99 //                                AllocaInst Class
100 //===----------------------------------------------------------------------===//
101
102 class AllocaInst : public AllocationInst {
103 public:
104   AllocaInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
105     : AllocationInst(Ty, ArraySize, Alloca, Name) {}
106
107   virtual Instruction *clone() const { 
108     return new AllocaInst(getType(),
109                           Operands.size() ? (Value*)Operands[1].get() : 0);
110   }
111
112   virtual const char *getOpcodeName() const { return "alloca"; }
113
114   // Methods for support type inquiry through isa, cast, and dyn_cast:
115   static inline bool classof(const AllocaInst *) { return true; }
116   static inline bool classof(const Instruction *I) {
117     return (I->getOpcode() == Instruction::Alloca);
118   }
119   static inline bool classof(const Value *V) {
120     return isa<Instruction>(V) && classof(cast<Instruction>(V));
121   }
122 };
123
124
125 //===----------------------------------------------------------------------===//
126 //                                 FreeInst Class
127 //===----------------------------------------------------------------------===//
128
129 class FreeInst : public Instruction {
130 public:
131   FreeInst(Value *Ptr, const string &Name = "") 
132     : Instruction(Type::VoidTy, Free, Name) {
133     assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!");
134     Operands.reserve(1);
135     Operands.push_back(Use(Ptr, this));
136   }
137
138   virtual Instruction *clone() const { return new FreeInst(Operands[0]); }
139
140   virtual const char *getOpcodeName() const { return "free"; }
141
142   virtual bool hasSideEffects() const { return true; }
143
144   // Methods for support type inquiry through isa, cast, and dyn_cast:
145   static inline bool classof(const FreeInst *) { return true; }
146   static inline bool classof(const Instruction *I) {
147     return (I->getOpcode() == Instruction::Free);
148   }
149   static inline bool classof(const Value *V) {
150     return isa<Instruction>(V) && classof(cast<Instruction>(V));
151   }
152 };
153
154
155 //===----------------------------------------------------------------------===//
156 //                              MemAccessInst Class
157 //===----------------------------------------------------------------------===//
158 //
159 // MemAccessInst - Common base class of LoadInst, StoreInst, and
160 // GetElementPtrInst...
161 //
162 class MemAccessInst : public Instruction {
163 protected:
164   inline MemAccessInst(const Type *Ty, unsigned Opcode,
165                        const vector<ConstPoolVal*> &Idx,
166                        const string &Nam = "")
167     : Instruction(Ty, Opcode, Nam),
168       indexVec(Idx)
169   {}
170   
171 protected:
172   vector<ConstPoolVal*> indexVec;
173   
174 public:
175   // getIndexedType - Returns the type of the element that would be loaded with
176   // a load instruction with the specified parameters.
177   //
178   // A null type is returned if the indices are invalid for the specified 
179   // pointer type.
180   //
181   static const Type *getIndexedType(const Type *Ptr, 
182                                     const vector<ConstPoolVal*> &Indices,
183                                     bool AllowStructLeaf = false);
184   
185   const vector<ConstPoolVal*>& getIndexVec() const { return indexVec; }
186   
187   virtual Value* getPtrOperand() = 0;
188   
189   virtual int   getFirstOffsetIdx() const = 0;
190 };
191
192
193 //===----------------------------------------------------------------------===//
194 //                                LoadInst Class
195 //===----------------------------------------------------------------------===//
196
197 class LoadInst : public MemAccessInst {
198   LoadInst(const LoadInst &LI) : MemAccessInst(LI.getType(), Load, LI.getIndexVec()) {
199     Operands.reserve(LI.Operands.size());
200     for (unsigned i = 0, E = LI.Operands.size(); i != E; ++i)
201       Operands.push_back(Use(LI.Operands[i], this));
202   }
203 public:
204   LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
205            const string &Name = "");
206   virtual Instruction*  clone() const { return new LoadInst(*this); }
207   virtual const char*   getOpcodeName() const { return "load"; }  
208   virtual Value*        getPtrOperand() { return this->getOperand(0); }
209   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
210
211   // Methods for support type inquiry through isa, cast, and dyn_cast:
212   static inline bool classof(const LoadInst *) { return true; }
213   static inline bool classof(const Instruction *I) {
214     return (I->getOpcode() == Instruction::Load);
215   }
216   static inline bool classof(const Value *V) {
217     return isa<Instruction>(V) && classof(cast<Instruction>(V));
218   }
219 };
220
221
222 //===----------------------------------------------------------------------===//
223 //                                StoreInst Class
224 //===----------------------------------------------------------------------===//
225
226 class StoreInst : public MemAccessInst {
227   StoreInst(const StoreInst &SI) : MemAccessInst(SI.getType(), Store, SI.getIndexVec()) {
228     Operands.reserve(SI.Operands.size());
229     for (unsigned i = 0, E = SI.Operands.size(); i != E; ++i)
230       Operands.push_back(Use(SI.Operands[i], this));
231   }
232 public:
233   StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
234             const string &Name = "");
235   virtual Instruction *clone() const { return new StoreInst(*this); }
236   virtual const char *getOpcodeName() const { return "store"; }  
237   
238   virtual bool hasSideEffects() const { return true; }
239   virtual Value*        getPtrOperand() { return this->getOperand(1); }
240   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 2)? 2 : -1;}
241
242   // Methods for support type inquiry through isa, cast, and dyn_cast:
243   static inline bool classof(const StoreInst *) { return true; }
244   static inline bool classof(const Instruction *I) {
245     return (I->getOpcode() == Instruction::Store);
246   }
247   static inline bool classof(const Value *V) {
248     return isa<Instruction>(V) && classof(cast<Instruction>(V));
249   }
250 };
251
252
253 //===----------------------------------------------------------------------===//
254 //                             GetElementPtrInst Class
255 //===----------------------------------------------------------------------===//
256
257 class GetElementPtrInst : public MemAccessInst {
258   GetElementPtrInst(const GetElementPtrInst &EPI)
259     : MemAccessInst(EPI.getType(), GetElementPtr, EPI.getIndexVec()) {
260     Operands.reserve(EPI.Operands.size());
261     for (unsigned i = 0, E = EPI.Operands.size(); i != E; ++i)
262       Operands.push_back(Use(EPI.Operands[i], this));
263   }
264 public:
265   GetElementPtrInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
266                     const string &Name = "");
267   virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
268   virtual const char *getOpcodeName() const { return "getelementptr"; }  
269   virtual Value*        getPtrOperand() { return this->getOperand(0); }
270   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
271   
272   inline bool isArraySelector() const { return !isStructSelector(); }
273   bool isStructSelector() const;
274
275
276   // Methods for support type inquiry through isa, cast, and dyn_cast:
277   static inline bool classof(const GetElementPtrInst *) { return true; }
278   static inline bool classof(const Instruction *I) {
279     return (I->getOpcode() == Instruction::GetElementPtr);
280   }
281   static inline bool classof(const Value *V) {
282     return isa<Instruction>(V) && classof(cast<Instruction>(V));
283   }
284 };
285
286 #endif // LLVM_IMEMORY_H