f3ec30281da95dc5000f64271cefa9b0502e7d9e
[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[0].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[0].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*> &getIndices() const { return indexVec; }
186
187   inline bool hasIndices() const { return !indexVec.empty(); }
188   
189   virtual Value *getPtrOperand() = 0;
190   
191   virtual int getFirstOffsetIdx() const = 0;
192 };
193
194
195 //===----------------------------------------------------------------------===//
196 //                                LoadInst Class
197 //===----------------------------------------------------------------------===//
198
199 class LoadInst : public MemAccessInst {
200   LoadInst(const LoadInst &LI) : MemAccessInst(LI.getType(), Load,
201                                                LI.getIndices()) {
202     Operands.reserve(LI.Operands.size());
203     for (unsigned i = 0, E = LI.Operands.size(); i != E; ++i)
204       Operands.push_back(Use(LI.Operands[i], this));
205   }
206 public:
207   LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
208            const string &Name = "");
209   LoadInst(Value *Ptr, const string &Name = "");
210
211   virtual Instruction *clone() const { return new LoadInst(*this); }
212   virtual const char *getOpcodeName() const { return "load"; }  
213   virtual Value *getPtrOperand() { return this->getOperand(0); }
214   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1; }
215
216   // Methods for support type inquiry through isa, cast, and dyn_cast:
217   static inline bool classof(const LoadInst *) { return true; }
218   static inline bool classof(const Instruction *I) {
219     return (I->getOpcode() == Instruction::Load);
220   }
221   static inline bool classof(const Value *V) {
222     return isa<Instruction>(V) && classof(cast<Instruction>(V));
223   }
224 };
225
226
227 //===----------------------------------------------------------------------===//
228 //                                StoreInst Class
229 //===----------------------------------------------------------------------===//
230
231 class StoreInst : public MemAccessInst {
232   StoreInst(const StoreInst &SI) : MemAccessInst(SI.getType(), Store,
233                                                  SI.getIndices()) {
234     Operands.reserve(SI.Operands.size());
235     for (unsigned i = 0, E = SI.Operands.size(); i != E; ++i)
236       Operands.push_back(Use(SI.Operands[i], this));
237   }
238 public:
239   StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
240             const string &Name = "");
241   StoreInst(Value *Val, Value *Ptr, const string &Name = "");
242   virtual Instruction *clone() const { return new StoreInst(*this); }
243
244   virtual const char *getOpcodeName() const { return "store"; }  
245   
246   virtual bool hasSideEffects() const { return true; }
247   virtual Value *getPtrOperand() { return this->getOperand(1); }
248   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 2)? 2 : -1;}
249
250   // Methods for support type inquiry through isa, cast, and dyn_cast:
251   static inline bool classof(const StoreInst *) { return true; }
252   static inline bool classof(const Instruction *I) {
253     return (I->getOpcode() == Instruction::Store);
254   }
255   static inline bool classof(const Value *V) {
256     return isa<Instruction>(V) && classof(cast<Instruction>(V));
257   }
258 };
259
260
261 //===----------------------------------------------------------------------===//
262 //                             GetElementPtrInst Class
263 //===----------------------------------------------------------------------===//
264
265 class GetElementPtrInst : public MemAccessInst {
266   GetElementPtrInst(const GetElementPtrInst &EPI)
267     : MemAccessInst(EPI.getType(), GetElementPtr, EPI.getIndices()) {
268     Operands.reserve(EPI.Operands.size());
269     for (unsigned i = 0, E = EPI.Operands.size(); i != E; ++i)
270       Operands.push_back(Use(EPI.Operands[i], this));
271   }
272 public:
273   GetElementPtrInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
274                     const string &Name = "");
275   virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
276   virtual const char *getOpcodeName() const { return "getelementptr"; }  
277   virtual Value *getPtrOperand() { return this->getOperand(0); }
278   virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
279   
280   inline bool isArraySelector() const { return !isStructSelector(); }
281   bool isStructSelector() const;
282
283   // getType - Overload to return most specific pointer type...
284   inline const PointerType *getType() const {
285     return cast<const PointerType>(Instruction::getType());
286   }
287
288   // Methods for support type inquiry through isa, cast, and dyn_cast:
289   static inline bool classof(const GetElementPtrInst *) { return true; }
290   static inline bool classof(const Instruction *I) {
291     return (I->getOpcode() == Instruction::GetElementPtr);
292   }
293   static inline bool classof(const Value *V) {
294     return isa<Instruction>(V) && classof(cast<Instruction>(V));
295   }
296 };
297
298 #endif // LLVM_IMEMORY_H