blob: 77ed50ae26db510f45f9546bdd1230a8bd06d265 [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
26// Constant getPlane - Returns true if the type plane does not exist, otherwise
27// updates the pointer to point to the correct plane.
28//
29bool ConstantPool::getPlane(const Type *T, const PlaneType *&Plane) const {
30 unsigned Ty = T->getUniqueID();
31 if (Ty >= Planes.size()) return true;
32 Plane = Planes[Ty];
33 return false;
34}
35
36// Constant getPlane - Returns true if the type plane does not exist, otherwise
37// updates the pointer to point to the correct plane.
38//
39bool ConstantPool::getPlane(const Type *T, PlaneType *&Plane) {
40 unsigned Ty = T->getUniqueID();
41 if (Ty >= Planes.size()) return true;
42 Plane = Planes[Ty];
43 return false;
44}
45
46void ConstantPool::resize(unsigned size) {
47 unsigned oldSize = Planes.size();
48 Planes.resize(size, 0);
49 while (oldSize < size)
50 Planes[oldSize++] = new PlaneType(Parent, Parent);
51}
52
53ConstantPool::PlaneType &ConstantPool::getPlane(const Type *T) {
54 unsigned Ty = T->getUniqueID();
55 if (Ty >= Planes.size()) resize(Ty+1);
56 return *Planes[Ty];
57}
58
59// insert - Add constant into the symbol table...
60void ConstantPool::insert(ConstPoolVal *N) {
61 unsigned Ty = N->getType()->getUniqueID();
62 if (Ty >= Planes.size()) resize(Ty+1);
63 Planes[Ty]->push_back(N);
64}
65
66bool ConstantPool::remove(ConstPoolVal *N) {
67 unsigned Ty = N->getType()->getUniqueID();
68 if (Ty >= Planes.size()) return true; // Doesn't contain any of that type
69
70 PlaneType::iterator I = ::find(Planes[Ty]->begin(), Planes[Ty]->end(), N);
71 if (I == Planes[Ty]->end()) return true;
72 Planes[Ty]->remove(I);
73 return false;
74}
75
76void ConstantPool::delete_all() {
77 dropAllReferences();
78 for (unsigned i = 0; i < Planes.size(); i++) {
79 Planes[i]->delete_all();
80 Planes[i]->setParent(0);
81 delete Planes[i];
82 }
83 Planes.clear();
84}
85
86void ConstantPool::dropAllReferences() {
87 for (unsigned i = 0; i < Planes.size(); i++)
Chris Lattner4cee8d82001-06-27 23:41:11 +000088 for_each(Planes[i]->begin(), Planes[i]->end(),
89 mem_fun(&ConstPoolVal::dropAllReferences));
Chris Lattner2f7c9632001-06-06 20:29:01 +000090}
91
92struct EqualsConstant {
93 const ConstPoolVal *v;
94 inline EqualsConstant(const ConstPoolVal *V) { v = V; }
95 inline bool operator()(const ConstPoolVal *V) const {
96 return v->equals(V);
97 }
98};
99
100
101ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) {
102 const PlaneType *P;
103 if (getPlane(V->getType(), P)) return 0;
104 PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
105 EqualsConstant(V));
106 if (PI == P->end()) return 0;
107 return *PI;
108}
109
110const ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) const {
111 const PlaneType *P;
112 if (getPlane(V->getType(), P)) return 0;
113 PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
114 EqualsConstant(V));
115 if (PI == P->end()) return 0;
116 return *PI;
117}
118
119ConstPoolVal *ConstantPool::find(const Type *Ty) {
120 const PlaneType *P;
121 if (getPlane(Type::TypeTy, P)) return 0;
122
123 // TODO: This is kinda silly
124 ConstPoolType V(Ty);
125
126 PlaneType::const_iterator PI =
127 find_if(P->begin(), P->end(), EqualsConstant(&V));
128 if (PI == P->end()) return 0;
129 return *PI;
130}
131
132const ConstPoolVal *ConstantPool::find(const Type *Ty) const {
133 const PlaneType *P;
134 if (getPlane(Type::TypeTy, P)) return 0;
135
136 // TODO: This is kinda silly
137 ConstPoolType V(Ty);
138
139 PlaneType::const_iterator PI =
140 find_if(P->begin(), P->end(), EqualsConstant(&V));
141 if (PI == P->end()) return 0;
142 return *PI;
143}
144
145//===----------------------------------------------------------------------===//
146// ConstPoolVal Class
147//===----------------------------------------------------------------------===//
148
149// Specialize setName to take care of symbol table majik
150void ConstPoolVal::setName(const string &name) {
151 SymTabValue *P;
152 if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
153 Value::setName(name);
154 if (P && hasName()) P->getSymbolTable()->insert(this);
155}
156
157// Static constructor to create a '0' constant of arbitrary type...
158ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
159 switch (Ty->getPrimitiveID()) {
160 case Type::BoolTyID: return new ConstPoolBool(false);
161 case Type::SByteTyID:
162 case Type::ShortTyID:
163 case Type::IntTyID:
164 case Type::LongTyID: return new ConstPoolSInt(Ty, 0);
165
166 case Type::UByteTyID:
167 case Type::UShortTyID:
168 case Type::UIntTyID:
169 case Type::ULongTyID: return new ConstPoolUInt(Ty, 0);
170
171 case Type::FloatTyID:
172 case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
173 default:
174 return 0;
175 }
176}
177
178
179
180//===----------------------------------------------------------------------===//
181// ConstPoolXXX Classes
182//===----------------------------------------------------------------------===//
183
184//===----------------------------------------------------------------------===//
185// Normal Constructors
186
187ConstPoolBool::ConstPoolBool(bool V, const string &Name = "")
188 : ConstPoolVal(Type::BoolTy, Name) {
189 Val = V;
190}
191
192ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
193 : ConstPoolVal(Ty, Name) {
194 //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
195 assert(isValueValidForType(Ty, V) && "Value to large for type!");
196 Val = V;
197}
198
199ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
200 : ConstPoolVal(Ty, Name) {
201 //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
202 assert(isValueValidForType(Ty, V) && "Value to large for type!");
203 Val = V;
204}
205
206ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
207 : ConstPoolVal(Ty, Name) {
208 assert(isValueValidForType(Ty, V) && "Value to large for type!");
209 Val = V;
210}
211
212ConstPoolType::ConstPoolType(const Type *V, const string &Name)
213 : ConstPoolVal(Type::TypeTy, Name), Val(V) {
214}
215
216ConstPoolArray::ConstPoolArray(const ArrayType *T,
217 vector<ConstPoolVal*> &V,
218 const string &Name)
219 : ConstPoolVal(T, Name) {
220 for (unsigned i = 0; i < V.size(); i++) {
221 assert(V[i]->getType() == T->getElementType());
222 Val.push_back(ConstPoolUse(V[i], this));
223 }
224}
225
226ConstPoolStruct::ConstPoolStruct(const StructType *T,
227 vector<ConstPoolVal*> &V,
228 const string &Name)
229 : ConstPoolVal(T, Name) {
230 const StructType::ElementTypes &ETypes = T->getElementTypes();
231
232 for (unsigned i = 0; i < V.size(); i++) {
233 assert(V[i]->getType() == ETypes[i]);
234 Val.push_back(ConstPoolUse(V[i], this));
235 }
236}
237
238
239//===----------------------------------------------------------------------===//
240// Copy Constructors
241
242ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
243 : ConstPoolVal(Type::BoolTy) {
244 Val = CPB.Val;
245}
246
247ConstPoolSInt::ConstPoolSInt(const ConstPoolSInt &CPSI)
248 : ConstPoolVal(CPSI.getType()) {
249 Val = CPSI.Val;
250}
251
252ConstPoolUInt::ConstPoolUInt(const ConstPoolUInt &CPUI)
253 : ConstPoolVal(CPUI.getType()) {
254 Val = CPUI.Val;
255}
256
257ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
258 : ConstPoolVal(CPFP.getType()) {
259 Val = CPFP.Val;
260}
261
262ConstPoolType::ConstPoolType(const ConstPoolType &CPT)
263 : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
264}
265
266ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
267 : ConstPoolVal(CPA.getType()) {
268 for (unsigned i = 0; i < CPA.Val.size(); i++)
269 Val.push_back(ConstPoolUse((ConstPoolVal*)CPA.Val[i], this));
270}
271
272ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
273 : ConstPoolVal(CPS.getType()) {
274 for (unsigned i = 0; i < CPS.Val.size(); i++)
275 Val.push_back(ConstPoolUse((ConstPoolVal*)CPS.Val[i], this));
276}
277
278//===----------------------------------------------------------------------===//
279// getStrValue implementations
280
281string ConstPoolBool::getStrValue() const {
Chris Lattner4cee8d82001-06-27 23:41:11 +0000282 return Val ? "true" : "false";
Chris Lattner2f7c9632001-06-06 20:29:01 +0000283}
284
285string ConstPoolSInt::getStrValue() const {
286 return itostr(Val);
287}
288
289string ConstPoolUInt::getStrValue() const {
290 return utostr(Val);
291}
292
293string ConstPoolFP::getStrValue() const {
294 assert(0 && "FP Constants Not implemented yet!!!!!!!!!!!");
295 return "% FP Constants NI!" /* + dtostr(Val)*/;
296}
297
298string ConstPoolType::getStrValue() const {
299 return Val->getName();
300}
301
302string ConstPoolArray::getStrValue() const {
303 string Result = "[";
304 if (Val.size()) {
305 Result += " " + Val[0]->getType()->getName() +
306 " " + Val[0]->getStrValue();
307 for (unsigned i = 1; i < Val.size(); i++)
308 Result += ", " + Val[i]->getType()->getName() +
309 " " + Val[i]->getStrValue();
310 }
311
312 return Result + " ]";
313}
314
315string ConstPoolStruct::getStrValue() const {
316 string Result = "{";
317 if (Val.size()) {
318 Result += " " + Val[0]->getType()->getName() +
319 " " + Val[0]->getStrValue();
320 for (unsigned i = 1; i < Val.size(); i++)
321 Result += ", " + Val[i]->getType()->getName() +
322 " " + Val[i]->getStrValue();
323 }
324
325 return Result + " }";
326}
327
328//===----------------------------------------------------------------------===//
329// equals implementations
330
331bool ConstPoolBool::equals(const ConstPoolVal *V) const {
332 assert(getType() == V->getType());
333 return ((ConstPoolBool*)V)->getValue() == Val;
334}
335
336bool ConstPoolSInt::equals(const ConstPoolVal *V) const {
337 assert(getType() == V->getType());
338 return ((ConstPoolSInt*)V)->getValue() == Val;
339}
340
341bool ConstPoolUInt::equals(const ConstPoolVal *V) const {
342 assert(getType() == V->getType());
343 return ((ConstPoolUInt*)V)->getValue() == Val;
344}
345
346bool ConstPoolFP::equals(const ConstPoolVal *V) const {
347 assert(getType() == V->getType());
348 return ((ConstPoolFP*)V)->getValue() == Val;
349}
350
351bool ConstPoolType::equals(const ConstPoolVal *V) const {
352 assert(getType() == V->getType());
353 return ((ConstPoolType*)V)->getValue() == Val;
354}
355
356bool ConstPoolArray::equals(const ConstPoolVal *V) const {
357 assert(getType() == V->getType());
358 ConstPoolArray *AV = (ConstPoolArray*)V;
359 if (Val.size() != AV->Val.size()) return false;
360 for (unsigned i = 0; i < Val.size(); i++)
361 if (!Val[i]->equals(AV->Val[i])) return false;
362
363 return true;
364}
365
366bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
367 assert(getType() == V->getType());
368 ConstPoolStruct *SV = (ConstPoolStruct*)V;
369 if (Val.size() != SV->Val.size()) return false;
370 for (unsigned i = 0; i < Val.size(); i++)
371 if (!Val[i]->equals(SV->Val[i])) return false;
372
373 return true;
374}
375
376//===----------------------------------------------------------------------===//
377// isValueValidForType implementations
378
379bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
380 switch (Ty->getPrimitiveID()) {
381 default:
382 return false; // These can't be represented as integers!!!
383
384 // Signed types...
385 case Type::SByteTyID:
386 return (Val <= INT8_MAX && Val >= INT8_MIN);
387 case Type::ShortTyID:
388 return (Val <= INT16_MAX && Val >= INT16_MIN);
389 case Type::IntTyID:
390 return (Val <= INT32_MAX && Val >= INT32_MIN);
391 case Type::LongTyID:
392 return true; // This is the largest type...
393 }
394 assert(0 && "WTF?");
395 return false;
396}
397
398bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
399 switch (Ty->getPrimitiveID()) {
400 default:
401 return false; // These can't be represented as integers!!!
402
403 // Unsigned types...
404 case Type::UByteTyID:
405 return (Val <= UINT8_MAX);
406 case Type::UShortTyID:
407 return (Val <= UINT16_MAX);
408 case Type::UIntTyID:
409 return (Val <= UINT32_MAX);
410 case Type::ULongTyID:
411 return true; // This is the largest type...
412 }
413 assert(0 && "WTF?");
414 return false;
415}
416
417bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
418 switch (Ty->getPrimitiveID()) {
419 default:
420 return false; // These can't be represented as floating point!
421
422 // TODO: Figure out how to test if a double can be cast to a float!
423 /*
424 case Type::FloatTyID:
425 return (Val <= UINT8_MAX);
426 */
427 case Type::DoubleTyID:
428 return true; // This is the largest type...
429 }
430};