bug 122:
[oota-llvm.git] / lib / VMCore / iMemory.cpp
1 //===-- iMemory.cpp - Implement Memory instructions -----------------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the various memory related classes defined in iMemory.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/iMemory.h"
15 #include "llvm/Constants.h"
16 #include "llvm/DerivedTypes.h"
17 using namespace llvm;
18
19 void AllocationInst::init(const Type *Ty, Value *ArraySize, unsigned iTy) {
20   // ArraySize defaults to 1.
21   if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1);
22
23   Operands.reserve(1);
24   assert(ArraySize->getType() == Type::UIntTy &&
25          "Malloc/Allocation array size != UIntTy!");
26
27   Operands.push_back(Use(ArraySize, this));
28 }
29
30 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
31                                const std::string &Name,
32                                Instruction *InsertBefore)
33   : Instruction(PointerType::get(Ty), iTy, Name, InsertBefore) {
34   init(Ty, ArraySize, iTy);
35 }
36
37 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
38                                const std::string &Name,
39                                BasicBlock *InsertAtEnd)
40   : Instruction(PointerType::get(Ty), iTy, Name, InsertAtEnd) {
41   init(Ty, ArraySize, iTy);
42 }
43
44 bool AllocationInst::isArrayAllocation() const {
45   return getOperand(0) != ConstantUInt::get(Type::UIntTy, 1);
46 }
47
48 const Type *AllocationInst::getAllocatedType() const {
49   return getType()->getElementType();
50 }
51
52 AllocaInst::AllocaInst(const AllocaInst &AI)
53   : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
54                    Instruction::Alloca) {
55 }
56
57 MallocInst::MallocInst(const MallocInst &MI)
58   : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
59                    Instruction::Malloc) {
60 }
61
62 //===----------------------------------------------------------------------===//
63 //                             FreeInst Implementation
64 //===----------------------------------------------------------------------===//
65
66 void FreeInst::init(Value *Ptr)
67 {
68   assert(Ptr && isa<PointerType>(Ptr->getType()) && "Can't free nonpointer!");
69   Operands.reserve(1);
70   Operands.push_back(Use(Ptr, this));
71 }
72
73 FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore)
74   : Instruction(Type::VoidTy, Free, "", InsertBefore) {
75   init(Ptr);
76 }
77
78 FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd)
79   : Instruction(Type::VoidTy, Free, "", InsertAtEnd) {
80   init(Ptr);
81 }
82
83
84 //===----------------------------------------------------------------------===//
85 //                           LoadInst Implementation
86 //===----------------------------------------------------------------------===//
87
88 void LoadInst::init(Value *Ptr) {
89   assert(Ptr && isa<PointerType>(Ptr->getType()) && 
90          "Ptr must have pointer type.");
91   Operands.reserve(1);
92   Operands.push_back(Use(Ptr, this));
93 }
94
95 LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
96   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
97                 Load, Name, InsertBef), Volatile(false) {
98   init(Ptr);
99 }
100
101 LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
102   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
103                 Load, Name, InsertAE), Volatile(false) {
104   init(Ptr);
105 }
106
107 LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
108                    Instruction *InsertBef)
109   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
110                 Load, Name, InsertBef), Volatile(isVolatile) {
111   init(Ptr);
112 }
113
114 LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
115                    BasicBlock *InsertAE)
116   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
117                 Load, Name, InsertAE), Volatile(isVolatile) {
118   init(Ptr);
119 }
120
121
122 //===----------------------------------------------------------------------===//
123 //                           StoreInst Implementation
124 //===----------------------------------------------------------------------===//
125
126 StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore)
127   : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(false) {
128   init(Val, Ptr);
129 }
130
131 StoreInst::StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd)
132   : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(false) {
133   init(Val, Ptr);
134 }
135
136 StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, 
137                      Instruction *InsertBefore)
138   : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) {
139   init(Val, Ptr);
140 }
141
142 StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, 
143                      BasicBlock *InsertAtEnd)
144   : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(isVolatile) {
145   init(Val, Ptr);
146 }
147
148 void StoreInst::init(Value *Val, Value *Ptr) {
149   assert(isa<PointerType>(Ptr->getType()) &&
150          Val->getType() == cast<PointerType>(Ptr->getType())->getElementType()
151          && "Ptr must have pointer type.");
152
153   Operands.reserve(2);
154   Operands.push_back(Use(Val, this));
155   Operands.push_back(Use(Ptr, this));
156 }
157
158 //===----------------------------------------------------------------------===//
159 //                       GetElementPtrInst Implementation
160 //===----------------------------------------------------------------------===//
161
162 // checkType - Simple wrapper function to give a better assertion failure
163 // message on bad indexes for a gep instruction.
164 //
165 static inline const Type *checkType(const Type *Ty) {
166   assert(Ty && "Invalid indices for type!");
167   return Ty;
168 }
169
170 void GetElementPtrInst::init(Value *Ptr, const std::vector<Value*> &Idx)
171 {
172   Operands.reserve(1+Idx.size());
173   Operands.push_back(Use(Ptr, this));
174
175   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
176     Operands.push_back(Use(Idx[i], this));
177 }
178
179 void GetElementPtrInst::init(Value *Ptr, Value *Idx0, Value *Idx1) {
180   Operands.reserve(3);
181   Operands.push_back(Use(Ptr, this));
182   Operands.push_back(Use(Idx0, this));
183   Operands.push_back(Use(Idx1, this));
184 }
185
186 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
187                                      const std::string &Name, Instruction *InBe)
188   : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
189                                                           Idx, true))),
190                 GetElementPtr, Name, InBe) {
191   init(Ptr, Idx);
192 }
193
194 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
195                                      const std::string &Name, BasicBlock *IAE)
196   : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
197                                                           Idx, true))),
198                 GetElementPtr, Name, IAE) {
199   init(Ptr, Idx);
200 }
201
202 GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
203                                      const std::string &Name, Instruction *InBe)
204   : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
205                                                           Idx0, Idx1, true))),
206                 GetElementPtr, Name, InBe) {
207   init(Ptr, Idx0, Idx1);
208 }
209
210 GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
211                                      const std::string &Name, BasicBlock *IAE)
212   : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
213                                                           Idx0, Idx1, true))),
214                 GetElementPtr, Name, IAE) {
215   init(Ptr, Idx0, Idx1);
216 }
217
218 // getIndexedType - Returns the type of the element that would be loaded with
219 // a load instruction with the specified parameters.
220 //
221 // A null type is returned if the indices are invalid for the specified 
222 // pointer type.
223 //
224 const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, 
225                                               const std::vector<Value*> &Idx,
226                                               bool AllowCompositeLeaf) {
227   if (!isa<PointerType>(Ptr)) return 0;   // Type isn't a pointer type!
228
229   // Handle the special case of the empty set index set...
230   if (Idx.empty())
231     if (AllowCompositeLeaf ||
232         cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
233       return cast<PointerType>(Ptr)->getElementType();
234     else
235       return 0;
236  
237   unsigned CurIdx = 0;
238   while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
239     if (Idx.size() == CurIdx) {
240       if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr;
241       return 0;   // Can't load a whole structure or array!?!?
242     }
243
244     Value *Index = Idx[CurIdx++];
245     if (isa<PointerType>(CT) && CurIdx != 1)
246       return 0;  // Can only index into pointer types at the first index!
247     if (!CT->indexValid(Index)) return 0;
248     Ptr = CT->getTypeAtIndex(Index);
249
250     // If the new type forwards to another type, then it is in the middle
251     // of being refined to another type (and hence, may have dropped all
252     // references to what it was using before).  So, use the new forwarded
253     // type.
254     if (const Type * Ty = Ptr->getForwardedType()) {
255       Ptr = Ty;
256     }
257   }
258   return CurIdx == Idx.size() ? Ptr : 0;
259 }
260
261 const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, 
262                                               Value *Idx0, Value *Idx1,
263                                               bool AllowCompositeLeaf) {
264   const PointerType *PTy = dyn_cast<PointerType>(Ptr);
265   if (!PTy) return 0;   // Type isn't a pointer type!
266
267   // Check the pointer index.
268   if (!PTy->indexValid(Idx0)) return 0;
269
270   const CompositeType *CT = dyn_cast<CompositeType>(PTy->getElementType());
271   if (!CT || !CT->indexValid(Idx1)) return 0;
272
273   const Type *ElTy = CT->getTypeAtIndex(Idx1);
274   if (AllowCompositeLeaf || ElTy->isFirstClassType())
275     return ElTy;
276   return 0;
277 }