blob: 374c583ab9bb5e8e2d4cc97295e953185c0d959c [file] [log] [blame]
Chris Lattner2f7c9632001-06-06 20:29:01 +00001//===-- 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"
Chris Lattnere2472bb2001-07-23 17:46:59 +00009#include "llvm/Support/StringExtras.h" // itostr
Chris Lattner2f7c9632001-06-06 20:29:01 +000010#include "llvm/DerivedTypes.h"
11#include "llvm/SymbolTable.h"
12#include <algorithm>
13#include <assert.h>
14
Chris Lattner49d855c2001-09-07 16:46:31 +000015ConstPoolBool *ConstPoolBool::True = new ConstPoolBool(true);
16ConstPoolBool *ConstPoolBool::False = new ConstPoolBool(false);
Chris Lattner2f7c9632001-06-06 20:29:01 +000017
Chris Lattner9655e542001-07-20 19:16:02 +000018
Chris Lattner2f7c9632001-06-06 20:29:01 +000019//===----------------------------------------------------------------------===//
20// ConstPoolVal Class
21//===----------------------------------------------------------------------===//
22
23// Specialize setName to take care of symbol table majik
Chris Lattner49d855c2001-09-07 16:46:31 +000024void 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);
Chris Lattner2f7c9632001-06-06 20:29:01 +000028}
29
30// Static constructor to create a '0' constant of arbitrary type...
31ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
32 switch (Ty->getPrimitiveID()) {
Chris Lattner49d855c2001-09-07 16:46:31 +000033 case Type::BoolTyID: return ConstPoolBool::get(false);
Chris Lattner2f7c9632001-06-06 20:29:01 +000034 case Type::SByteTyID:
35 case Type::ShortTyID:
36 case Type::IntTyID:
Chris Lattner49d855c2001-09-07 16:46:31 +000037 case Type::LongTyID: return ConstPoolSInt::get(Ty, 0);
Chris Lattner2f7c9632001-06-06 20:29:01 +000038
39 case Type::UByteTyID:
40 case Type::UShortTyID:
41 case Type::UIntTyID:
Chris Lattner49d855c2001-09-07 16:46:31 +000042 case Type::ULongTyID: return ConstPoolUInt::get(Ty, 0);
Chris Lattner2f7c9632001-06-06 20:29:01 +000043
44 case Type::FloatTyID:
Chris Lattner49d855c2001-09-07 16:46:31 +000045 case Type::DoubleTyID: return ConstPoolFP::get(Ty, 0);
Chris Lattner436248f2001-09-30 20:14:07 +000046
47 case Type::PointerTyID:
48 return ConstPoolPointer::getNullPointer(Ty->castPointerType());
Chris Lattner2f7c9632001-06-06 20:29:01 +000049 default:
50 return 0;
51 }
52}
53
54
55
56//===----------------------------------------------------------------------===//
57// ConstPoolXXX Classes
58//===----------------------------------------------------------------------===//
59
60//===----------------------------------------------------------------------===//
61// Normal Constructors
62
Chris Lattner49d855c2001-09-07 16:46:31 +000063ConstPoolBool::ConstPoolBool(bool V) : ConstPoolVal(Type::BoolTy) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000064 Val = V;
65}
Chris Lattner49d855c2001-09-07 16:46:31 +000066
67ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V) : ConstPoolVal(Ty) {
68 Val.Unsigned = V;
Chris Lattner7309d662001-07-21 19:16:08 +000069}
Chris Lattner2f7c9632001-06-06 20:29:01 +000070
Chris Lattner49d855c2001-09-07 16:46:31 +000071ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000072 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000073}
74
Chris Lattner49d855c2001-09-07 16:46:31 +000075ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000076 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000077}
78
Chris Lattner49d855c2001-09-07 16:46:31 +000079ConstPoolFP::ConstPoolFP(const Type *Ty, double V) : ConstPoolVal(Ty) {
Chris Lattner9655e542001-07-20 19:16:02 +000080 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000081 Val = V;
82}
83
Chris Lattner49d855c2001-09-07 16:46:31 +000084ConstPoolArray::ConstPoolArray(const ArrayType *T,
85 const vector<ConstPoolVal*> &V)
86 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000087 for (unsigned i = 0; i < V.size(); i++) {
88 assert(V[i]->getType() == T->getElementType());
Chris Lattnera073acb2001-07-07 08:36:50 +000089 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +000090 }
91}
92
Chris Lattner49d855c2001-09-07 16:46:31 +000093ConstPoolStruct::ConstPoolStruct(const StructType *T,
94 const vector<ConstPoolVal*> &V)
95 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000096 const StructType::ElementTypes &ETypes = T->getElementTypes();
Chris Lattner49d855c2001-09-07 16:46:31 +000097
Chris Lattner2f7c9632001-06-06 20:29:01 +000098 for (unsigned i = 0; i < V.size(); i++) {
99 assert(V[i]->getType() == ETypes[i]);
Chris Lattnera073acb2001-07-07 08:36:50 +0000100 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000101 }
102}
103
Chris Lattner436248f2001-09-30 20:14:07 +0000104ConstPoolPointer::ConstPoolPointer(const PointerType *T) : ConstPoolVal(T) {}
105
Chris Lattner2f7c9632001-06-06 20:29:01 +0000106
107//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000108// getStrValue implementations
109
110string ConstPoolBool::getStrValue() const {
Chris Lattner4cee8d82001-06-27 23:41:11 +0000111 return Val ? "true" : "false";
Chris Lattner2f7c9632001-06-06 20:29:01 +0000112}
113
114string ConstPoolSInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000115 return itostr(Val.Signed);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000116}
117
118string ConstPoolUInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000119 return utostr(Val.Unsigned);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000120}
121
122string ConstPoolFP::getStrValue() const {
Chris Lattnerd06dd692001-07-15 00:18:39 +0000123 return ftostr(Val);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000124}
125
Chris Lattner2f7c9632001-06-06 20:29:01 +0000126string ConstPoolArray::getStrValue() const {
127 string Result = "[";
Chris Lattnera073acb2001-07-07 08:36:50 +0000128 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000129 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000130 " " + cast<ConstPoolVal>(Operands[0])->getStrValue();
Chris Lattnera073acb2001-07-07 08:36:50 +0000131 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000132 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000133 " " + cast<ConstPoolVal>(Operands[i])->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000134 }
135
136 return Result + " ]";
137}
138
139string ConstPoolStruct::getStrValue() const {
140 string Result = "{";
Chris Lattnera073acb2001-07-07 08:36:50 +0000141 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000142 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000143 " " + cast<ConstPoolVal>(Operands[0])->getStrValue();
Chris Lattnera073acb2001-07-07 08:36:50 +0000144 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000145 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000146 " " + cast<ConstPoolVal>(Operands[i])->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000147 }
148
149 return Result + " }";
150}
151
Chris Lattner436248f2001-09-30 20:14:07 +0000152string ConstPoolPointer::getStrValue() const {
153 return "null";
154}
155
Chris Lattner2f7c9632001-06-06 20:29:01 +0000156//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000157// isValueValidForType implementations
158
159bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
160 switch (Ty->getPrimitiveID()) {
161 default:
162 return false; // These can't be represented as integers!!!
163
164 // Signed types...
165 case Type::SByteTyID:
166 return (Val <= INT8_MAX && Val >= INT8_MIN);
167 case Type::ShortTyID:
168 return (Val <= INT16_MAX && Val >= INT16_MIN);
169 case Type::IntTyID:
170 return (Val <= INT32_MAX && Val >= INT32_MIN);
171 case Type::LongTyID:
172 return true; // This is the largest type...
173 }
174 assert(0 && "WTF?");
175 return false;
176}
177
178bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
179 switch (Ty->getPrimitiveID()) {
180 default:
181 return false; // These can't be represented as integers!!!
182
183 // Unsigned types...
184 case Type::UByteTyID:
185 return (Val <= UINT8_MAX);
186 case Type::UShortTyID:
187 return (Val <= UINT16_MAX);
188 case Type::UIntTyID:
189 return (Val <= UINT32_MAX);
190 case Type::ULongTyID:
191 return true; // This is the largest type...
192 }
193 assert(0 && "WTF?");
194 return false;
195}
196
197bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
198 switch (Ty->getPrimitiveID()) {
199 default:
200 return false; // These can't be represented as floating point!
201
202 // TODO: Figure out how to test if a double can be cast to a float!
Chris Lattner2f7c9632001-06-06 20:29:01 +0000203 case Type::FloatTyID:
Chris Lattnerd06dd692001-07-15 00:18:39 +0000204 /*
Chris Lattner2f7c9632001-06-06 20:29:01 +0000205 return (Val <= UINT8_MAX);
206 */
207 case Type::DoubleTyID:
208 return true; // This is the largest type...
209 }
210};
Chris Lattner9655e542001-07-20 19:16:02 +0000211
Chris Lattner49d855c2001-09-07 16:46:31 +0000212//===----------------------------------------------------------------------===//
213// Hash Function Implementations
214#if 0
215unsigned ConstPoolSInt::hash(const Type *Ty, int64_t V) {
216 return unsigned(Ty->getPrimitiveID() ^ V);
217}
218
219unsigned ConstPoolUInt::hash(const Type *Ty, uint64_t V) {
220 return unsigned(Ty->getPrimitiveID() ^ V);
221}
222
223unsigned ConstPoolFP::hash(const Type *Ty, double V) {
224 return Ty->getPrimitiveID() ^ unsigned(V);
225}
226
227unsigned ConstPoolArray::hash(const ArrayType *Ty,
228 const vector<ConstPoolVal*> &V) {
229 unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
230 for (unsigned i = 0; i < V.size(); ++i)
231 Result ^= V[i]->getHash() << (i & 7);
232 return Result;
233}
234
235unsigned ConstPoolStruct::hash(const StructType *Ty,
236 const vector<ConstPoolVal*> &V) {
237 unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
238 for (unsigned i = 0; i < V.size(); ++i)
239 Result ^= V[i]->getHash() << (i & 7);
240 return Result;
241}
242#endif
243
244//===----------------------------------------------------------------------===//
245// Factory Function Implementation
246
247template<class ValType, class ConstPoolClass>
248struct ValueMap {
249 typedef pair<const Type*, ValType> ConstHashKey;
250 map<ConstHashKey, ConstPoolClass *> Map;
251
252 inline ConstPoolClass *get(const Type *Ty, ValType V) {
253 map<ConstHashKey,ConstPoolClass *>::iterator I =
254 Map.find(ConstHashKey(Ty, V));
255 return (I != Map.end()) ? I->second : 0;
256 }
257
258 inline void add(const Type *Ty, ValType V, ConstPoolClass *CP) {
259 Map.insert(make_pair(ConstHashKey(Ty, V), CP));
260 }
261};
262
263//---- ConstPoolUInt::get() and ConstPoolSInt::get() implementations...
264//
265static ValueMap<uint64_t, ConstPoolInt> IntConstants;
266
267ConstPoolSInt *ConstPoolSInt::get(const Type *Ty, int64_t V) {
268 ConstPoolSInt *Result = (ConstPoolSInt*)IntConstants.get(Ty, (uint64_t)V);
269 if (!Result) // If no preexisting value, create one now...
270 IntConstants.add(Ty, V, Result = new ConstPoolSInt(Ty, V));
271 return Result;
272}
273
274ConstPoolUInt *ConstPoolUInt::get(const Type *Ty, uint64_t V) {
275 ConstPoolUInt *Result = (ConstPoolUInt*)IntConstants.get(Ty, V);
276 if (!Result) // If no preexisting value, create one now...
277 IntConstants.add(Ty, V, Result = new ConstPoolUInt(Ty, V));
278 return Result;
279}
280
281ConstPoolInt *ConstPoolInt::get(const Type *Ty, unsigned char V) {
282 assert(V <= 127 && "Can only be used with very small positive constants!");
283 if (Ty->isSigned()) return ConstPoolSInt::get(Ty, V);
284 return ConstPoolUInt::get(Ty, V);
285}
286
287//---- ConstPoolFP::get() implementation...
288//
289static ValueMap<double, ConstPoolFP> FPConstants;
290
291ConstPoolFP *ConstPoolFP::get(const Type *Ty, double V) {
292 ConstPoolFP *Result = FPConstants.get(Ty, V);
293 if (!Result) // If no preexisting value, create one now...
294 FPConstants.add(Ty, V, Result = new ConstPoolFP(Ty, V));
295 return Result;
296}
297
298//---- ConstPoolArray::get() implementation...
299//
300static ValueMap<vector<ConstPoolVal*>, ConstPoolArray> ArrayConstants;
301
302ConstPoolArray *ConstPoolArray::get(const ArrayType *Ty,
303 const vector<ConstPoolVal*> &V) {
304 ConstPoolArray *Result = ArrayConstants.get(Ty, V);
305 if (!Result) // If no preexisting value, create one now...
306 ArrayConstants.add(Ty, V, Result = new ConstPoolArray(Ty, V));
307 return Result;
308}
309
310//---- ConstPoolStruct::get() implementation...
311//
312static ValueMap<vector<ConstPoolVal*>, ConstPoolStruct> StructConstants;
313
314ConstPoolStruct *ConstPoolStruct::get(const StructType *Ty,
315 const vector<ConstPoolVal*> &V) {
316 ConstPoolStruct *Result = StructConstants.get(Ty, V);
317 if (!Result) // If no preexisting value, create one now...
318 StructConstants.add(Ty, V, Result = new ConstPoolStruct(Ty, V));
319 return Result;
320}