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