blob: f53c090f70b6a7df0295824df0a89c2900a6cea4 [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:
Chris Lattnerda558102001-10-02 03:41:24 +000048 return ConstPoolPointer::getNullPointer(cast<PointerType>(Ty));
Chris Lattner2f7c9632001-06-06 20:29:01 +000049 default:
50 return 0;
51 }
52}
53
Chris Lattnerda558102001-10-02 03:41:24 +000054bool ConstPoolInt::classof(const ConstPoolVal *CPV) {
Chris Lattner38569342001-10-01 20:11:19 +000055 return CPV->getType()->isIntegral();
56}
Chris Lattner2f7c9632001-06-06 20:29:01 +000057
58//===----------------------------------------------------------------------===//
59// ConstPoolXXX Classes
60//===----------------------------------------------------------------------===//
61
62//===----------------------------------------------------------------------===//
63// Normal Constructors
64
Chris Lattner49d855c2001-09-07 16:46:31 +000065ConstPoolBool::ConstPoolBool(bool V) : ConstPoolVal(Type::BoolTy) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000066 Val = V;
67}
Chris Lattner49d855c2001-09-07 16:46:31 +000068
69ConstPoolInt::ConstPoolInt(const Type *Ty, uint64_t V) : ConstPoolVal(Ty) {
70 Val.Unsigned = V;
Chris Lattner7309d662001-07-21 19:16:08 +000071}
Chris Lattner2f7c9632001-06-06 20:29:01 +000072
Chris Lattner49d855c2001-09-07 16:46:31 +000073ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000074 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000075}
76
Chris Lattner49d855c2001-09-07 16:46:31 +000077ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V) : ConstPoolInt(Ty, V) {
Chris Lattner9655e542001-07-20 19:16:02 +000078 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000079}
80
Chris Lattner49d855c2001-09-07 16:46:31 +000081ConstPoolFP::ConstPoolFP(const Type *Ty, double V) : ConstPoolVal(Ty) {
Chris Lattner9655e542001-07-20 19:16:02 +000082 assert(isValueValidForType(Ty, V) && "Value too large for type!");
Chris Lattner2f7c9632001-06-06 20:29:01 +000083 Val = V;
84}
85
Chris Lattner49d855c2001-09-07 16:46:31 +000086ConstPoolArray::ConstPoolArray(const ArrayType *T,
87 const vector<ConstPoolVal*> &V)
88 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000089 for (unsigned i = 0; i < V.size(); i++) {
90 assert(V[i]->getType() == T->getElementType());
Chris Lattnera073acb2001-07-07 08:36:50 +000091 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +000092 }
93}
94
Chris Lattner49d855c2001-09-07 16:46:31 +000095ConstPoolStruct::ConstPoolStruct(const StructType *T,
96 const vector<ConstPoolVal*> &V)
97 : ConstPoolVal(T) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000098 const StructType::ElementTypes &ETypes = T->getElementTypes();
Chris Lattner49d855c2001-09-07 16:46:31 +000099
Chris Lattner2f7c9632001-06-06 20:29:01 +0000100 for (unsigned i = 0; i < V.size(); i++) {
101 assert(V[i]->getType() == ETypes[i]);
Chris Lattnera073acb2001-07-07 08:36:50 +0000102 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000103 }
104}
105
Chris Lattner436248f2001-09-30 20:14:07 +0000106ConstPoolPointer::ConstPoolPointer(const PointerType *T) : ConstPoolVal(T) {}
107
Chris Lattner2f7c9632001-06-06 20:29:01 +0000108
109//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000110// getStrValue implementations
111
112string ConstPoolBool::getStrValue() const {
Chris Lattner4cee8d82001-06-27 23:41:11 +0000113 return Val ? "true" : "false";
Chris Lattner2f7c9632001-06-06 20:29:01 +0000114}
115
116string ConstPoolSInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000117 return itostr(Val.Signed);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000118}
119
120string ConstPoolUInt::getStrValue() const {
Chris Lattner9655e542001-07-20 19:16:02 +0000121 return utostr(Val.Unsigned);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000122}
123
124string ConstPoolFP::getStrValue() const {
Chris Lattnerd06dd692001-07-15 00:18:39 +0000125 return ftostr(Val);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000126}
127
Chris Lattner2f7c9632001-06-06 20:29:01 +0000128string ConstPoolArray::getStrValue() const {
129 string Result = "[";
Chris Lattnera073acb2001-07-07 08:36:50 +0000130 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000131 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000132 " " + cast<ConstPoolVal>(Operands[0])->getStrValue();
Chris Lattnera073acb2001-07-07 08:36:50 +0000133 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000134 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000135 " " + cast<ConstPoolVal>(Operands[i])->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000136 }
137
138 return Result + " ]";
139}
140
141string ConstPoolStruct::getStrValue() const {
142 string Result = "{";
Chris Lattnera073acb2001-07-07 08:36:50 +0000143 if (Operands.size()) {
Chris Lattner49d855c2001-09-07 16:46:31 +0000144 Result += " " + Operands[0]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000145 " " + cast<ConstPoolVal>(Operands[0])->getStrValue();
Chris Lattnera073acb2001-07-07 08:36:50 +0000146 for (unsigned i = 1; i < Operands.size(); i++)
Chris Lattner49d855c2001-09-07 16:46:31 +0000147 Result += ", " + Operands[i]->getType()->getDescription() +
Chris Lattner8f191122001-10-01 18:26:53 +0000148 " " + cast<ConstPoolVal>(Operands[i])->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000149 }
150
151 return Result + " }";
152}
153
Chris Lattner436248f2001-09-30 20:14:07 +0000154string ConstPoolPointer::getStrValue() const {
155 return "null";
156}
157
Chris Lattner2f7c9632001-06-06 20:29:01 +0000158//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000159// isValueValidForType implementations
160
161bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
162 switch (Ty->getPrimitiveID()) {
163 default:
164 return false; // These can't be represented as integers!!!
165
166 // Signed types...
167 case Type::SByteTyID:
168 return (Val <= INT8_MAX && Val >= INT8_MIN);
169 case Type::ShortTyID:
170 return (Val <= INT16_MAX && Val >= INT16_MIN);
171 case Type::IntTyID:
172 return (Val <= INT32_MAX && Val >= INT32_MIN);
173 case Type::LongTyID:
174 return true; // This is the largest type...
175 }
176 assert(0 && "WTF?");
177 return false;
178}
179
180bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
181 switch (Ty->getPrimitiveID()) {
182 default:
183 return false; // These can't be represented as integers!!!
184
185 // Unsigned types...
186 case Type::UByteTyID:
187 return (Val <= UINT8_MAX);
188 case Type::UShortTyID:
189 return (Val <= UINT16_MAX);
190 case Type::UIntTyID:
191 return (Val <= UINT32_MAX);
192 case Type::ULongTyID:
193 return true; // This is the largest type...
194 }
195 assert(0 && "WTF?");
196 return false;
197}
198
199bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
200 switch (Ty->getPrimitiveID()) {
201 default:
202 return false; // These can't be represented as floating point!
203
204 // TODO: Figure out how to test if a double can be cast to a float!
Chris Lattner2f7c9632001-06-06 20:29:01 +0000205 case Type::FloatTyID:
Chris Lattnerd06dd692001-07-15 00:18:39 +0000206 /*
Chris Lattner2f7c9632001-06-06 20:29:01 +0000207 return (Val <= UINT8_MAX);
208 */
209 case Type::DoubleTyID:
210 return true; // This is the largest type...
211 }
212};
Chris Lattner9655e542001-07-20 19:16:02 +0000213
Chris Lattner49d855c2001-09-07 16:46:31 +0000214//===----------------------------------------------------------------------===//
215// Hash Function Implementations
216#if 0
217unsigned ConstPoolSInt::hash(const Type *Ty, int64_t V) {
218 return unsigned(Ty->getPrimitiveID() ^ V);
219}
220
221unsigned ConstPoolUInt::hash(const Type *Ty, uint64_t V) {
222 return unsigned(Ty->getPrimitiveID() ^ V);
223}
224
225unsigned ConstPoolFP::hash(const Type *Ty, double V) {
226 return Ty->getPrimitiveID() ^ unsigned(V);
227}
228
229unsigned ConstPoolArray::hash(const ArrayType *Ty,
230 const vector<ConstPoolVal*> &V) {
231 unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
232 for (unsigned i = 0; i < V.size(); ++i)
233 Result ^= V[i]->getHash() << (i & 7);
234 return Result;
235}
236
237unsigned ConstPoolStruct::hash(const StructType *Ty,
238 const vector<ConstPoolVal*> &V) {
239 unsigned Result = (Ty->getUniqueID() << 5) ^ (Ty->getUniqueID() * 7);
240 for (unsigned i = 0; i < V.size(); ++i)
241 Result ^= V[i]->getHash() << (i & 7);
242 return Result;
243}
244#endif
245
246//===----------------------------------------------------------------------===//
247// Factory Function Implementation
248
249template<class ValType, class ConstPoolClass>
250struct ValueMap {
251 typedef pair<const Type*, ValType> ConstHashKey;
252 map<ConstHashKey, ConstPoolClass *> Map;
253
254 inline ConstPoolClass *get(const Type *Ty, ValType V) {
255 map<ConstHashKey,ConstPoolClass *>::iterator I =
256 Map.find(ConstHashKey(Ty, V));
257 return (I != Map.end()) ? I->second : 0;
258 }
259
260 inline void add(const Type *Ty, ValType V, ConstPoolClass *CP) {
261 Map.insert(make_pair(ConstHashKey(Ty, V), CP));
262 }
263};
264
265//---- ConstPoolUInt::get() and ConstPoolSInt::get() implementations...
266//
267static ValueMap<uint64_t, ConstPoolInt> IntConstants;
268
269ConstPoolSInt *ConstPoolSInt::get(const Type *Ty, int64_t V) {
270 ConstPoolSInt *Result = (ConstPoolSInt*)IntConstants.get(Ty, (uint64_t)V);
271 if (!Result) // If no preexisting value, create one now...
272 IntConstants.add(Ty, V, Result = new ConstPoolSInt(Ty, V));
273 return Result;
274}
275
276ConstPoolUInt *ConstPoolUInt::get(const Type *Ty, uint64_t V) {
277 ConstPoolUInt *Result = (ConstPoolUInt*)IntConstants.get(Ty, V);
278 if (!Result) // If no preexisting value, create one now...
279 IntConstants.add(Ty, V, Result = new ConstPoolUInt(Ty, V));
280 return Result;
281}
282
283ConstPoolInt *ConstPoolInt::get(const Type *Ty, unsigned char V) {
284 assert(V <= 127 && "Can only be used with very small positive constants!");
285 if (Ty->isSigned()) return ConstPoolSInt::get(Ty, V);
286 return ConstPoolUInt::get(Ty, V);
287}
288
289//---- ConstPoolFP::get() implementation...
290//
291static ValueMap<double, ConstPoolFP> FPConstants;
292
293ConstPoolFP *ConstPoolFP::get(const Type *Ty, double V) {
294 ConstPoolFP *Result = FPConstants.get(Ty, V);
295 if (!Result) // If no preexisting value, create one now...
296 FPConstants.add(Ty, V, Result = new ConstPoolFP(Ty, V));
297 return Result;
298}
299
300//---- ConstPoolArray::get() implementation...
301//
302static ValueMap<vector<ConstPoolVal*>, ConstPoolArray> ArrayConstants;
303
304ConstPoolArray *ConstPoolArray::get(const ArrayType *Ty,
305 const vector<ConstPoolVal*> &V) {
306 ConstPoolArray *Result = ArrayConstants.get(Ty, V);
307 if (!Result) // If no preexisting value, create one now...
308 ArrayConstants.add(Ty, V, Result = new ConstPoolArray(Ty, V));
309 return Result;
310}
311
312//---- ConstPoolStruct::get() implementation...
313//
314static ValueMap<vector<ConstPoolVal*>, ConstPoolStruct> StructConstants;
315
316ConstPoolStruct *ConstPoolStruct::get(const StructType *Ty,
317 const vector<ConstPoolVal*> &V) {
318 ConstPoolStruct *Result = StructConstants.get(Ty, V);
319 if (!Result) // If no preexisting value, create one now...
320 StructConstants.add(Ty, V, Result = new ConstPoolStruct(Ty, V));
321 return Result;
322}