X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=5d7c35f232d0efd87df8c518875df1df3bd23452;hb=f6ffcb6b713c259992b68d6b328f1b806775b9fb;hp=68a3c83aec87ed893090532a4099c58e5db2c6c5;hpb=4d2da0d7a74f1648ef7d4946ae87ec3e6b3209cf;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 68a3c83aec8..5d7c35f232d 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -4,7 +4,6 @@ // //===----------------------------------------------------------------------===// -#define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends... #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/iMemory.h" @@ -18,8 +17,6 @@ using std::map; using std::pair; using std::make_pair; using std::vector; -using std::cerr; -using std::endl; ConstantBool *ConstantBool::True = new ConstantBool(true); ConstantBool *ConstantBool::False = new ConstantBool(false); @@ -36,6 +33,34 @@ void Constant::setName(const std::string &Name, SymbolTable *ST) { if (Name.size()) ST->insert(Name, this); } +void Constant::destroyConstantImpl() { + // When a Constant is destroyed, there may be lingering + // references to the constant by other constants in the constant pool. These + // constants are implicitly dependant on the module that is being deleted, + // but they don't know that. Because we only find out when the CPV is + // deleted, we must now notify all of our users (that should only be + // Constants) that they are, in fact, invalid now and should be deleted. + // + while (!use_empty()) { + Value *V = use_back(); +#ifndef NDEBUG // Only in -g mode... + if (!isa(V)) + std::cerr << "While deleting: " << *this + << "\n\nUse still stuck around after Def is destroyed: " + << *V << "\n\n"; +#endif + assert(isa(V) && "References remain to Constant being destroyed"); + Constant *CPV = cast(V); + CPV->destroyConstant(); + + // The constant should remove itself from our use list... + assert((use_empty() || use_back() != V) && "Constant not removed!"); + } + + // Value has no outstanding references it is safe to delete it now... + delete this; +} + // Static constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(const Type *Ty) { switch (Ty->getPrimitiveID()) { @@ -60,37 +85,78 @@ Constant *Constant::getNullValue(const Type *Ty) { } } -void Constant::destroyConstantImpl() { - // When a Constant is destroyed, there may be lingering - // references to the constant by other constants in the constant pool. These - // constants are implicitly dependant on the module that is being deleted, - // but they don't know that. Because we only find out when the CPV is - // deleted, we must now notify all of our users (that should only be - // Constants) that they are, in fact, invalid now and should be deleted. - // - while (!use_empty()) { - Value *V = use_back(); -#ifndef NDEBUG // Only in -g mode... - if (!isa(V)) { - std::cerr << "While deleting: "; - dump(); - std::cerr << "\nUse still stuck around after Def is destroyed: "; - V->dump(); - std::cerr << "\n"; - } -#endif - assert(isa(V) && "References remain to Constant being destroyed"); - Constant *CPV = cast(V); - CPV->destroyConstant(); +// Static constructor to create the maximum constant of an integral type... +ConstantIntegral *ConstantIntegral::getMaxValue(const Type *Ty) { + switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: return ConstantBool::True; + case Type::SByteTyID: + case Type::ShortTyID: + case Type::IntTyID: + case Type::LongTyID: { + // Calculate 011111111111111... + unsigned TypeBits = Ty->getPrimitiveSize()*8; + int64_t Val = INT64_MAX; // All ones + Val >>= 64-TypeBits; // Shift out unwanted 1 bits... + return ConstantSInt::get(Ty, Val); + } - // The constant should remove itself from our use list... - assert((use_empty() || use_back() != V) && "Constant not removed!"); + case Type::UByteTyID: + case Type::UShortTyID: + case Type::UIntTyID: + case Type::ULongTyID: return getAllOnesValue(Ty); + + default: return 0; } +} - // Value has no outstanding references it is safe to delete it now... - delete this; +// Static constructor to create the minimum constant for an integral type... +ConstantIntegral *ConstantIntegral::getMinValue(const Type *Ty) { + switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: return ConstantBool::False; + case Type::SByteTyID: + case Type::ShortTyID: + case Type::IntTyID: + case Type::LongTyID: { + // Calculate 1111111111000000000000 + unsigned TypeBits = Ty->getPrimitiveSize()*8; + int64_t Val = -1; // All ones + Val <<= TypeBits-1; // Shift over to the right spot + return ConstantSInt::get(Ty, Val); + } + + case Type::UByteTyID: + case Type::UShortTyID: + case Type::UIntTyID: + case Type::ULongTyID: return ConstantUInt::get(Ty, 0); + + default: return 0; + } +} + +// Static constructor to create an integral constant with all bits set +ConstantIntegral *ConstantIntegral::getAllOnesValue(const Type *Ty) { + switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: return ConstantBool::True; + case Type::SByteTyID: + case Type::ShortTyID: + case Type::IntTyID: + case Type::LongTyID: return ConstantSInt::get(Ty, -1); + + case Type::UByteTyID: + case Type::UShortTyID: + case Type::UIntTyID: + case Type::ULongTyID: { + // Calculate ~0 of the right type... + unsigned TypeBits = Ty->getPrimitiveSize()*8; + uint64_t Val = ~0ULL; // All ones + Val >>= 64-TypeBits; // Shift out unwanted 1 bits... + return ConstantUInt::get(Ty, Val); + } + default: return 0; + } } + //===----------------------------------------------------------------------===// // ConstantXXX Classes //===----------------------------------------------------------------------===// @@ -98,19 +164,23 @@ void Constant::destroyConstantImpl() { //===----------------------------------------------------------------------===// // Normal Constructors -ConstantBool::ConstantBool(bool V) : Constant(Type::BoolTy) { +ConstantBool::ConstantBool(bool V) : ConstantIntegral(Type::BoolTy) { Val = V; } -ConstantInt::ConstantInt(const Type *Ty, uint64_t V) : Constant(Ty) { +ConstantInt::ConstantInt(const Type *Ty, uint64_t V) : ConstantIntegral(Ty) { Val.Unsigned = V; } ConstantSInt::ConstantSInt(const Type *Ty, int64_t V) : ConstantInt(Ty, V) { + assert(Ty->isInteger() && Ty->isSigned() && + "Illegal type for unsigned integer constant!"); assert(isValueValidForType(Ty, V) && "Value too large for type!"); } ConstantUInt::ConstantUInt(const Type *Ty, uint64_t V) : ConstantInt(Ty, V) { + assert(Ty->isInteger() && Ty->isUnsigned() && + "Illegal type for unsigned integer constant!"); assert(isValueValidForType(Ty, V) && "Value too large for type!"); } @@ -143,21 +213,20 @@ ConstantPointerRef::ConstantPointerRef(GlobalValue *GV) Operands.push_back(Use(GV, this)); } -ConstantExpr::ConstantExpr(unsigned opCode, Constant *C, const Type *Ty) - : Constant(Ty), iType(opCode) { +ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) + : Constant(Ty), iType(Opcode) { Operands.push_back(Use(C, this)); } -ConstantExpr::ConstantExpr(unsigned opCode, Constant* C1, - Constant* C2, const Type *Ty) - : Constant(Ty), iType(opCode) { +ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + : Constant(C1->getType()), iType(Opcode) { Operands.push_back(Use(C1, this)); Operands.push_back(Use(C2, this)); } -ConstantExpr::ConstantExpr(unsigned opCode, Constant* C, - const std::vector& IdxList, const Type *Ty) - : Constant(Ty), iType(opCode) { +ConstantExpr::ConstantExpr(Constant *C, const std::vector &IdxList, + const Type *DestTy) + : Constant(DestTy), iType(Instruction::GetElementPtr) { Operands.reserve(1+IdxList.size()); Operands.push_back(Use(C, this)); for (unsigned i = 0, E = IdxList.size(); i != E; ++i) @@ -169,28 +238,32 @@ ConstantExpr::ConstantExpr(unsigned opCode, Constant* C, //===----------------------------------------------------------------------===// // classof implementations +bool ConstantIntegral::classof(const Constant *CPV) { + return CPV->getType()->isIntegral() && !isa(CPV); +} + bool ConstantInt::classof(const Constant *CPV) { - return CPV->getType()->isIntegral() && ! isa(CPV); + return CPV->getType()->isInteger() && !isa(CPV); } bool ConstantSInt::classof(const Constant *CPV) { - return CPV->getType()->isSigned() && ! isa(CPV); + return CPV->getType()->isSigned() && !isa(CPV); } bool ConstantUInt::classof(const Constant *CPV) { - return CPV->getType()->isUnsigned() && ! isa(CPV); + return CPV->getType()->isUnsigned() && !isa(CPV); } bool ConstantFP::classof(const Constant *CPV) { const Type *Ty = CPV->getType(); return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) && - ! isa(CPV)); + !isa(CPV)); } bool ConstantArray::classof(const Constant *CPV) { - return isa(CPV->getType()) && ! isa(CPV); + return isa(CPV->getType()) && !isa(CPV); } bool ConstantStruct::classof(const Constant *CPV) { - return isa(CPV->getType()) && ! isa(CPV); + return isa(CPV->getType()) && !isa(CPV); } bool ConstantPointer::classof(const Constant *CPV) { - return (isa(CPV->getType()) && ! isa(CPV)); + return (isa(CPV->getType()) && !isa(CPV)); } @@ -260,7 +333,7 @@ struct ValueMap { map Map; inline ConstantClass *get(const Type *Ty, ValType V) { - map::iterator I = + typename map::iterator I = Map.find(ConstHashKey(Ty, V)); return (I != Map.end()) ? I->second : 0; } @@ -270,7 +343,7 @@ struct ValueMap { } inline void remove(ConstantClass *CP) { - for (map::iterator I = Map.begin(), + for (typename map::iterator I = Map.begin(), E = Map.end(); I != E;++I) if (I->second == CP) { Map.erase(I); @@ -351,6 +424,24 @@ void ConstantArray::destroyConstant() { destroyConstantImpl(); } +// getAsString - If the sub-element type of this array is either sbyte or ubyte, +// then this method converts the array to an std::string and returns it. +// Otherwise, it asserts out. +// +std::string ConstantArray::getAsString() const { + std::string Result; + if (getType()->getElementType() == Type::SByteTy) + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + Result += (char)cast(getOperand(i))->getValue(); + else { + assert(getType()->getElementType() == Type::UByteTy && "Not a string!"); + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + Result += (char)cast(getOperand(i))->getValue(); + } + return Result; +} + + //---- ConstantStruct::get() implementation... // static ValueMap, ConstantStruct> StructConstants; @@ -370,6 +461,7 @@ void ConstantStruct::destroyConstant() { destroyConstantImpl(); } + //---- ConstantPointerNull::get() implementation... // static ValueMap NullPtrConstants; @@ -381,6 +473,14 @@ ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { return Result; } +// destroyConstant - Remove the constant from the constant table... +// +void ConstantPointerNull::destroyConstant() { + NullPtrConstants.remove(this); + destroyConstantImpl(); +} + + //---- ConstantPointerRef::get() implementation... // ConstantPointerRef *ConstantPointerRef::get(GlobalValue *GV) { @@ -390,120 +490,80 @@ ConstantPointerRef *ConstantPointerRef::get(GlobalValue *GV) { return GV->getParent()->getConstantPointerRef(GV); } +// destroyConstant - Remove the constant from the constant table... +// +void ConstantPointerRef::destroyConstant() { + getValue()->getParent()->destroyConstantPointerRef(this); + destroyConstantImpl(); +} + + //---- ConstantExpr::get() implementations... -// Return NULL on invalid expressions. // typedef pair > ExprMapKeyType; static ValueMap ExprConstants; -ConstantExpr* -ConstantExpr::get(unsigned opCode, Constant *C, const Type *Ty) { +ConstantExpr *ConstantExpr::getCast(Constant *C, const Type *Ty) { // Look up the constant in the table first to ensure uniqueness vector argVec(1, C); - const ExprMapKeyType& key = make_pair(opCode, argVec); - ConstantExpr* result = ExprConstants.get(Ty, key); - if (result) - return result; + const ExprMapKeyType &Key = make_pair(Instruction::Cast, argVec); + ConstantExpr *Result = ExprConstants.get(Ty, Key); + if (Result) return Result; // Its not in the table so create a new one and put it in the table. - // Check the operands for consistency first - if (opCode != Instruction::Cast && - (opCode < Instruction::FirstUnaryOp || - opCode >= Instruction::NumUnaryOps)) { - std::cerr << "Invalid opcode " << ConstantExpr::getOpcodeName(opCode) - << " in unary constant expression" << std::endl; - return NULL; // Not Cast or other unary opcode - } - // type of operand will not match result for Cast operation - if (opCode != Instruction::Cast && Ty != C->getType()) { - cerr << "Type of operand in unary constant expression should match result" << endl; - return NULL; - } - - result = new ConstantExpr(opCode, C, Ty); - ExprConstants.add(Ty, key, result); - return result; + Result = new ConstantExpr(Instruction::Cast, C, Ty); + ExprConstants.add(Ty, Key, Result); + return Result; } -ConstantExpr* -ConstantExpr::get(unsigned opCode, Constant *C1, Constant *C2,const Type *Ty) { - +ConstantExpr *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { // Look up the constant in the table first to ensure uniqueness vector argVec(1, C1); argVec.push_back(C2); - const ExprMapKeyType& key = make_pair(opCode, argVec); - ConstantExpr* result = ExprConstants.get(Ty, key); - if (result) - return result; + const ExprMapKeyType &Key = make_pair(Opcode, argVec); + ConstantExpr *Result = ExprConstants.get(C1->getType(), Key); + if (Result) return Result; // Its not in the table so create a new one and put it in the table. // Check the operands for consistency first - if (opCode < Instruction::FirstBinaryOp || - opCode >= Instruction::NumBinaryOps) { - cerr << "Invalid opcode " << ConstantExpr::getOpcodeName(opCode) - << " in binary constant expression" << endl; - return NULL; - } - if (Ty != C1->getType() || Ty != C2->getType()) { - cerr << "Types of both operands in binary constant expression should match result" << endl; - return NULL; - } + assert((Opcode >= Instruction::FirstBinaryOp && + Opcode < Instruction::NumBinaryOps) && + "Invalid opcode in binary constant expression"); + + assert(C1->getType() == C2->getType() && + "Operand types in binary constant expression should match"); - result = new ConstantExpr(opCode, C1, C2, Ty); - ExprConstants.add(Ty, key, result); - return result; + Result = new ConstantExpr(Opcode, C1, C2); + ExprConstants.add(C1->getType(), Key, Result); + return Result; } -ConstantExpr* -ConstantExpr::get(unsigned opCode, Constant*C, - const std::vector& idxList, const Type *Ty) { +ConstantExpr *ConstantExpr::getGetElementPtr(Constant *C, + const std::vector &IdxList) { + const Type *Ty = C->getType(); // Look up the constant in the table first to ensure uniqueness vector argVec(1, C); - for(vector::const_iterator VI=idxList.begin(), VE=idxList.end(); - VI != VE; ++VI) - if (Constant *C = dyn_cast(*VI)) - argVec.push_back(C); - else { - cerr << "Non-constant index in constant GetElementPtr expr"; - return NULL; - } - - const ExprMapKeyType& key = make_pair(opCode, argVec); - ConstantExpr* result = ExprConstants.get(Ty, key); - if (result) - return result; + argVec.insert(argVec.end(), IdxList.begin(), IdxList.end()); + const ExprMapKeyType &Key = make_pair(Instruction::GetElementPtr, argVec); + ConstantExpr *Result = ExprConstants.get(Ty, Key); + if (Result) return Result; + // Its not in the table so create a new one and put it in the table. // Check the operands for consistency first - // Must be a getElementPtr. Check for valid getElementPtr expression. // - if (opCode != Instruction::GetElementPtr) { - cerr << "operator other than GetElementPtr used with an index list" << endl; - return NULL; - } - if (!isa(C)) { - cerr << "Constant GelElementPtr expression using something other than a constant pointer" << endl; - return NULL; - } - if (!isa(Ty)) { - cerr << "Non-pointer type for constant GelElementPtr expression" << endl; - return NULL; - } - const Type* fldType = GetElementPtrInst::getIndexedType(C->getType(), - idxList, true); - if (!fldType) { - cerr << "Invalid index list for constant GelElementPtr expression" << endl; - return NULL; - } - if (cast(Ty)->getElementType() != fldType) { - cerr << "Type for constant GelElementPtr expression does not match field type" << endl; - return NULL; - } + assert(isa(Ty) && + "Non-pointer type for constant GelElementPtr expression"); + + // Check that the indices list is valid... + std::vector ValIdxList(IdxList.begin(), IdxList.end()); + const Type *DestTy = GetElementPtrInst::getIndexedType(Ty, ValIdxList, true); + assert(DestTy && "Invalid index list for constant GelElementPtr expression"); - result = new ConstantExpr(opCode, C, idxList, Ty); - ExprConstants.add(Ty, key, result); - return result; + Result = new ConstantExpr(C, IdxList, PointerType::get(DestTy)); + ExprConstants.add(Ty, Key, Result); + return Result; } // destroyConstant - Remove the constant from the constant table... @@ -513,18 +573,16 @@ void ConstantExpr::destroyConstant() { destroyConstantImpl(); } -const char* -ConstantExpr::getOpcodeName(unsigned opCode) { - return Instruction::getOpcodeName(opCode); +const char *ConstantExpr::getOpcodeName() const { + return Instruction::getOpcodeName(getOpcode()); } //---- ConstantPointerRef::mutateReferences() implementation... // -unsigned -ConstantPointerRef::mutateReferences(Value* OldV, Value *NewV) { +unsigned ConstantPointerRef::mutateReferences(Value *OldV, Value *NewV) { assert(getValue() == OldV && "Cannot mutate old value if I'm not using it!"); - GlobalValue* NewGV = cast(NewV); + GlobalValue *NewGV = cast(NewV); getValue()->getParent()->mutateConstantPointerRef(getValue(), NewGV); Operands[0] = NewGV; return 1; @@ -533,14 +591,13 @@ ConstantPointerRef::mutateReferences(Value* OldV, Value *NewV) { //---- ConstantPointerExpr::mutateReferences() implementation... // -unsigned -ConstantExpr::mutateReferences(Value* OldV, Value *NewV) { - unsigned numReplaced = 0; - Constant* NewC = cast(NewV); - for (unsigned i=0, N = getNumOperands(); i < N; ++i) +unsigned ConstantExpr::mutateReferences(Value* OldV, Value *NewV) { + unsigned NumReplaced = 0; + Constant *NewC = cast(NewV); + for (unsigned i = 0, N = getNumOperands(); i != N; ++i) if (Operands[i] == OldV) { - ++numReplaced; + ++NumReplaced; Operands[i] = NewC; } - return numReplaced; + return NumReplaced; }