blob: d53130d6012ecb3cd1ad782d8e7b08a9d2268c75 [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 Lattner2f7c9632001-06-06 20:29:01 +000046 default:
47 return 0;
48 }
49}
50
51
52
53//===----------------------------------------------------------------------===//
54// ConstPoolXXX Classes
55//===----------------------------------------------------------------------===//
56
57//===----------------------------------------------------------------------===//
58// Normal Constructors
59
Chris Lattner49d855c2001-09-07 16:46:31 +000060ConstPoolBool::ConstPoolBool(bool V) : ConstPoolVal(Type::BoolTy) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000061 Val = V;
62}
Chris Lattner49d855c2001-09-07 16:46:31 +000063
64ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V) : ConstPoolVal(Ty) {
65 Val.Unsigned = V;
Chris Lattner7309d662001-07-21 19:16:08 +000066}
Chris Lattner2f7c9632001-06-06 20:29:01 +000067
Chris Lattner49d855c2001-09-07 16:46:31 +000068ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000069 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000070}
71
Chris Lattner49d855c2001-09-07 16:46:31 +000072ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000073 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000074}
75
Chris Lattner49d855c2001-09-07 16:46:31 +000076ConstPoolFP::ConstPoolFP(const Type *Ty, double V) : ConstPoolVal(Ty) {
Chris Lattner9655e542001-07-20 19:16:02 +000077 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000078 Val = V;
79}
80
Chris Lattner49d855c2001-09-07 16:46:31 +000081ConstPoolArray::ConstPoolArray(const ArrayType *T,
82 const vector<ConstPoolVal*> &V)
83 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000084 for (unsigned i = 0; i < V.size(); i++) {
85 assert(V[i]->getType() == T->getElementType());
Chris Lattnera073acb2001-07-07 08:36:50 +000086 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +000087 }
88}
89
Chris Lattner49d855c2001-09-07 16:46:31 +000090ConstPoolStruct::ConstPoolStruct(const StructType *T,
91 const vector<ConstPoolVal*> &V)
92 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000093 const StructType::ElementTypes &ETypes = T->getElementTypes();
Chris Lattner49d855c2001-09-07 16:46:31 +000094
Chris Lattner2f7c9632001-06-06 20:29:01 +000095 for (unsigned i = 0; i < V.size(); i++) {
96 assert(V[i]->getType() == ETypes[i]);
Chris Lattnera073acb2001-07-07 08:36:50 +000097 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +000098 }
99}
100
101
102//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000103// getStrValue implementations
104
105string ConstPoolBool::getStrValue() const {
Chris Lattner4cee8d82001-06-27 23:41:11 +0000106 return Val ? "true" : "false";
Chris Lattner2f7c9632001-06-06 20:29:01 +0000107}
108
109string ConstPoolSInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000110 return itostr(Val.Signed);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000111}
112
113string ConstPoolUInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000114 return utostr(Val.Unsigned);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000115}
116
117string ConstPoolFP::getStrValue() const {
Chris Lattnerd06dd692001-07-15 00:18:39 +0000118 return ftostr(Val);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000119}
120
Chris Lattner2f7c9632001-06-06 20:29:01 +0000121string ConstPoolArray::getStrValue() const {
122 string Result = "[";
Chris Lattnera073acb2001-07-07 08:36:50 +0000123 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000124 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattnera073acb2001-07-07 08:36:50 +0000125 " " + Operands[0]->castConstantAsserting()->getStrValue();
126 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000127 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattnera073acb2001-07-07 08:36:50 +0000128 " " + Operands[i]->castConstantAsserting()->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000129 }
130
131 return Result + " ]";
132}
133
134string ConstPoolStruct::getStrValue() const {
135 string Result = "{";
Chris Lattnera073acb2001-07-07 08:36:50 +0000136 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000137 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattnera073acb2001-07-07 08:36:50 +0000138 " " + Operands[0]->castConstantAsserting()->getStrValue();
139 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000140 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattnera073acb2001-07-07 08:36:50 +0000141 " " + Operands[i]->castConstantAsserting()->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000142 }
143
144 return Result + " }";
145}
146
147//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000148// isValueValidForType implementations
149
150bool 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
169bool 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
188bool 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!
Chris Lattner2f7c9632001-06-06 20:29:01 +0000194 case Type::FloatTyID:
Chris Lattnerd06dd692001-07-15 00:18:39 +0000195 /*
Chris Lattner2f7c9632001-06-06 20:29:01 +0000196 return (Val <= UINT8_MAX);
197 */
198 case Type::DoubleTyID:
199 return true; // This is the largest type...
200 }
201};
Chris Lattner9655e542001-07-20 19:16:02 +0000202
Chris Lattner49d855c2001-09-07 16:46:31 +0000203//===----------------------------------------------------------------------===//
204// Hash Function Implementations
205#if 0
206unsigned ConstPoolSInt::hash(const Type *Ty, int64_t V) {
207 return unsigned(Ty->getPrimitiveID() ^ V);
208}
209
210unsigned ConstPoolUInt::hash(const Type *Ty, uint64_t V) {
211 return unsigned(Ty->getPrimitiveID() ^ V);
212}
213
214unsigned ConstPoolFP::hash(const Type *Ty, double V) {
215 return Ty->getPrimitiveID() ^ unsigned(V);
216}
217
218unsigned 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
226unsigned 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
238template<class ValType, class ConstPoolClass>
239struct 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//
256static ValueMap<uint64_t, ConstPoolInt> IntConstants;
257
258ConstPoolSInt *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
265ConstPoolUInt *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
272ConstPoolInt *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//
280static ValueMap<double, ConstPoolFP> FPConstants;
281
282ConstPoolFP *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//
291static ValueMap<vector<ConstPoolVal*>, ConstPoolArray> ArrayConstants;
292
293ConstPoolArray *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//
303static ValueMap<vector<ConstPoolVal*>, ConstPoolStruct> StructConstants;
304
305ConstPoolStruct *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}