Remove some gross stuff
[oota-llvm.git] / lib / VMCore / ConstantPool.cpp
1 //===-- iConstPool.cpp - Implement ConstPool instructions --------*- C++ -*--=//
2 //
3 // This file implements the ConstPool* classes...
4 //
5 //===----------------------------------------------------------------------===//
6
7 #define __STDC_LIMIT_MACROS           // Get defs for INT64_MAX and friends...
8 #include "llvm/ConstPoolVals.h"
9 #include "llvm/ConstantPool.h"
10 #include "llvm/Support/StringExtras.h"  // itostr
11 #include "llvm/DerivedTypes.h"
12 #include "llvm/SymbolTable.h"
13 #include <algorithm>
14 #include <assert.h>
15
16 //===----------------------------------------------------------------------===//
17 //                             ConstantPool Class
18 //===----------------------------------------------------------------------===//
19
20 void ConstantPool::setParent(SymTabValue *STV) {
21   Parent = STV;
22   for (unsigned i = 0; i < Planes.size(); i++)
23     Planes[i]->setParent(Parent);  
24 }
25
26 const Value *ConstantPool::getParentV() const { return Parent->getSTVParent(); }
27 Value *ConstantPool::getParentV() { return Parent->getSTVParent(); }
28
29
30
31 // Constant getPlane - Returns true if the type plane does not exist, otherwise
32 // updates the pointer to point to the correct plane.
33 //
34 bool ConstantPool::getPlane(const Type *T, const PlaneType *&Plane) const {
35   unsigned Ty = T->getUniqueID();
36   if (Ty >= Planes.size()) return true;
37   Plane = Planes[Ty];
38   return false;
39 }
40
41 // Constant getPlane - Returns true if the type plane does not exist, otherwise
42 // updates the pointer to point to the correct plane.
43 //
44 bool ConstantPool::getPlane(const Type *T, PlaneType *&Plane) {
45   unsigned Ty = T->getUniqueID();
46   if (Ty >= Planes.size()) return true;
47   Plane = Planes[Ty];
48   return false;
49 }
50
51 void ConstantPool::resize(unsigned size) {
52   unsigned oldSize = Planes.size();
53   Planes.resize(size, 0);
54   while (oldSize < size)
55     Planes[oldSize++] = new PlaneType(Parent, Parent);
56 }
57
58 ConstantPool::PlaneType &ConstantPool::getPlane(const Type *T) {
59   unsigned Ty = T->getUniqueID();
60   if (Ty >= Planes.size()) resize(Ty+1);
61   return *Planes[Ty];
62 }
63
64 // insert - Add constant into the symbol table...
65 void ConstantPool::insert(ConstPoolVal *N) {
66   unsigned Ty = N->getType()->getUniqueID();
67   if (Ty >= Planes.size()) resize(Ty+1);
68   Planes[Ty]->push_back(N);
69 }
70
71 bool ConstantPool::remove(ConstPoolVal *N) {
72   unsigned Ty = N->getType()->getUniqueID();
73   if (Ty >= Planes.size()) return true;     // Doesn't contain any of that type
74
75   PlaneType::iterator I = ::find(Planes[Ty]->begin(), Planes[Ty]->end(), N);
76   if (I == Planes[Ty]->end()) return true;
77   Planes[Ty]->remove(I);
78   return false;
79 }
80
81 void ConstantPool::delete_all() {
82   dropAllReferences();
83   for (unsigned i = 0; i < Planes.size(); i++) {
84     Planes[i]->delete_all();
85     Planes[i]->setParent(0);
86     delete Planes[i];
87   }
88   Planes.clear();
89 }
90
91 void ConstantPool::dropAllReferences() {
92   for (unsigned i = 0; i < Planes.size(); i++)
93     for_each(Planes[i]->begin(), Planes[i]->end(),
94              mem_fun(&ConstPoolVal::dropAllReferences));
95 }
96
97 struct EqualsConstant {
98   const ConstPoolVal *v;
99   inline EqualsConstant(const ConstPoolVal *V) { v = V; }
100   inline bool operator()(const ConstPoolVal *V) const {
101     return v->equals(V);
102   }
103 };
104
105
106 ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) {
107   const PlaneType *P;
108   if (getPlane(V->getType(), P)) return 0;
109   PlaneType::const_iterator PI = find_if(P->begin(), P->end(), 
110                                          EqualsConstant(V));
111   if (PI == P->end()) return 0;
112   return *PI;
113 }
114
115 const ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) const {
116   const PlaneType *P;
117   if (getPlane(V->getType(), P)) return 0;
118   PlaneType::const_iterator PI = find_if(P->begin(), P->end(), 
119                                          EqualsConstant(V));
120   if (PI == P->end()) return 0;
121   return *PI;
122 }
123
124 ConstPoolVal *ConstantPool::find(const Type *Ty) {
125   const PlaneType *P;
126   if (getPlane(Type::TypeTy, P)) return 0;
127
128   // TODO: This is kinda silly
129   ConstPoolType V(Ty);
130
131   PlaneType::const_iterator PI = 
132     find_if(P->begin(), P->end(), EqualsConstant(&V));
133   if (PI == P->end()) return 0;
134   return *PI;
135 }
136
137 const ConstPoolVal *ConstantPool::find(const Type *Ty) const {
138   const PlaneType *P;
139   if (getPlane(Type::TypeTy, P)) return 0;
140
141   // TODO: This is kinda silly
142   ConstPoolType V(Ty);
143
144   PlaneType::const_iterator PI = 
145     find_if(P->begin(), P->end(), EqualsConstant(&V));
146   if (PI == P->end()) return 0;
147   return *PI;
148 }
149
150 struct EqualsType {
151   const Type *T;
152   inline EqualsType(const Type *t) { T = t; }
153   inline bool operator()(const ConstPoolVal *CPV) const {
154     return static_cast<const ConstPoolType*>(CPV)->getValue() == T;
155   }
156 };
157
158 // ensureTypeAvailable - This is used to make sure that the specified type is
159 // in the constant pool.  If it is not already in the constant pool, it is
160 // added.
161 //
162 const Type *ConstantPool::ensureTypeAvailable(const Type *Ty) {
163   // Get the type type plane...
164   PlaneType &P = getPlane(Type::TypeTy);
165   PlaneType::const_iterator PI = find_if(P.begin(), P.end(), EqualsType(Ty));
166                                          
167   if (PI == P.end()) {
168     ConstPoolVal *CPT = new ConstPoolType(Ty);
169     insert(CPT);
170   }
171   return Ty;
172 }
173
174 //===----------------------------------------------------------------------===//
175 //                              ConstPoolVal Class
176 //===----------------------------------------------------------------------===//
177
178 // Specialize setName to take care of symbol table majik
179 void ConstPoolVal::setName(const string &name) {
180   SymTabValue *P;
181   if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
182   Value::setName(name);
183   if (P && hasName()) P->getSymbolTable()->insert(this);
184 }
185
186 // Static constructor to create a '0' constant of arbitrary type...
187 ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
188   switch (Ty->getPrimitiveID()) {
189   case Type::BoolTyID:   return new ConstPoolBool(false);
190   case Type::SByteTyID:
191   case Type::ShortTyID:
192   case Type::IntTyID:
193   case Type::LongTyID:   return new ConstPoolSInt(Ty, 0);
194
195   case Type::UByteTyID:
196   case Type::UShortTyID:
197   case Type::UIntTyID:
198   case Type::ULongTyID:  return new ConstPoolUInt(Ty, 0);
199
200   case Type::FloatTyID:
201   case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
202   default:
203     return 0;
204   }
205 }
206
207
208
209 //===----------------------------------------------------------------------===//
210 //                            ConstPoolXXX Classes
211 //===----------------------------------------------------------------------===//
212
213 //===----------------------------------------------------------------------===//
214 //                             Normal Constructors
215
216 ConstPoolBool::ConstPoolBool(bool V, const string &Name = "") 
217   : ConstPoolVal(Type::BoolTy, Name) {
218   Val = V;
219 }
220 ConstPoolBool::ConstPoolBool(const Type *Ty, bool V, const string &Name = "") 
221   : ConstPoolVal(Type::BoolTy, Name) {
222   Val = V;
223   assert(Ty == Type::BoolTy && "BoolTy is only valid type for bool constant");
224 }
225
226 ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V, const string &Name)
227   : ConstPoolVal(Ty, Name) { Val.Unsigned = V; }
228 ConstPoolInt::ConstPoolInt(const Type *Ty, int64_t V, const string &Name)
229   : ConstPoolVal(Ty, Name) { Val.Signed = V; }
230
231 ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
232   : ConstPoolInt(Ty, V, Name) {
233   //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
234   assert(isValueValidForType(Ty, V) && "Value too large for type!");
235 }
236
237 ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
238   : ConstPoolInt(Ty, V, Name) {
239   //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
240   assert(isValueValidForType(Ty, V) && "Value too large for type!");
241 }
242
243 ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
244   : ConstPoolVal(Ty, Name) {
245   assert(isValueValidForType(Ty, V) && "Value too large for type!");
246   Val = V;
247 }
248
249 ConstPoolType::ConstPoolType(const Type *V, const string &Name) 
250   : ConstPoolVal(Type::TypeTy, Name), Val(V) {
251 }
252
253 ConstPoolArray::ConstPoolArray(const ArrayType *T, 
254                                vector<ConstPoolVal*> &V, 
255                                const string &Name)
256   : ConstPoolVal(T, Name) {
257   for (unsigned i = 0; i < V.size(); i++) {
258     assert(V[i]->getType() == T->getElementType());
259     Operands.push_back(Use(V[i], this));
260   }
261 }
262
263 ConstPoolStruct::ConstPoolStruct(const StructType *T, 
264                                  vector<ConstPoolVal*> &V, 
265                                  const string &Name)
266   : ConstPoolVal(T, Name) {
267   const StructType::ElementTypes &ETypes = T->getElementTypes();
268
269   for (unsigned i = 0; i < V.size(); i++) {
270     assert(V[i]->getType() == ETypes[i]);
271     Operands.push_back(Use(V[i], this));
272   }
273 }
274
275
276 //===----------------------------------------------------------------------===//
277 //                               Copy Constructors
278
279 ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
280   : ConstPoolVal(Type::BoolTy) {
281   Val = CPB.Val;
282 }
283
284 ConstPoolInt::ConstPoolInt(const ConstPoolInt &CPI)
285   : ConstPoolVal(CPI.getType()) {
286   Val.Signed = CPI.Val.Signed;
287 }
288
289 ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
290   : ConstPoolVal(CPFP.getType()) {
291   Val = CPFP.Val;
292 }
293
294 ConstPoolType::ConstPoolType(const ConstPoolType &CPT) 
295   : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
296 }
297
298 ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
299   : ConstPoolVal(CPA.getType()) {
300   for (unsigned i = 0; i < CPA.Operands.size(); i++)
301     Operands.push_back(Use(CPA.Operands[i], this));
302 }
303
304 ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
305   : ConstPoolVal(CPS.getType()) {
306   for (unsigned i = 0; i < CPS.Operands.size(); i++)
307     Operands.push_back(Use(CPS.Operands[i], this));
308 }
309
310 //===----------------------------------------------------------------------===//
311 //                          getStrValue implementations
312
313 string ConstPoolBool::getStrValue() const {
314   return Val ? "true" : "false";
315 }
316
317 string ConstPoolSInt::getStrValue() const {
318   return itostr(Val.Signed);
319 }
320
321 string ConstPoolUInt::getStrValue() const {
322   return utostr(Val.Unsigned);
323 }
324
325 string ConstPoolFP::getStrValue() const {
326   return ftostr(Val);
327 }
328
329 string ConstPoolType::getStrValue() const {
330   return Val->getName();
331 }
332
333 string ConstPoolArray::getStrValue() const {
334   string Result = "[";
335   if (Operands.size()) {
336     Result += " " + Operands[0]->getType()->getName() + 
337               " " + Operands[0]->castConstantAsserting()->getStrValue();
338     for (unsigned i = 1; i < Operands.size(); i++)
339       Result += ", " + Operands[i]->getType()->getName() + 
340                  " " + Operands[i]->castConstantAsserting()->getStrValue();
341   }
342
343   return Result + " ]";
344 }
345
346 string ConstPoolStruct::getStrValue() const {
347   string Result = "{";
348   if (Operands.size()) {
349     Result += " " + Operands[0]->getType()->getName() + 
350               " " + Operands[0]->castConstantAsserting()->getStrValue();
351     for (unsigned i = 1; i < Operands.size(); i++)
352       Result += ", " + Operands[i]->getType()->getName() + 
353                  " " + Operands[i]->castConstantAsserting()->getStrValue();
354   }
355
356   return Result + " }";
357 }
358
359 //===----------------------------------------------------------------------===//
360 //                             equals implementations
361
362 bool ConstPoolBool::equals(const ConstPoolVal *V) const {
363   assert(getType() == V->getType());
364   return ((ConstPoolBool*)V)->getValue() == Val;
365 }
366
367 bool ConstPoolInt::equals(const ConstPoolVal *V) const {
368   assert(getType() == V->getType());
369   return ((ConstPoolInt*)V)->Val.Signed == Val.Signed;
370 }
371
372 bool ConstPoolFP::equals(const ConstPoolVal *V) const {
373   assert(getType() == V->getType());
374   return ((ConstPoolFP*)V)->getValue() == Val;
375 }
376
377 bool ConstPoolType::equals(const ConstPoolVal *V) const {
378   assert(getType() == V->getType());
379   return ((ConstPoolType*)V)->getValue() == Val;
380 }
381
382 bool ConstPoolArray::equals(const ConstPoolVal *V) const {
383   assert(getType() == V->getType());
384   ConstPoolArray *AV = (ConstPoolArray*)V;
385   if (Operands.size() != AV->Operands.size()) return false;
386   for (unsigned i = 0; i < Operands.size(); i++)
387     if (!Operands[i]->castConstantAsserting()->equals(
388                AV->Operands[i]->castConstantAsserting()))
389       return false;
390
391   return true;
392 }
393
394 bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
395   assert(getType() == V->getType());
396   ConstPoolStruct *SV = (ConstPoolStruct*)V;
397   if (Operands.size() != SV->Operands.size()) return false;
398   for (unsigned i = 0; i < Operands.size(); i++)
399     if (!Operands[i]->castConstantAsserting()->equals(
400            SV->Operands[i]->castConstantAsserting()))
401       return false;
402
403   return true;
404 }
405
406 //===----------------------------------------------------------------------===//
407 //                      isValueValidForType implementations
408
409 bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
410   switch (Ty->getPrimitiveID()) {
411   default:
412     return false;         // These can't be represented as integers!!!
413
414     // Signed types...
415   case Type::SByteTyID:
416     return (Val <= INT8_MAX && Val >= INT8_MIN);
417   case Type::ShortTyID:
418     return (Val <= INT16_MAX && Val >= INT16_MIN);
419   case Type::IntTyID:
420     return (Val <= INT32_MAX && Val >= INT32_MIN);
421   case Type::LongTyID:
422     return true;          // This is the largest type...
423   }
424   assert(0 && "WTF?");
425   return false;
426 }
427
428 bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
429   switch (Ty->getPrimitiveID()) {
430   default:
431     return false;         // These can't be represented as integers!!!
432
433     // Unsigned types...
434   case Type::UByteTyID:
435     return (Val <= UINT8_MAX);
436   case Type::UShortTyID:
437     return (Val <= UINT16_MAX);
438   case Type::UIntTyID:
439     return (Val <= UINT32_MAX);
440   case Type::ULongTyID:
441     return true;          // This is the largest type...
442   }
443   assert(0 && "WTF?");
444   return false;
445 }
446
447 bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
448   switch (Ty->getPrimitiveID()) {
449   default:
450     return false;         // These can't be represented as floating point!
451
452     // TODO: Figure out how to test if a double can be cast to a float!
453   case Type::FloatTyID:
454     /*
455     return (Val <= UINT8_MAX);
456     */
457   case Type::DoubleTyID:
458     return true;          // This is the largest type...
459   }
460 };
461
462
463 //===----------------------------------------------------------------------===//
464 //                      Extra Method implementations
465
466 ConstPoolInt *ConstPoolInt::get(const Type *Ty, unsigned char V) {
467   assert(V <= 127 && "equals: Can only be used with very small constants!");
468   if (Ty->isSigned()) return new ConstPoolSInt(Ty, V);
469   return new ConstPoolUInt(Ty, V);
470 }