Rename file to be consistent with header name
[oota-llvm.git] / lib / VMCore / ConstPoolVals.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/Support/StringExtras.h"  // itostr
10 #include "llvm/DerivedTypes.h"
11 #include "llvm/SymbolTable.h"
12 #include <algorithm>
13 #include <assert.h>
14
15 ConstPoolBool *ConstPoolBool::True  = new ConstPoolBool(true);
16 ConstPoolBool *ConstPoolBool::False = new ConstPoolBool(false);
17
18
19 //===----------------------------------------------------------------------===//
20 //                              ConstPoolVal Class
21 //===----------------------------------------------------------------------===//
22
23 // Specialize setName to take care of symbol table majik
24 void ConstPoolVal::setName(const string &Name, SymbolTable *ST) {
25   assert(ST && "Type::setName - Must provide symbol table argument!");
26
27   if (Name.size()) ST->insert(Name, this);
28 }
29
30 // Static constructor to create a '0' constant of arbitrary type...
31 ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
32   switch (Ty->getPrimitiveID()) {
33   case Type::BoolTyID:   return ConstPoolBool::get(false);
34   case Type::SByteTyID:
35   case Type::ShortTyID:
36   case Type::IntTyID:
37   case Type::LongTyID:   return ConstPoolSInt::get(Ty, 0);
38
39   case Type::UByteTyID:
40   case Type::UShortTyID:
41   case Type::UIntTyID:
42   case Type::ULongTyID:  return ConstPoolUInt::get(Ty, 0);
43
44   case Type::FloatTyID:
45   case Type::DoubleTyID: return ConstPoolFP::get(Ty, 0);
46   default:
47     return 0;
48   }
49 }
50
51
52
53 //===----------------------------------------------------------------------===//
54 //                            ConstPoolXXX Classes
55 //===----------------------------------------------------------------------===//
56
57 //===----------------------------------------------------------------------===//
58 //                             Normal Constructors
59
60 ConstPoolBool::ConstPoolBool(bool V) : ConstPoolVal(Type::BoolTy) {
61   Val = V;
62 }
63
64 ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V) : ConstPoolVal(Ty) {
65   Val.Unsigned = V;
66 }
67
68 ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V) : ConstPoolInt(Ty, V) {
69   assert(isValueValidForType(Ty, V) && "Value too large for type!");
70 }
71
72 ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V) : ConstPoolInt(Ty, V) {
73   assert(isValueValidForType(Ty, V) && "Value too large for type!");
74 }
75
76 ConstPoolFP::ConstPoolFP(const Type *Ty, double V) : ConstPoolVal(Ty) {
77   assert(isValueValidForType(Ty, V) && "Value too large for type!");
78   Val = V;
79 }
80
81 ConstPoolArray::ConstPoolArray(const ArrayType *T,
82                                const vector<ConstPoolVal*> &V)
83   : ConstPoolVal(T) {
84   for (unsigned i = 0; i < V.size(); i++) {
85     assert(V[i]->getType() == T->getElementType());
86     Operands.push_back(Use(V[i], this));
87   }
88 }
89
90 ConstPoolStruct::ConstPoolStruct(const StructType *T,
91                                  const vector<ConstPoolVal*> &V)
92   : ConstPoolVal(T) {
93   const StructType::ElementTypes &ETypes = T->getElementTypes();
94   
95   for (unsigned i = 0; i < V.size(); i++) {
96     assert(V[i]->getType() == ETypes[i]);
97     Operands.push_back(Use(V[i], this));
98   }
99 }
100
101
102 //===----------------------------------------------------------------------===//
103 //                          getStrValue implementations
104
105 string ConstPoolBool::getStrValue() const {
106   return Val ? "true" : "false";
107 }
108
109 string ConstPoolSInt::getStrValue() const {
110   return itostr(Val.Signed);
111 }
112
113 string ConstPoolUInt::getStrValue() const {
114   return utostr(Val.Unsigned);
115 }
116
117 string ConstPoolFP::getStrValue() const {
118   return ftostr(Val);
119 }
120
121 string ConstPoolArray::getStrValue() const {
122   string Result = "[";
123   if (Operands.size()) {
124     Result += " " + Operands[0]->getType()->getDescription() + 
125               " " + Operands[0]->castConstantAsserting()->getStrValue();
126     for (unsigned i = 1; i < Operands.size(); i++)
127       Result += ", " + Operands[i]->getType()->getDescription() + 
128                  " " + Operands[i]->castConstantAsserting()->getStrValue();
129   }
130
131   return Result + " ]";
132 }
133
134 string ConstPoolStruct::getStrValue() const {
135   string Result = "{";
136   if (Operands.size()) {
137     Result += " " + Operands[0]->getType()->getDescription() + 
138               " " + Operands[0]->castConstantAsserting()->getStrValue();
139     for (unsigned i = 1; i < Operands.size(); i++)
140       Result += ", " + Operands[i]->getType()->getDescription() + 
141                  " " + Operands[i]->castConstantAsserting()->getStrValue();
142   }
143
144   return Result + " }";
145 }
146
147 //===----------------------------------------------------------------------===//
148 //                      isValueValidForType implementations
149
150 bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
151   switch (Ty->getPrimitiveID()) {
152   default:
153     return false;         // These can't be represented as integers!!!
154
155     // Signed types...
156   case Type::SByteTyID:
157     return (Val <= INT8_MAX && Val >= INT8_MIN);
158   case Type::ShortTyID:
159     return (Val <= INT16_MAX && Val >= INT16_MIN);
160   case Type::IntTyID:
161     return (Val <= INT32_MAX && Val >= INT32_MIN);
162   case Type::LongTyID:
163     return true;          // This is the largest type...
164   }
165   assert(0 && "WTF?");
166   return false;
167 }
168
169 bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
170   switch (Ty->getPrimitiveID()) {
171   default:
172     return false;         // These can't be represented as integers!!!
173
174     // Unsigned types...
175   case Type::UByteTyID:
176     return (Val <= UINT8_MAX);
177   case Type::UShortTyID:
178     return (Val <= UINT16_MAX);
179   case Type::UIntTyID:
180     return (Val <= UINT32_MAX);
181   case Type::ULongTyID:
182     return true;          // This is the largest type...
183   }
184   assert(0 && "WTF?");
185   return false;
186 }
187
188 bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
189   switch (Ty->getPrimitiveID()) {
190   default:
191     return false;         // These can't be represented as floating point!
192
193     // TODO: Figure out how to test if a double can be cast to a float!
194   case Type::FloatTyID:
195     /*
196     return (Val <= UINT8_MAX);
197     */
198   case Type::DoubleTyID:
199     return true;          // This is the largest type...
200   }
201 };
202
203 //===----------------------------------------------------------------------===//
204 //                      Hash Function Implementations
205 #if 0
206 unsigned ConstPoolSInt::hash(const Type *Ty, int64_t V) {
207   return unsigned(Ty->getPrimitiveID() ^ V);
208 }
209
210 unsigned ConstPoolUInt::hash(const Type *Ty, uint64_t V) {
211   return unsigned(Ty->getPrimitiveID() ^ V);
212 }
213
214 unsigned ConstPoolFP::hash(const Type *Ty, double V) {
215   return Ty->getPrimitiveID() ^ unsigned(V);
216 }
217
218 unsigned ConstPoolArray::hash(const ArrayType *Ty,
219                               const vector<ConstPoolVal*> &V) {
220   unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
221   for (unsigned i = 0; i < V.size(); ++i)
222     Result ^= V[i]->getHash() << (i & 7);
223   return Result;
224 }
225
226 unsigned ConstPoolStruct::hash(const StructType *Ty,
227                                const vector<ConstPoolVal*> &V) {
228   unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
229   for (unsigned i = 0; i < V.size(); ++i)
230     Result ^= V[i]->getHash() << (i & 7);
231   return Result;
232 }
233 #endif
234
235 //===----------------------------------------------------------------------===//
236 //                      Factory Function Implementation
237
238 template<class ValType, class ConstPoolClass>
239 struct ValueMap {
240   typedef pair<const Type*, ValType> ConstHashKey;
241   map<ConstHashKey, ConstPoolClass *> Map;
242
243   inline ConstPoolClass *get(const Type *Ty, ValType V) {
244     map<ConstHashKey,ConstPoolClass *>::iterator I =
245       Map.find(ConstHashKey(Ty, V));
246     return (I != Map.end()) ? I->second : 0;
247   }
248
249   inline void add(const Type *Ty, ValType V, ConstPoolClass *CP) {
250     Map.insert(make_pair(ConstHashKey(Ty, V), CP));
251   }
252 };
253
254 //---- ConstPoolUInt::get() and ConstPoolSInt::get() implementations...
255 //
256 static ValueMap<uint64_t, ConstPoolInt> IntConstants;
257
258 ConstPoolSInt *ConstPoolSInt::get(const Type *Ty, int64_t V) {
259   ConstPoolSInt *Result = (ConstPoolSInt*)IntConstants.get(Ty, (uint64_t)V);
260   if (!Result)   // If no preexisting value, create one now...
261     IntConstants.add(Ty, V, Result = new ConstPoolSInt(Ty, V));
262   return Result;
263 }
264
265 ConstPoolUInt *ConstPoolUInt::get(const Type *Ty, uint64_t V) {
266   ConstPoolUInt *Result = (ConstPoolUInt*)IntConstants.get(Ty, V);
267   if (!Result)   // If no preexisting value, create one now...
268     IntConstants.add(Ty, V, Result = new ConstPoolUInt(Ty, V));
269   return Result;
270 }
271
272 ConstPoolInt *ConstPoolInt::get(const Type *Ty, unsigned char V) {
273   assert(V <= 127 && "Can only be used with very small positive constants!");
274   if (Ty->isSigned()) return ConstPoolSInt::get(Ty, V);
275   return ConstPoolUInt::get(Ty, V);
276 }
277
278 //---- ConstPoolFP::get() implementation...
279 //
280 static ValueMap<double, ConstPoolFP> FPConstants;
281
282 ConstPoolFP *ConstPoolFP::get(const Type *Ty, double V) {
283   ConstPoolFP *Result = FPConstants.get(Ty, V);
284   if (!Result)   // If no preexisting value, create one now...
285     FPConstants.add(Ty, V, Result = new ConstPoolFP(Ty, V));
286   return Result;
287 }
288
289 //---- ConstPoolArray::get() implementation...
290 //
291 static ValueMap<vector<ConstPoolVal*>, ConstPoolArray> ArrayConstants;
292
293 ConstPoolArray *ConstPoolArray::get(const ArrayType *Ty,
294                                     const vector<ConstPoolVal*> &V) {
295   ConstPoolArray *Result = ArrayConstants.get(Ty, V);
296   if (!Result)   // If no preexisting value, create one now...
297     ArrayConstants.add(Ty, V, Result = new ConstPoolArray(Ty, V));
298   return Result;
299 }
300
301 //---- ConstPoolStruct::get() implementation...
302 //
303 static ValueMap<vector<ConstPoolVal*>, ConstPoolStruct> StructConstants;
304
305 ConstPoolStruct *ConstPoolStruct::get(const StructType *Ty,
306                                       const vector<ConstPoolVal*> &V) {
307   ConstPoolStruct *Result = StructConstants.get(Ty, V);
308   if (!Result)   // If no preexisting value, create one now...
309     StructConstants.add(Ty, V, Result = new ConstPoolStruct(Ty, V));
310   return Result;
311 }
312
313
314
315
316 //===----------------------------------------------------------------------===//
317 //                      Extra Method implementations
318
319
320
321
322
323
324 // Convenience functions to get the value of an integer constant, for an
325 // appropriate integer or non-integer type that can be held in an integer.
326 // The type of the argument must be the following:
327 //   GetSignedIntConstantValue:   signed integer or bool
328 //   GetUnsignedIntConstantValue: unsigned integer, bool, or pointer
329 //   GetConstantValueAsSignedInt: any of the above, but the value
330 //                                must fit into a int64_t.
331 // 
332 // isValidConstant is set to true if a valid constant was found.
333 // 
334 int64_t
335 GetSignedIntConstantValue(const Value* val, bool& isValidConstant)
336 {
337   int64_t intValue = 0;
338   isValidConstant = false;
339   
340   if (val->getValueType() == Value::ConstantVal)
341     {
342       switch(val->getType()->getPrimitiveID())
343         {
344         case Type::BoolTyID:
345           intValue = ((ConstPoolBool*) val)->getValue()? 1 : 0;
346           isValidConstant = true;
347           break;
348         case Type::SByteTyID:
349         case Type::ShortTyID:
350         case Type::IntTyID:
351         case Type::LongTyID:
352           intValue = ((ConstPoolSInt*) val)->getValue();
353           isValidConstant = true;
354           break;
355         default:
356           break;
357         }
358     }
359   
360   return intValue;
361 }
362
363 uint64_t
364 GetUnsignedIntConstantValue(const Value* val, bool& isValidConstant)
365 {
366   uint64_t intValue = 0;
367   isValidConstant = false;
368   
369   if (val->getValueType() == Value::ConstantVal)
370     {
371       switch(val->getType()->getPrimitiveID())
372         {
373         case Type::BoolTyID:
374           intValue = ((ConstPoolBool*) val)->getValue()? 1 : 0;
375           isValidConstant = true;
376           break;
377         case Type::UByteTyID:
378         case Type::UShortTyID:
379         case Type::UIntTyID:
380         case Type::ULongTyID:
381         case Type::PointerTyID:
382           intValue = ((ConstPoolUInt*) val)->getValue();
383           isValidConstant = true;
384           break;
385         default:
386           break;
387         }
388     }
389   
390   return intValue;
391 }
392
393
394 int64_t
395 GetConstantValueAsSignedInt(const Value* val, bool& isValidConstant)
396 {
397   int64_t intValue = 0;
398   
399   if (val->getType()->isSigned())
400     {
401       intValue = GetSignedIntConstantValue(val, isValidConstant);
402     }
403   else                          // non-numeric types will fall here
404     {
405       uint64_t uintValue = GetUnsignedIntConstantValue(val, isValidConstant);
406       if (isValidConstant && uintValue < INT64_MAX)     // then safe to cast to signed
407         intValue = (int64_t) uintValue;
408       else 
409         isValidConstant = false;
410     }
411   
412   return intValue;
413 }