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