summaryrefslogtreecommitdiff
path: root/lib/VMCore/ConstantPool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore/ConstantPool.cpp')
-rw-r--r--lib/VMCore/ConstantPool.cpp434
1 files changed, 434 insertions, 0 deletions
diff --git a/lib/VMCore/ConstantPool.cpp b/lib/VMCore/ConstantPool.cpp
new file mode 100644
index 0000000000..d624c8dad0
--- /dev/null
+++ b/lib/VMCore/ConstantPool.cpp
@@ -0,0 +1,434 @@
+//===-- iConstPool.cpp - Implement ConstPool instructions --------*- C++ -*--=//
+//
+// This file implements the ConstPool* classes...
+//
+//===----------------------------------------------------------------------===//
+
+#define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends...
+#include "llvm/ConstPoolVals.h"
+#include "llvm/ConstantPool.h"
+#include "llvm/Tools/StringExtras.h" // itostr
+#include "llvm/DerivedTypes.h"
+#include "llvm/SymbolTable.h"
+#include <algorithm>
+#include <assert.h>
+
+//===----------------------------------------------------------------------===//
+// ConstantPool Class
+//===----------------------------------------------------------------------===//
+
+void ConstantPool::setParent(SymTabValue *STV) {
+ Parent = STV;
+ for (unsigned i = 0; i < Planes.size(); i++)
+ Planes[i]->setParent(Parent);
+}
+
+// Constant getPlane - Returns true if the type plane does not exist, otherwise
+// updates the pointer to point to the correct plane.
+//
+bool ConstantPool::getPlane(const Type *T, const PlaneType *&Plane) const {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) return true;
+ Plane = Planes[Ty];
+ return false;
+}
+
+// Constant getPlane - Returns true if the type plane does not exist, otherwise
+// updates the pointer to point to the correct plane.
+//
+bool ConstantPool::getPlane(const Type *T, PlaneType *&Plane) {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) return true;
+ Plane = Planes[Ty];
+ return false;
+}
+
+void ConstantPool::resize(unsigned size) {
+ unsigned oldSize = Planes.size();
+ Planes.resize(size, 0);
+ while (oldSize < size)
+ Planes[oldSize++] = new PlaneType(Parent, Parent);
+}
+
+ConstantPool::PlaneType &ConstantPool::getPlane(const Type *T) {
+ unsigned Ty = T->getUniqueID();
+ if (Ty >= Planes.size()) resize(Ty+1);
+ return *Planes[Ty];
+}
+
+// insert - Add constant into the symbol table...
+void ConstantPool::insert(ConstPoolVal *N) {
+ unsigned Ty = N->getType()->getUniqueID();
+ if (Ty >= Planes.size()) resize(Ty+1);
+ Planes[Ty]->push_back(N);
+}
+
+bool ConstantPool::remove(ConstPoolVal *N) {
+ unsigned Ty = N->getType()->getUniqueID();
+ if (Ty >= Planes.size()) return true; // Doesn't contain any of that type
+
+ PlaneType::iterator I = ::find(Planes[Ty]->begin(), Planes[Ty]->end(), N);
+ if (I == Planes[Ty]->end()) return true;
+ Planes[Ty]->remove(I);
+ return false;
+}
+
+void ConstantPool::delete_all() {
+ dropAllReferences();
+ for (unsigned i = 0; i < Planes.size(); i++) {
+ Planes[i]->delete_all();
+ Planes[i]->setParent(0);
+ delete Planes[i];
+ }
+ Planes.clear();
+}
+
+void ConstantPool::dropAllReferences() {
+ for (unsigned i = 0; i < Planes.size(); i++)
+ for (PlaneType::iterator I = Planes[i]->begin();
+ I != Planes[i]->end(); I++)
+ (*I)->dropAllReferences();
+}
+
+struct EqualsConstant {
+ const ConstPoolVal *v;
+ inline EqualsConstant(const ConstPoolVal *V) { v = V; }
+ inline bool operator()(const ConstPoolVal *V) const {
+ return v->equals(V);
+ }
+};
+
+
+ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) {
+ const PlaneType *P;
+ if (getPlane(V->getType(), P)) return 0;
+ PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
+ EqualsConstant(V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+const ConstPoolVal *ConstantPool::find(const ConstPoolVal *V) const {
+ const PlaneType *P;
+ if (getPlane(V->getType(), P)) return 0;
+ PlaneType::const_iterator PI = find_if(P->begin(), P->end(),
+ EqualsConstant(V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+ConstPoolVal *ConstantPool::find(const Type *Ty) {
+ const PlaneType *P;
+ if (getPlane(Type::TypeTy, P)) return 0;
+
+ // TODO: This is kinda silly
+ ConstPoolType V(Ty);
+
+ PlaneType::const_iterator PI =
+ find_if(P->begin(), P->end(), EqualsConstant(&V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+const ConstPoolVal *ConstantPool::find(const Type *Ty) const {
+ const PlaneType *P;
+ if (getPlane(Type::TypeTy, P)) return 0;
+
+ // TODO: This is kinda silly
+ ConstPoolType V(Ty);
+
+ PlaneType::const_iterator PI =
+ find_if(P->begin(), P->end(), EqualsConstant(&V));
+ if (PI == P->end()) return 0;
+ return *PI;
+}
+
+//===----------------------------------------------------------------------===//
+// ConstPoolVal Class
+//===----------------------------------------------------------------------===//
+
+// Specialize setName to take care of symbol table majik
+void ConstPoolVal::setName(const string &name) {
+ SymTabValue *P;
+ if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
+ Value::setName(name);
+ if (P && hasName()) P->getSymbolTable()->insert(this);
+}
+
+// Static constructor to create a '0' constant of arbitrary type...
+ConstPoolVal *ConstPoolVal::getNullConstant(const Type *Ty) {
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID: return new ConstPoolBool(false);
+ case Type::SByteTyID:
+ case Type::ShortTyID:
+ case Type::IntTyID:
+ case Type::LongTyID: return new ConstPoolSInt(Ty, 0);
+
+ case Type::UByteTyID:
+ case Type::UShortTyID:
+ case Type::UIntTyID:
+ case Type::ULongTyID: return new ConstPoolUInt(Ty, 0);
+
+ case Type::FloatTyID:
+ case Type::DoubleTyID: return new ConstPoolFP(Ty, 0);
+ default:
+ return 0;
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// ConstPoolXXX Classes
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Normal Constructors
+
+ConstPoolBool::ConstPoolBool(bool V, const string &Name = "")
+ : ConstPoolVal(Type::BoolTy, Name) {
+ Val = V;
+}
+
+ConstPoolSInt::ConstPoolSInt(const Type *Ty, int64_t V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ //cerr << "value = " << (int)V << ": " << Ty->getName() << endl;
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolUInt::ConstPoolUInt(const Type *Ty, uint64_t V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ //cerr << "Uvalue = " << (int)V << ": " << Ty->getName() << endl;
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolFP::ConstPoolFP(const Type *Ty, double V, const string &Name)
+ : ConstPoolVal(Ty, Name) {
+ assert(isValueValidForType(Ty, V) && "Value to large for type!");
+ Val = V;
+}
+
+ConstPoolType::ConstPoolType(const Type *V, const string &Name)
+ : ConstPoolVal(Type::TypeTy, Name), Val(V) {
+}
+
+ConstPoolArray::ConstPoolArray(const ArrayType *T,
+ vector<ConstPoolVal*> &V,
+ const string &Name)
+ : ConstPoolVal(T, Name) {
+ for (unsigned i = 0; i < V.size(); i++) {
+ assert(V[i]->getType() == T->getElementType());
+ Val.push_back(ConstPoolUse(V[i], this));
+ }
+}
+
+ConstPoolStruct::ConstPoolStruct(const StructType *T,
+ vector<ConstPoolVal*> &V,
+ const string &Name)
+ : ConstPoolVal(T, Name) {
+ const StructType::ElementTypes &ETypes = T->getElementTypes();
+
+ for (unsigned i = 0; i < V.size(); i++) {
+ assert(V[i]->getType() == ETypes[i]);
+ Val.push_back(ConstPoolUse(V[i], this));
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Copy Constructors
+
+ConstPoolBool::ConstPoolBool(const ConstPoolBool &CPB)
+ : ConstPoolVal(Type::BoolTy) {
+ Val = CPB.Val;
+}
+
+ConstPoolSInt::ConstPoolSInt(const ConstPoolSInt &CPSI)
+ : ConstPoolVal(CPSI.getType()) {
+ Val = CPSI.Val;
+}
+
+ConstPoolUInt::ConstPoolUInt(const ConstPoolUInt &CPUI)
+ : ConstPoolVal(CPUI.getType()) {
+ Val = CPUI.Val;
+}
+
+ConstPoolFP::ConstPoolFP(const ConstPoolFP &CPFP)
+ : ConstPoolVal(CPFP.getType()) {
+ Val = CPFP.Val;
+}
+
+ConstPoolType::ConstPoolType(const ConstPoolType &CPT)
+ : ConstPoolVal(Type::TypeTy), Val(CPT.Val) {
+}
+
+ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
+ : ConstPoolVal(CPA.getType()) {
+ for (unsigned i = 0; i < CPA.Val.size(); i++)
+ Val.push_back(ConstPoolUse((ConstPoolVal*)CPA.Val[i], this));
+}
+
+ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
+ : ConstPoolVal(CPS.getType()) {
+ for (unsigned i = 0; i < CPS.Val.size(); i++)
+ Val.push_back(ConstPoolUse((ConstPoolVal*)CPS.Val[i], this));
+}
+
+//===----------------------------------------------------------------------===//
+// getStrValue implementations
+
+string ConstPoolBool::getStrValue() const {
+ if (Val)
+ return "true";
+ else
+ return "false";
+}
+
+string ConstPoolSInt::getStrValue() const {
+ return itostr(Val);
+}
+
+string ConstPoolUInt::getStrValue() const {
+ return utostr(Val);
+}
+
+string ConstPoolFP::getStrValue() const {
+ assert(0 && "FP Constants Not implemented yet!!!!!!!!!!!");
+ return "% FP Constants NI!" /* + dtostr(Val)*/;
+}
+
+string ConstPoolType::getStrValue() const {
+ return Val->getName();
+}
+
+string ConstPoolArray::getStrValue() const {
+ string Result = "[";
+ if (Val.size()) {
+ Result += " " + Val[0]->getType()->getName() +
+ " " + Val[0]->getStrValue();
+ for (unsigned i = 1; i < Val.size(); i++)
+ Result += ", " + Val[i]->getType()->getName() +
+ " " + Val[i]->getStrValue();
+ }
+
+ return Result + " ]";
+}
+
+string ConstPoolStruct::getStrValue() const {
+ string Result = "{";
+ if (Val.size()) {
+ Result += " " + Val[0]->getType()->getName() +
+ " " + Val[0]->getStrValue();
+ for (unsigned i = 1; i < Val.size(); i++)
+ Result += ", " + Val[i]->getType()->getName() +
+ " " + Val[i]->getStrValue();
+ }
+
+ return Result + " }";
+}
+
+//===----------------------------------------------------------------------===//
+// equals implementations
+
+bool ConstPoolBool::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolBool*)V)->getValue() == Val;
+}
+
+bool ConstPoolSInt::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolSInt*)V)->getValue() == Val;
+}
+
+bool ConstPoolUInt::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolUInt*)V)->getValue() == Val;
+}
+
+bool ConstPoolFP::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolFP*)V)->getValue() == Val;
+}
+
+bool ConstPoolType::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ return ((ConstPoolType*)V)->getValue() == Val;
+}
+
+bool ConstPoolArray::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ ConstPoolArray *AV = (ConstPoolArray*)V;
+ if (Val.size() != AV->Val.size()) return false;
+ for (unsigned i = 0; i < Val.size(); i++)
+ if (!Val[i]->equals(AV->Val[i])) return false;
+
+ return true;
+}
+
+bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
+ assert(getType() == V->getType());
+ ConstPoolStruct *SV = (ConstPoolStruct*)V;
+ if (Val.size() != SV->Val.size()) return false;
+ for (unsigned i = 0; i < Val.size(); i++)
+ if (!Val[i]->equals(SV->Val[i])) return false;
+
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// isValueValidForType implementations
+
+bool ConstPoolSInt::isValueValidForType(const Type *Ty, int64_t Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as integers!!!
+
+ // Signed types...
+ case Type::SByteTyID:
+ return (Val <= INT8_MAX && Val >= INT8_MIN);
+ case Type::ShortTyID:
+ return (Val <= INT16_MAX && Val >= INT16_MIN);
+ case Type::IntTyID:
+ return (Val <= INT32_MAX && Val >= INT32_MIN);
+ case Type::LongTyID:
+ return true; // This is the largest type...
+ }
+ assert(0 && "WTF?");
+ return false;
+}
+
+bool ConstPoolUInt::isValueValidForType(const Type *Ty, uint64_t Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as integers!!!
+
+ // Unsigned types...
+ case Type::UByteTyID:
+ return (Val <= UINT8_MAX);
+ case Type::UShortTyID:
+ return (Val <= UINT16_MAX);
+ case Type::UIntTyID:
+ return (Val <= UINT32_MAX);
+ case Type::ULongTyID:
+ return true; // This is the largest type...
+ }
+ assert(0 && "WTF?");
+ return false;
+}
+
+bool ConstPoolFP::isValueValidForType(const Type *Ty, double Val) {
+ switch (Ty->getPrimitiveID()) {
+ default:
+ return false; // These can't be represented as floating point!
+
+ // TODO: Figure out how to test if a double can be cast to a float!
+ /*
+ case Type::FloatTyID:
+ return (Val <= UINT8_MAX);
+ */
+ case Type::DoubleTyID:
+ return true; // This is the largest type...
+ }
+};