blob: bb61b33f5e6f5565741bc8a5dd945b7c44d1568b [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"
9#include "llvm/ConstantPool.h"
10#include "llvm/Tools/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
20void ConstantPool::setParent(SymTabValue *STV) {
21 Parent = STV;
22 for (unsigned i = 0; i < Planes.size(); i++)
23 Planes[i]->setParent(Parent);
24}
25
Chris Lattnerf2a738c2001-07-14 06:13:19 +000026const Value *ConstantPool::getParentV() const { return Parent->getSTVParent(); }
27Value *ConstantPool::getParentV() { return Parent->getSTVParent(); }
28
29
30
Chris Lattner2f7c9632001-06-06 20:29:01 +000031// Constant getPlane - Returns true if the type plane does not exist, otherwise
32// updates the pointer to point to the correct plane.
33//
34bool 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//
44bool 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
51void 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
58ConstantPool::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...
65void 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
71bool 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
81void 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
91void ConstantPool::dropAllReferences() {
92 for (unsigned i = 0; i < Planes.size(); i++)
Chris Lattner4cee8d82001-06-27 23:41:11 +000093 for_each(Planes[i]->begin(), Planes[i]->end(),
94 mem_fun(&ConstPoolVal::dropAllReferences));
Chris Lattner2f7c9632001-06-06 20:29:01 +000095}
96
97struct 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
106ConstPoolVal *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
115const 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
124ConstPoolVal *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
137const 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//===----------------------------------------------------------------------===//
151// ConstPoolVal Class
152//===----------------------------------------------------------------------===//
153
154// Specialize setName to take care of symbol table majik
155void ConstPoolVal::setName(const string &name) {
156 SymTabValue *P;
157 if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
158 Value::setName(name);
159 if (P && hasName()) P->getSymbolTable()->insert(this);
160}
161
162// Static constructor to create a '0' constant of arbitrary type...
163ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
164 switch (Ty->getPrimitiveID()) {
165 case Type::BoolTyID: return new ConstPoolBool(false);
166 case Type::SByteTyID:
167 case Type::ShortTyID:
168 case Type::IntTyID:
169 case Type::LongTyID: return new ConstPoolSInt(Ty, 0);
170
171 case Type::UByteTyID:
172 case Type::UShortTyID:
173 case Type::UIntTyID:
174 case Type::ULongTyID: return new ConstPoolUInt(Ty, 0);
175
176 case Type::FloatTyID:
177 case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
178 default:
179 return 0;
180 }
181}
182
183
184
185//===----------------------------------------------------------------------===//
186// ConstPoolXXX Classes
187//===----------------------------------------------------------------------===//
188
189//===----------------------------------------------------------------------===//
190// Normal Constructors
191
192ConstPoolBool::ConstPoolBool(bool V, const string &Name = "")
193 : ConstPoolVal(Type::BoolTy, Name) {
194 Val = V;
195}
196
197ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
198 : ConstPoolVal(Ty, Name) {
199 //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
200 assert(isValueValidForType(Ty, V) && "Value to large for type!");
201 Val = V;
202}
203
204ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
205 : ConstPoolVal(Ty, Name) {
206 //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
207 assert(isValueValidForType(Ty, V) && "Value to large for type!");
208 Val = V;
209}
210
211ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
212 : ConstPoolVal(Ty, Name) {
213 assert(isValueValidForType(Ty, V) && "Value to large for type!");
214 Val = V;
215}
216
217ConstPoolType::ConstPoolType(const Type *V, const string &Name)
218 : ConstPoolVal(Type::TypeTy, Name), Val(V) {
219}
220
221ConstPoolArray::ConstPoolArray(const ArrayType *T,
222 vector<ConstPoolVal*> &V,
223 const string &Name)
224 : ConstPoolVal(T, Name) {
225 for (unsigned i = 0; i < V.size(); i++) {
226 assert(V[i]->getType() == T->getElementType());
Chris Lattnera073acb2001-07-07 08:36:50 +0000227 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000228 }
229}
230
231ConstPoolStruct::ConstPoolStruct(const StructType *T,
232 vector<ConstPoolVal*> &V,
233 const string &Name)
234 : ConstPoolVal(T, Name) {
235 const StructType::ElementTypes &ETypes = T->getElementTypes();
236
237 for (unsigned i = 0; i < V.size(); i++) {
238 assert(V[i]->getType() == ETypes[i]);
Chris Lattnera073acb2001-07-07 08:36:50 +0000239 Operands.push_back(Use(V[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000240 }
241}
242
243
244//===----------------------------------------------------------------------===//
245// Copy Constructors
246
247ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
248 : ConstPoolVal(Type::BoolTy) {
249 Val = CPB.Val;
250}
251
252ConstPoolSInt::ConstPoolSInt(const ConstPoolSInt &CPSI)
253 : ConstPoolVal(CPSI.getType()) {
254 Val = CPSI.Val;
255}
256
257ConstPoolUInt::ConstPoolUInt(const ConstPoolUInt &CPUI)
258 : ConstPoolVal(CPUI.getType()) {
259 Val = CPUI.Val;
260}
261
262ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
263 : ConstPoolVal(CPFP.getType()) {
264 Val = CPFP.Val;
265}
266
267ConstPoolType::ConstPoolType(const ConstPoolType &CPT)
268 : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
269}
270
271ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
272 : ConstPoolVal(CPA.getType()) {
Chris Lattnera073acb2001-07-07 08:36:50 +0000273 for (unsigned i = 0; i < CPA.Operands.size(); i++)
274 Operands.push_back(Use(CPA.Operands[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000275}
276
277ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
278 : ConstPoolVal(CPS.getType()) {
Chris Lattnera073acb2001-07-07 08:36:50 +0000279 for (unsigned i = 0; i < CPS.Operands.size(); i++)
280 Operands.push_back(Use(CPS.Operands[i], this));
Chris Lattner2f7c9632001-06-06 20:29:01 +0000281}
282
283//===----------------------------------------------------------------------===//
284// getStrValue implementations
285
286string ConstPoolBool::getStrValue() const {
Chris Lattner4cee8d82001-06-27 23:41:11 +0000287 return Val ? "true" : "false";
Chris Lattner2f7c9632001-06-06 20:29:01 +0000288}
289
290string ConstPoolSInt::getStrValue() const {
291 return itostr(Val);
292}
293
294string ConstPoolUInt::getStrValue() const {
295 return utostr(Val);
296}
297
298string ConstPoolFP::getStrValue() const {
Chris Lattnerd06dd692001-07-15 00:18:39 +0000299 return ftostr(Val);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000300}
301
302string ConstPoolType::getStrValue() const {
303 return Val->getName();
304}
305
306string ConstPoolArray::getStrValue() const {
307 string Result = "[";
Chris Lattnera073acb2001-07-07 08:36:50 +0000308 if (Operands.size()) {
309 Result += " " + Operands[0]->getType()->getName() +
310 " " + Operands[0]->castConstantAsserting()->getStrValue();
311 for (unsigned i = 1; i < Operands.size(); i++)
312 Result += ", " + Operands[i]->getType()->getName() +
313 " " + Operands[i]->castConstantAsserting()->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000314 }
315
316 return Result + " ]";
317}
318
319string ConstPoolStruct::getStrValue() const {
320 string Result = "{";
Chris Lattnera073acb2001-07-07 08:36:50 +0000321 if (Operands.size()) {
322 Result += " " + Operands[0]->getType()->getName() +
323 " " + Operands[0]->castConstantAsserting()->getStrValue();
324 for (unsigned i = 1; i < Operands.size(); i++)
325 Result += ", " + Operands[i]->getType()->getName() +
326 " " + Operands[i]->castConstantAsserting()->getStrValue();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000327 }
328
329 return Result + " }";
330}
331
332//===----------------------------------------------------------------------===//
333// equals implementations
334
335bool ConstPoolBool::equals(const ConstPoolVal *V) const {
336 assert(getType() == V->getType());
337 return ((ConstPoolBool*)V)->getValue() == Val;
338}
339
340bool ConstPoolSInt::equals(const ConstPoolVal *V) const {
341 assert(getType() == V->getType());
342 return ((ConstPoolSInt*)V)->getValue() == Val;
343}
344
345bool ConstPoolUInt::equals(const ConstPoolVal *V) const {
346 assert(getType() == V->getType());
347 return ((ConstPoolUInt*)V)->getValue() == Val;
348}
349
350bool ConstPoolFP::equals(const ConstPoolVal *V) const {
351 assert(getType() == V->getType());
352 return ((ConstPoolFP*)V)->getValue() == Val;
353}
354
355bool ConstPoolType::equals(const ConstPoolVal *V) const {
356 assert(getType() == V->getType());
357 return ((ConstPoolType*)V)->getValue() == Val;
358}
359
360bool ConstPoolArray::equals(const ConstPoolVal *V) const {
361 assert(getType() == V->getType());
362 ConstPoolArray *AV = (ConstPoolArray*)V;
Chris Lattnera073acb2001-07-07 08:36:50 +0000363 if (Operands.size() != AV->Operands.size()) return false;
364 for (unsigned i = 0; i < Operands.size(); i++)
365 if (!Operands[i]->castConstantAsserting()->equals(
366 AV->Operands[i]->castConstantAsserting()))
367 return false;
Chris Lattner2f7c9632001-06-06 20:29:01 +0000368
369 return true;
370}
371
372bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
373 assert(getType() == V->getType());
374 ConstPoolStruct *SV = (ConstPoolStruct*)V;
Chris Lattnera073acb2001-07-07 08:36:50 +0000375 if (Operands.size() != SV->Operands.size()) return false;
376 for (unsigned i = 0; i < Operands.size(); i++)
377 if (!Operands[i]->castConstantAsserting()->equals(
378 SV->Operands[i]->castConstantAsserting()))
379 return false;
Chris Lattner2f7c9632001-06-06 20:29:01 +0000380
381 return true;
382}
383
384//===----------------------------------------------------------------------===//
385// isValueValidForType implementations
386
387bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
388 switch (Ty->getPrimitiveID()) {
389 default:
390 return false; // These can't be represented as integers!!!
391
392 // Signed types...
393 case Type::SByteTyID:
394 return (Val <= INT8_MAX && Val >= INT8_MIN);
395 case Type::ShortTyID:
396 return (Val <= INT16_MAX && Val >= INT16_MIN);
397 case Type::IntTyID:
398 return (Val <= INT32_MAX && Val >= INT32_MIN);
399 case Type::LongTyID:
400 return true; // This is the largest type...
401 }
402 assert(0 && "WTF?");
403 return false;
404}
405
406bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
407 switch (Ty->getPrimitiveID()) {
408 default:
409 return false; // These can't be represented as integers!!!
410
411 // Unsigned types...
412 case Type::UByteTyID:
413 return (Val <= UINT8_MAX);
414 case Type::UShortTyID:
415 return (Val <= UINT16_MAX);
416 case Type::UIntTyID:
417 return (Val <= UINT32_MAX);
418 case Type::ULongTyID:
419 return true; // This is the largest type...
420 }
421 assert(0 && "WTF?");
422 return false;
423}
424
425bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
426 switch (Ty->getPrimitiveID()) {
427 default:
428 return false; // These can't be represented as floating point!
429
430 // TODO: Figure out how to test if a double can be cast to a float!
Chris Lattner2f7c9632001-06-06 20:29:01 +0000431 case Type::FloatTyID:
Chris Lattnerd06dd692001-07-15 00:18:39 +0000432 /*
Chris Lattner2f7c9632001-06-06 20:29:01 +0000433 return (Val <= UINT8_MAX);
434 */
435 case Type::DoubleTyID:
436 return true; // This is the largest type...
437 }
438};