X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=b96257936df880144dd7495f15f8c2f2dd1f70dd;hb=2f87640b86315beab8a5671cc23f524e59c58bd3;hp=15d7793d589394ea67f34128d85b00497f1824c9;hpb=ddcdcc88631c6bd4ad43d9198b98bc9a829be036;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 15d7793d589..b96257936df 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include #include using namespace llvm; @@ -39,11 +40,60 @@ using namespace llvm; // Constant Class //===----------------------------------------------------------------------===// +void Constant::anchor() { } + +bool Constant::isNegativeZeroValue() const { + // Floating point values have an explicit -0.0 value. + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->isZero() && CFP->isNegative(); + + // Otherwise, just use +0.0. + return isNullValue(); +} + +bool Constant::isNullValue() const { + // 0 is null. + if (const ConstantInt *CI = dyn_cast(this)) + return CI->isZero(); + + // +0.0 is null. + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->isZero() && !CFP->isNegative(); + + // constant zero is zero for aggregates and cpnull is null for pointers. + return isa(this) || isa(this); +} + +bool Constant::isAllOnesValue() const { + // Check for -1 integers + if (const ConstantInt *CI = dyn_cast(this)) + return CI->isMinusOne(); + + // Check for FP which are bitcasted from -1 integers + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->getValueAPF().bitcastToAPInt().isAllOnesValue(); + + // Check for constant vectors which are splats of -1 values. + if (const ConstantVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isAllOnesValue(); + + // Check for constant vectors which are splats of -1 values. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isAllOnesValue(); + + return false; +} + // Constructor to create a '0' constant of arbitrary type... -Constant *Constant::getNullValue(const Type *Ty) { +Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); + case Type::HalfTyID: + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEhalf)); case Type::FloatTyID: return ConstantFP::get(Ty->getContext(), APFloat::getZero(APFloat::IEEEsingle)); @@ -67,30 +117,29 @@ Constant *Constant::getNullValue(const Type *Ty) { return ConstantAggregateZero::get(Ty); default: // Function, Label, or Opaque type? - assert(!"Cannot create a null constant of that type!"); - return 0; + llvm_unreachable("Cannot create a null constant of that type!"); } } -Constant *Constant::getIntegerValue(const Type *Ty, const APInt &V) { - const Type *ScalarTy = Ty->getScalarType(); +Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) { + Type *ScalarTy = Ty->getScalarType(); // Create the base integer constant. Constant *C = ConstantInt::get(Ty->getContext(), V); // Convert an integer to a pointer, if necessary. - if (const PointerType *PTy = dyn_cast(ScalarTy)) + if (PointerType *PTy = dyn_cast(ScalarTy)) C = ConstantExpr::getIntToPtr(C, PTy); // Broadcast a scalar to a vector, if necessary. - if (const VectorType *VTy = dyn_cast(Ty)) - C = ConstantVector::get(std::vector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + C = ConstantVector::getSplat(VTy->getNumElements(), C); return C; } -Constant *Constant::getAllOnesValue(const Type *Ty) { - if (const IntegerType *ITy = dyn_cast(Ty)) +Constant *Constant::getAllOnesValue(Type *Ty) { + if (IntegerType *ITy = dyn_cast(Ty)) return ConstantInt::get(Ty->getContext(), APInt::getAllOnesValue(ITy->getBitWidth())); @@ -100,13 +149,44 @@ Constant *Constant::getAllOnesValue(const Type *Ty) { return ConstantFP::get(Ty->getContext(), FL); } - SmallVector Elts; - const VectorType *VTy = cast(Ty); - Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); - assert(Elts[0] && "Not a vector integer type!"); - return cast(ConstantVector::get(Elts)); + VectorType *VTy = cast(Ty); + return ConstantVector::getSplat(VTy->getNumElements(), + getAllOnesValue(VTy->getElementType())); +} + +/// getAggregateElement - For aggregates (struct/array/vector) return the +/// constant that corresponds to the specified element if possible, or null if +/// not. This can return null if the element index is a ConstantExpr, or if +/// 'this' is a constant expr. +Constant *Constant::getAggregateElement(unsigned Elt) const { + if (const ConstantStruct *CS = dyn_cast(this)) + return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : 0; + + if (const ConstantArray *CA = dyn_cast(this)) + return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : 0; + + if (const ConstantVector *CV = dyn_cast(this)) + return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : 0; + + if (const ConstantAggregateZero *CAZ =dyn_cast(this)) + return CAZ->getElementValue(Elt); + + if (const UndefValue *UV = dyn_cast(this)) + return UV->getElementValue(Elt); + + if (const ConstantDataSequential *CDS =dyn_cast(this)) + return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0; + return 0; +} + +Constant *Constant::getAggregateElement(Constant *Elt) const { + assert(isa(Elt->getType()) && "Index must be an integer"); + if (ConstantInt *CI = dyn_cast(Elt)) + return getAggregateElement(CI->getZExtValue()); + return 0; } + void Constant::destroyConstantImpl() { // When a Constant is destroyed, there may be lingering // references to the constant by other constants in the constant pool. These @@ -125,8 +205,7 @@ void Constant::destroyConstantImpl() { } #endif assert(isa(V) && "References remain to Constant being destroyed"); - Constant *CV = cast(V); - CV->destroyConstant(); + cast(V)->destroyConstant(); // The constant should remove itself from our use list... assert((use_empty() || use_back() != V) && "Constant not removed!"); @@ -143,10 +222,10 @@ bool Constant::canTrap() const { // The only thing that could possibly trap are constant exprs. const ConstantExpr *CE = dyn_cast(this); if (!CE) return false; - - // ConstantExpr traps if any operands can trap. + + // ConstantExpr traps if any operands can trap. for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (CE->getOperand(i)->canTrap()) + if (CE->getOperand(i)->canTrap()) return true; // Otherwise, only specific operations can trap. @@ -173,7 +252,7 @@ bool Constant::isConstantUsed() const { const Constant *UC = dyn_cast(*UI); if (UC == 0 || isa(UC)) return true; - + if (UC->isConstantUsed()) return true; } @@ -223,58 +302,28 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { cast(RHS->getOperand(0))->getFunction()) return NoRelocation; } - + PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) Result = std::max(Result, cast(getOperand(i))->getRelocationInfo()); - - return Result; -} - -/// getVectorElements - This method, which is only valid on constant of vector -/// type, returns the elements of the vector in the specified smallvector. -/// This handles breaking down a vector undef into undef elements, etc. For -/// constant exprs and other cases we can't handle, we return an empty vector. -void Constant::getVectorElements(SmallVectorImpl &Elts) const { - assert(getType()->isVectorTy() && "Not a vector constant!"); - - if (const ConstantVector *CV = dyn_cast(this)) { - for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) - Elts.push_back(CV->getOperand(i)); - return; - } - - const VectorType *VT = cast(getType()); - if (isa(this)) { - Elts.assign(VT->getNumElements(), - Constant::getNullValue(VT->getElementType())); - return; - } - - if (isa(this)) { - Elts.assign(VT->getNumElements(), UndefValue::get(VT->getElementType())); - return; - } - - // Unknown type, must be constant expr etc. + return Result; } - /// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove /// it. This involves recursively eliminating any dead users of the /// constantexpr. static bool removeDeadUsersOfConstant(const Constant *C) { if (isa(C)) return false; // Cannot remove this - + while (!C->use_empty()) { const Constant *User = dyn_cast(C->use_back()); if (!User) return false; // Non-constant usage; if (!removeDeadUsersOfConstant(User)) return false; // Constant wasn't dead } - + const_cast(C)->destroyConstant(); return true; } @@ -294,7 +343,7 @@ void Constant::removeDeadConstantUsers() const { ++I; continue; } - + if (!removeDeadUsersOfConstant(User)) { // If the constant wasn't dead, remember that this was the last live use // and move on to the next constant. @@ -302,7 +351,7 @@ void Constant::removeDeadConstantUsers() const { ++I; continue; } - + // If the constant was dead, then the iterator is invalidated. if (LastNonDeadUser == E) { I = use_begin(); @@ -320,7 +369,9 @@ void Constant::removeDeadConstantUsers() const { // ConstantInt //===----------------------------------------------------------------------===// -ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V) +void ConstantInt::anchor() { } + +ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V) : Constant(Ty, ConstantIntVal, 0, 0), Val(V) { assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } @@ -339,30 +390,28 @@ ConstantInt *ConstantInt::getFalse(LLVMContext &Context) { return pImpl->TheFalseVal; } -Constant *ConstantInt::getTrue(const Type *Ty) { - const VectorType *VTy = dyn_cast(Ty); +Constant *ConstantInt::getTrue(Type *Ty) { + VectorType *VTy = dyn_cast(Ty); if (!VTy) { assert(Ty->isIntegerTy(1) && "True must be i1 or vector of i1."); return ConstantInt::getTrue(Ty->getContext()); } assert(VTy->getElementType()->isIntegerTy(1) && "True must be vector of i1 or i1."); - SmallVector Splat(VTy->getNumElements(), - ConstantInt::getTrue(Ty->getContext())); - return ConstantVector::get(Splat); + return ConstantVector::getSplat(VTy->getNumElements(), + ConstantInt::getTrue(Ty->getContext())); } -Constant *ConstantInt::getFalse(const Type *Ty) { - const VectorType *VTy = dyn_cast(Ty); +Constant *ConstantInt::getFalse(Type *Ty) { + VectorType *VTy = dyn_cast(Ty); if (!VTy) { assert(Ty->isIntegerTy(1) && "False must be i1 or vector of i1."); return ConstantInt::getFalse(Ty->getContext()); } assert(VTy->getElementType()->isIntegerTy(1) && "False must be vector of i1 or i1."); - SmallVector Splat(VTy->getNumElements(), - ConstantInt::getFalse(Ty->getContext())); - return ConstantVector::get(Splat); + return ConstantVector::getSplat(VTy->getNumElements(), + ConstantInt::getFalse(Ty->getContext())); } @@ -373,7 +422,7 @@ Constant *ConstantInt::getFalse(const Type *Ty) { // invariant which generates an assertion. ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { // Get the corresponding integer type for the bit width of the value. - const IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); + IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); // get an existing value or the insertion position DenseMapAPIntKeyInfo::KeyTy Key(V, ITy); ConstantInt *&Slot = Context.pImpl->IntConstants[Key]; @@ -381,44 +430,42 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { return Slot; } -Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) { +Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) { Constant *C = get(cast(Ty->getScalarType()), V, isSigned); // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast(Ty)) - return ConstantVector::get(SmallVector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); return C; } -ConstantInt* ConstantInt::get(const IntegerType* Ty, uint64_t V, +ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) { return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned)); } -ConstantInt* ConstantInt::getSigned(const IntegerType* Ty, int64_t V) { +ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) { return get(Ty, V, true); } -Constant *ConstantInt::getSigned(const Type *Ty, int64_t V) { +Constant *ConstantInt::getSigned(Type *Ty, int64_t V) { return get(Ty, V, true); } -Constant *ConstantInt::get(const Type* Ty, const APInt& V) { +Constant *ConstantInt::get(Type *Ty, const APInt& V) { ConstantInt *C = get(Ty->getContext(), V); assert(C->getType() == Ty->getScalarType() && "ConstantInt type doesn't match the type implied by its value!"); // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast(Ty)) - return ConstantVector::get( - SmallVector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); return C; } -ConstantInt* ConstantInt::get(const IntegerType* Ty, StringRef Str, +ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) { return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); } @@ -427,7 +474,9 @@ ConstantInt* ConstantInt::get(const IntegerType* Ty, StringRef Str, // ConstantFP //===----------------------------------------------------------------------===// -static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { +static const fltSemantics *TypeToFloatSemantics(Type *Ty) { + if (Ty->isHalfTy()) + return &APFloat::IEEEhalf; if (Ty->isFloatTy()) return &APFloat::IEEEsingle; if (Ty->isDoubleTy()) @@ -436,17 +485,19 @@ static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { return &APFloat::x87DoubleExtended; else if (Ty->isFP128Ty()) return &APFloat::IEEEquad; - + assert(Ty->isPPC_FP128Ty() && "Unknown FP format"); return &APFloat::PPCDoubleDouble; } +void ConstantFP::anchor() { } + /// get() - This returns a constant fp for the specified value in the /// specified type. This should only be used for simple constant values like /// 2.0/1.0 etc, that are known-valid both as double and as the target format. -Constant *ConstantFP::get(const Type* Ty, double V) { +Constant *ConstantFP::get(Type *Ty, double V) { LLVMContext &Context = Ty->getContext(); - + APFloat FV(V); bool ignored; FV.convert(*TypeToFloatSemantics(Ty->getScalarType()), @@ -454,47 +505,43 @@ Constant *ConstantFP::get(const Type* Ty, double V) { Constant *C = get(Context, FV); // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast(Ty)) - return ConstantVector::get( - SmallVector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); return C; } -Constant *ConstantFP::get(const Type* Ty, StringRef Str) { +Constant *ConstantFP::get(Type *Ty, StringRef Str) { LLVMContext &Context = Ty->getContext(); APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str); Constant *C = get(Context, FV); // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast(Ty)) - return ConstantVector::get( - SmallVector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); return C; } -ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) { +ConstantFP *ConstantFP::getNegativeZero(Type *Ty) { LLVMContext &Context = Ty->getContext(); - APFloat apf = cast (Constant::getNullValue(Ty))->getValueAPF(); + APFloat apf = cast(Constant::getNullValue(Ty))->getValueAPF(); apf.changeSign(); return get(Context, apf); } -Constant *ConstantFP::getZeroValueForNegation(const Type* Ty) { - if (const VectorType *PTy = dyn_cast(Ty)) - if (PTy->getElementType()->isFloatingPointTy()) { - SmallVector zeros(PTy->getNumElements(), - getNegativeZero(PTy->getElementType())); - return ConstantVector::get(zeros); - } - - if (Ty->isFloatingPointTy()) - return getNegativeZero(Ty); +Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { + Type *ScalarTy = Ty->getScalarType(); + if (ScalarTy->isFloatingPointTy()) { + Constant *C = getNegativeZero(ScalarTy); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + return C; + } return Constant::getNullValue(Ty); } @@ -503,14 +550,16 @@ Constant *ConstantFP::getZeroValueForNegation(const Type* Ty) { // ConstantFP accessors. ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { DenseMapAPFloatKeyInfo::KeyTy Key(V); - + LLVMContextImpl* pImpl = Context.pImpl; - + ConstantFP *&Slot = pImpl->FPConstants[Key]; - + if (!Slot) { - const Type *Ty; - if (&V.getSemantics() == &APFloat::IEEEsingle) + Type *Ty; + if (&V.getSemantics() == &APFloat::IEEEhalf) + Ty = Type::getHalfTy(Context); + else if (&V.getSemantics() == &APFloat::IEEEsingle) Ty = Type::getFloatTy(Context); else if (&V.getSemantics() == &APFloat::IEEEdouble) Ty = Type::getDoubleTy(Context); @@ -525,180 +574,298 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { } Slot = new ConstantFP(Ty, V); } - + return Slot; } -ConstantFP *ConstantFP::getInfinity(const Type *Ty, bool Negative) { +ConstantFP *ConstantFP::getInfinity(Type *Ty, bool Negative) { const fltSemantics &Semantics = *TypeToFloatSemantics(Ty); return ConstantFP::get(Ty->getContext(), APFloat::getInf(Semantics, Negative)); } -ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) +ConstantFP::ConstantFP(Type *Ty, const APFloat& V) : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { assert(&V.getSemantics() == TypeToFloatSemantics(Ty) && "FP type Mismatch"); } -bool ConstantFP::isNullValue() const { - return Val.isZero() && !Val.isNegative(); +bool ConstantFP::isExactlyValue(const APFloat &V) const { + return Val.bitwiseIsEqual(V); } -bool ConstantFP::isExactlyValue(const APFloat& V) const { - return Val.bitwiseIsEqual(V); +//===----------------------------------------------------------------------===// +// ConstantAggregateZero Implementation +//===----------------------------------------------------------------------===// + +/// getSequentialElement - If this CAZ has array or vector type, return a zero +/// with the right element type. +Constant *ConstantAggregateZero::getSequentialElement() const { + return Constant::getNullValue(getType()->getSequentialElementType()); +} + +/// getStructElement - If this CAZ has struct type, return a zero with the +/// right element type for the specified element. +Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const { + return Constant::getNullValue(getType()->getStructElementType(Elt)); +} + +/// getElementValue - Return a zero of the right value for the specified GEP +/// index if we can, otherwise return null (e.g. if C is a ConstantExpr). +Constant *ConstantAggregateZero::getElementValue(Constant *C) const { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(cast(C)->getZExtValue()); +} + +/// getElementValue - Return a zero of the right value for the specified GEP +/// index. +Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(Idx); +} + + +//===----------------------------------------------------------------------===// +// UndefValue Implementation +//===----------------------------------------------------------------------===// + +/// getSequentialElement - If this undef has array or vector type, return an +/// undef with the right element type. +UndefValue *UndefValue::getSequentialElement() const { + return UndefValue::get(getType()->getSequentialElementType()); +} + +/// getStructElement - If this undef has struct type, return a zero with the +/// right element type for the specified element. +UndefValue *UndefValue::getStructElement(unsigned Elt) const { + return UndefValue::get(getType()->getStructElementType(Elt)); +} + +/// getElementValue - Return an undef of the right value for the specified GEP +/// index if we can, otherwise return null (e.g. if C is a ConstantExpr). +UndefValue *UndefValue::getElementValue(Constant *C) const { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(cast(C)->getZExtValue()); +} + +/// getElementValue - Return an undef of the right value for the specified GEP +/// index. +UndefValue *UndefValue::getElementValue(unsigned Idx) const { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(Idx); } + + //===----------------------------------------------------------------------===// // ConstantXXX Classes //===----------------------------------------------------------------------===// +template +static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) { + for (; Start != End; ++Start) + if (*Start != Elt) + return false; + return true; +} -ConstantArray::ConstantArray(const ArrayType *T, - const std::vector &V) +ConstantArray::ConstantArray(ArrayType *T, ArrayRef V) : Constant(T, ConstantArrayVal, OperandTraits::op_end(this) - V.size(), V.size()) { assert(V.size() == T->getNumElements() && "Invalid initializer vector for constant array"); - Use *OL = OperandList; - for (std::vector::const_iterator I = V.begin(), E = V.end(); - I != E; ++I, ++OL) { - Constant *C = *I; - assert(C->getType() == T->getElementType() && + for (unsigned i = 0, e = V.size(); i != e; ++i) + assert(V[i]->getType() == T->getElementType() && "Initializer for array element doesn't match array element type!"); - *OL = C; - } + std::copy(V.begin(), V.end(), op_begin()); } -Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector &V) { +Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { + // Empty arrays are canonicalized to ConstantAggregateZero. + if (V.empty()) + return ConstantAggregateZero::get(Ty); + for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); } LLVMContextImpl *pImpl = Ty->getContext().pImpl; - // If this is an all-zero array, return a ConstantAggregateZero object - if (!V.empty()) { - Constant *C = V[0]; - if (!C->isNullValue()) - return pImpl->ArrayConstants.getOrCreate(Ty, V); - - for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) - return pImpl->ArrayConstants.getOrCreate(Ty, V); + + // If this is an all-zero array, return a ConstantAggregateZero object. If + // all undef, return an UndefValue, if "all simple", then return a + // ConstantDataArray. + Constant *C = V[0]; + if (isa(C) && rangeOnlyContains(V.begin(), V.end(), C)) + return UndefValue::get(Ty); + + if (C->isNullValue() && rangeOnlyContains(V.begin(), V.end(), C)) + return ConstantAggregateZero::get(Ty); + + // Check to see if all of the elements are ConstantFP or ConstantInt and if + // the element type is compatible with ConstantDataVector. If so, use it. + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { + // We speculatively build the elements here even if it turns out that there + // is a constantexpr or something else weird in the array, since it is so + // uncommon for that to happen. + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getType()->isIntegerTy(8)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(16)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(32)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(64)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } + } + + if (ConstantFP *CFP = dyn_cast(C)) { + if (CFP->getType()->isFloatTy()) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantFP *CFP = dyn_cast(V[i])) + Elts.push_back(CFP->getValueAPF().convertToFloat()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } else if (CFP->getType()->isDoubleTy()) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantFP *CFP = dyn_cast(V[i])) + Elts.push_back(CFP->getValueAPF().convertToDouble()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataArray::get(C->getContext(), Elts); + } + } } - - return ConstantAggregateZero::get(Ty); + + // Otherwise, we really do want to create a ConstantArray. + return pImpl->ArrayConstants.getOrCreate(Ty, V); } +/// getTypeForElements - Return an anonymous struct type to use for a constant +/// with the specified set of elements. The list must not be empty. +StructType *ConstantStruct::getTypeForElements(LLVMContext &Context, + ArrayRef V, + bool Packed) { + unsigned VecSize = V.size(); + SmallVector EltTypes(VecSize); + for (unsigned i = 0; i != VecSize; ++i) + EltTypes[i] = V[i]->getType(); -Constant *ConstantArray::get(const ArrayType* T, Constant *const* Vals, - unsigned NumVals) { - // FIXME: make this the primary ctor method. - return get(T, std::vector(Vals, Vals+NumVals)); + return StructType::get(Context, EltTypes, Packed); } -/// ConstantArray::get(const string&) - Return an array that is initialized to -/// contain the specified string. If length is zero then a null terminator is -/// added to the specified string so that it may be used in a natural way. -/// Otherwise, the length parameter specifies how much of the string to use -/// and it won't be null terminated. -/// -Constant *ConstantArray::get(LLVMContext &Context, StringRef Str, - bool AddNull) { - std::vector ElementVals; - ElementVals.reserve(Str.size() + size_t(AddNull)); - for (unsigned i = 0; i < Str.size(); ++i) - ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i])); - - // Add a null terminator to the string... - if (AddNull) { - ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0)); - } - ArrayType *ATy = ArrayType::get(Type::getInt8Ty(Context), ElementVals.size()); - return get(ATy, ElementVals); +StructType *ConstantStruct::getTypeForElements(ArrayRef V, + bool Packed) { + assert(!V.empty() && + "ConstantStruct::getTypeForElements cannot be called on empty list"); + return getTypeForElements(V[0]->getContext(), V, Packed); } -ConstantStruct::ConstantStruct(const StructType *T, - const std::vector &V) + +ConstantStruct::ConstantStruct(StructType *T, ArrayRef V) : Constant(T, ConstantStructVal, OperandTraits::op_end(this) - V.size(), V.size()) { assert(V.size() == T->getNumElements() && "Invalid initializer vector for constant structure"); - Use *OL = OperandList; - for (std::vector::const_iterator I = V.begin(), E = V.end(); - I != E; ++I, ++OL) { - Constant *C = *I; - assert(C->getType() == T->getElementType(I-V.begin()) && + for (unsigned i = 0, e = V.size(); i != e; ++i) + assert((T->isOpaque() || V[i]->getType() == T->getElementType(i)) && "Initializer for struct element doesn't match struct element type!"); - *OL = C; - } + std::copy(V.begin(), V.end(), op_begin()); } // ConstantStruct accessors. -Constant *ConstantStruct::get(const StructType* T, - const std::vector& V) { - LLVMContextImpl* pImpl = T->getContext().pImpl; - - // Create a ConstantAggregateZero value if all elements are zeros... - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (!V[i]->isNullValue()) - return pImpl->StructConstants.getOrCreate(T, V); - - return ConstantAggregateZero::get(T); -} +Constant *ConstantStruct::get(StructType *ST, ArrayRef V) { + assert((ST->isOpaque() || ST->getNumElements() == V.size()) && + "Incorrect # elements specified to ConstantStruct::get"); -Constant *ConstantStruct::get(LLVMContext &Context, - const std::vector& V, bool packed) { - std::vector StructEls; - StructEls.reserve(V.size()); - for (unsigned i = 0, e = V.size(); i != e; ++i) - StructEls.push_back(V[i]->getType()); - return get(StructType::get(Context, StructEls, packed), V); -} + // Create a ConstantAggregateZero value if all elements are zeros. + bool isZero = true; + bool isUndef = false; + + if (!V.empty()) { + isUndef = isa(V[0]); + isZero = V[0]->isNullValue(); + if (isUndef || isZero) { + for (unsigned i = 0, e = V.size(); i != e; ++i) { + if (!V[i]->isNullValue()) + isZero = false; + if (!isa(V[i])) + isUndef = false; + } + } + } + if (isZero) + return ConstantAggregateZero::get(ST); + if (isUndef) + return UndefValue::get(ST); -Constant *ConstantStruct::get(LLVMContext &Context, - Constant *const *Vals, unsigned NumVals, - bool Packed) { - // FIXME: make this the primary ctor method. - return get(Context, std::vector(Vals, Vals+NumVals), Packed); + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V); } -Constant* ConstantStruct::get(LLVMContext &Context, bool Packed, - Constant * Val, ...) { +Constant *ConstantStruct::get(StructType *T, ...) { va_list ap; - std::vector Values; - va_start(ap, Val); - while (Val) { + SmallVector Values; + va_start(ap, T); + while (Constant *Val = va_arg(ap, llvm::Constant*)) Values.push_back(Val); - Val = va_arg(ap, llvm::Constant*); - } va_end(ap); - return get(Context, Values, Packed); + return get(T, Values); } -ConstantVector::ConstantVector(const VectorType *T, - const std::vector &V) +ConstantVector::ConstantVector(VectorType *T, ArrayRef V) : Constant(T, ConstantVectorVal, OperandTraits::op_end(this) - V.size(), V.size()) { - Use *OL = OperandList; - for (std::vector::const_iterator I = V.begin(), E = V.end(); - I != E; ++I, ++OL) { - Constant *C = *I; - assert(C->getType() == T->getElementType() && + for (size_t i = 0, e = V.size(); i != e; i++) + assert(V[i]->getType() == T->getElementType() && "Initializer for vector element doesn't match vector element type!"); - *OL = C; - } + std::copy(V.begin(), V.end(), op_begin()); } // ConstantVector accessors. -Constant *ConstantVector::get(const VectorType *T, - const std::vector &V) { +Constant *ConstantVector::get(ArrayRef V) { assert(!V.empty() && "Vectors can't be empty"); + VectorType *T = VectorType::get(V.front()->getType(), V.size()); LLVMContextImpl *pImpl = T->getContext().pImpl; // If this is an all-undef or all-zero vector, return a @@ -714,21 +881,98 @@ Constant *ConstantVector::get(const VectorType *T, break; } } - + if (isZero) return ConstantAggregateZero::get(T); if (isUndef) return UndefValue::get(T); - + + // Check to see if all of the elements are ConstantFP or ConstantInt and if + // the element type is compatible with ConstantDataVector. If so, use it. + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { + // We speculatively build the elements here even if it turns out that there + // is a constantexpr or something else weird in the array, since it is so + // uncommon for that to happen. + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getType()->isIntegerTy(8)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(16)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(32)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } else if (CI->getType()->isIntegerTy(64)) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantInt *CI = dyn_cast(V[i])) + Elts.push_back(CI->getZExtValue()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } + } + + if (ConstantFP *CFP = dyn_cast(C)) { + if (CFP->getType()->isFloatTy()) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantFP *CFP = dyn_cast(V[i])) + Elts.push_back(CFP->getValueAPF().convertToFloat()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } else if (CFP->getType()->isDoubleTy()) { + SmallVector Elts; + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (ConstantFP *CFP = dyn_cast(V[i])) + Elts.push_back(CFP->getValueAPF().convertToDouble()); + else + break; + if (Elts.size() == V.size()) + return ConstantDataVector::get(C->getContext(), Elts); + } + } + } + + // Otherwise, the element type isn't compatible with ConstantDataVector, or + // the operand list constants a ConstantExpr or something else strange. return pImpl->VectorConstants.getOrCreate(T, V); } -Constant *ConstantVector::get(ArrayRef V) { - // FIXME: make this the primary ctor method. - assert(!V.empty() && "Vectors cannot be empty"); - return get(VectorType::get(V.front()->getType(), V.size()), V.vec()); +Constant *ConstantVector::getSplat(unsigned NumElts, Constant *V) { + // If this splat is compatible with ConstantDataVector, use it instead of + // ConstantVector. + if ((isa(V) || isa(V)) && + ConstantDataSequential::isElementTypeCompatible(V->getType())) + return ConstantDataVector::getSplat(NumElts, V); + + SmallVector Elts(NumElts, V); + return get(Elts); } + // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into // Constant.h @@ -755,7 +999,7 @@ bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const { for (; GEPI != E; ++GEPI, ++OI) { ConstantInt *CI = dyn_cast(*OI); if (!CI) return false; - if (const ArrayType *ATy = dyn_cast(*GEPI)) + if (ArrayType *ATy = dyn_cast(*GEPI)) if (CI->getValue().getActiveBits() > 64 || CI->getZExtValue() >= ATy->getNumElements()) return false; @@ -779,8 +1023,7 @@ ArrayRef ConstantExpr::getIndices() const { } unsigned ConstantExpr::getPredicate() const { - assert(getOpcode() == Instruction::FCmp || - getOpcode() == Instruction::ICmp); + assert(isCompare()); return ((const CompareConstantExpr*)this)->predicate; } @@ -788,80 +1031,28 @@ unsigned ConstantExpr::getPredicate() const { /// one, but with the specified operand set to the specified value. Constant * ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { - assert(OpNo < getNumOperands() && "Operand num is out of range!"); assert(Op->getType() == getOperand(OpNo)->getType() && "Replacing operand with value of different type!"); if (getOperand(OpNo) == Op) return const_cast(this); - - Constant *Op0, *Op1, *Op2; - switch (getOpcode()) { - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::PtrToInt: - case Instruction::IntToPtr: - case Instruction::BitCast: - return ConstantExpr::getCast(getOpcode(), Op, getType()); - case Instruction::Select: - Op0 = (OpNo == 0) ? Op : getOperand(0); - Op1 = (OpNo == 1) ? Op : getOperand(1); - Op2 = (OpNo == 2) ? Op : getOperand(2); - return ConstantExpr::getSelect(Op0, Op1, Op2); - case Instruction::InsertElement: - Op0 = (OpNo == 0) ? Op : getOperand(0); - Op1 = (OpNo == 1) ? Op : getOperand(1); - Op2 = (OpNo == 2) ? Op : getOperand(2); - return ConstantExpr::getInsertElement(Op0, Op1, Op2); - case Instruction::ExtractElement: - Op0 = (OpNo == 0) ? Op : getOperand(0); - Op1 = (OpNo == 1) ? Op : getOperand(1); - return ConstantExpr::getExtractElement(Op0, Op1); - case Instruction::ShuffleVector: - Op0 = (OpNo == 0) ? Op : getOperand(0); - Op1 = (OpNo == 1) ? Op : getOperand(1); - Op2 = (OpNo == 2) ? Op : getOperand(2); - return ConstantExpr::getShuffleVector(Op0, Op1, Op2); - case Instruction::GetElementPtr: { - SmallVector Ops; - Ops.resize(getNumOperands()-1); - for (unsigned i = 1, e = getNumOperands(); i != e; ++i) - Ops[i-1] = getOperand(i); - if (OpNo == 0) - return cast(this)->isInBounds() ? - ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) : - ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); - Ops[OpNo-1] = Op; - return cast(this)->isInBounds() ? - ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0],Ops.size()): - ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); - } - default: - assert(getNumOperands() == 2 && "Must be binary operator?"); - Op0 = (OpNo == 0) ? Op : getOperand(0); - Op1 = (OpNo == 1) ? Op : getOperand(1); - return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassOptionalData); - } + + SmallVector NewOps; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + NewOps.push_back(i == OpNo ? Op : getOperand(i)); + + return getWithOperands(NewOps); } /// getWithOperands - This returns the current constant expression with the -/// operands replaced with the specified values. The specified operands must -/// match count and type with the existing ones. +/// operands replaced with the specified values. The specified array must +/// have the same number of operands as our current one. Constant *ConstantExpr:: -getWithOperands(ArrayRef Ops) const { +getWithOperands(ArrayRef Ops, Type *Ty) const { assert(Ops.size() == getNumOperands() && "Operand count mismatch!"); - bool AnyChange = false; - for (unsigned i = 0; i != Ops.size(); ++i) { - assert(Ops[i]->getType() == getOperand(i)->getType() && - "Operand type mismatch!"); + bool AnyChange = Ty != getType(); + for (unsigned i = 0; i != Ops.size(); ++i) AnyChange |= Ops[i] != getOperand(i); - } + if (!AnyChange) // No operands changed, return self. return const_cast(this); @@ -878,19 +1069,22 @@ getWithOperands(ArrayRef Ops) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: - return ConstantExpr::getCast(getOpcode(), Ops[0], getType()); + return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::InsertElement: return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); case Instruction::ExtractElement: return ConstantExpr::getExtractElement(Ops[0], Ops[1]); + case Instruction::InsertValue: + return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices()); + case Instruction::ExtractValue: + return ConstantExpr::getExtractValue(Ops[0], getIndices()); case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); case Instruction::GetElementPtr: - return cast(this)->isInBounds() ? - ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], Ops.size()-1) : - ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1); + return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1), + cast(this)->isInBounds()); case Instruction::ICmp: case Instruction::FCmp: return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); @@ -904,9 +1098,9 @@ getWithOperands(ArrayRef Ops) const { //===----------------------------------------------------------------------===// // isValueValidForType implementations -bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { - unsigned NumBits = cast(Ty)->getBitWidth(); // assert okay - if (Ty == Type::getInt1Ty(Ty->getContext())) +bool ConstantInt::isValueValidForType(Type *Ty, uint64_t Val) { + unsigned NumBits = Ty->getIntegerBitWidth(); // assert okay + if (Ty->isIntegerTy(1)) return Val == 0 || Val == 1; if (NumBits >= 64) return true; // always true, has to fit in largest type @@ -914,9 +1108,9 @@ bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { return Val <= Max; } -bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) { - unsigned NumBits = cast(Ty)->getBitWidth(); // assert okay - if (Ty == Type::getInt1Ty(Ty->getContext())) +bool ConstantInt::isValueValidForType(Type *Ty, int64_t Val) { + unsigned NumBits = Ty->getIntegerBitWidth(); + if (Ty->isIntegerTy(1)) return Val == 0 || Val == 1 || Val == -1; if (NumBits >= 64) return true; // always true, has to fit in largest type @@ -925,7 +1119,7 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) { return (Val >= Min && Val <= Max); } -bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { +bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) { // convert modifies in place, so make a copy. APFloat Val2 = APFloat(Val); bool losesInfo; @@ -934,6 +1128,12 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { return false; // These can't be represented as floating point! // FIXME rounding mode needs to be more flexible + case Type::HalfTyID: { + if (&Val2.getSemantics() == &APFloat::IEEEhalf) + return true; + Val2.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &losesInfo); + return !losesInfo; + } case Type::FloatTyID: { if (&Val2.getSemantics() == &APFloat::IEEEsingle) return true; @@ -941,139 +1141,78 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { return !losesInfo; } case Type::DoubleTyID: { - if (&Val2.getSemantics() == &APFloat::IEEEsingle || + if (&Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble) return true; Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo); return !losesInfo; } case Type::X86_FP80TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::x87DoubleExtended; case Type::FP128TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::IEEEquad; case Type::PPC_FP128TyID: - return &Val2.getSemantics() == &APFloat::IEEEsingle || + return &Val2.getSemantics() == &APFloat::IEEEhalf || + &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::PPCDoubleDouble; } } + //===----------------------------------------------------------------------===// // Factory Function Implementation -ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { +ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) && "Cannot create an aggregate zero of non-aggregate type!"); - LLVMContextImpl *pImpl = Ty->getContext().pImpl; - return pImpl->AggZeroConstants.getOrCreate(Ty, 0); + ConstantAggregateZero *&Entry = Ty->getContext().pImpl->CAZConstants[Ty]; + if (Entry == 0) + Entry = new ConstantAggregateZero(Ty); + + return Entry; } -/// destroyConstant - Remove the constant from the constant table... +/// destroyConstant - Remove the constant from the constant table. /// void ConstantAggregateZero::destroyConstant() { - getRawType()->getContext().pImpl->AggZeroConstants.remove(this); + getContext().pImpl->CAZConstants.erase(getType()); destroyConstantImpl(); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { - getRawType()->getContext().pImpl->ArrayConstants.remove(this); + getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } -/// isString - This method returns true if the array is an array of i8, and -/// if the elements of the array are all ConstantInt's. -bool ConstantArray::isString() const { - // Check the element type for i8... - if (!getType()->getElementType()->isIntegerTy(8)) - return false; - // Check the elements to make sure they are all integers, not constant - // expressions. - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (!isa(getOperand(i))) - return false; - return true; -} - -/// isCString - This method returns true if the array is a string (see -/// isString) and it ends in a null byte \\0 and does not contains any other -/// null bytes except its terminator. -bool ConstantArray::isCString() const { - // Check the element type for i8... - if (!getType()->getElementType()->isIntegerTy(8)) - return false; - - // Last element must be a null. - if (!getOperand(getNumOperands()-1)->isNullValue()) - return false; - // Other elements must be non-null integers. - for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) { - if (!isa(getOperand(i))) - return false; - if (getOperand(i)->isNullValue()) - return false; - } - return true; -} - - -/// getAsString - If the sub-element type of this array is i8 -/// then this method converts the array to an std::string and returns it. -/// Otherwise, it asserts out. -/// -std::string ConstantArray::getAsString() const { - assert(isString() && "Not a string!"); - std::string Result; - Result.reserve(getNumOperands()); - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - Result.push_back((char)cast(getOperand(i))->getZExtValue()); - return Result; -} - //---- ConstantStruct::get() implementation... // -namespace llvm { - -} - // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { - getRawType()->getContext().pImpl->StructConstants.remove(this); + getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { - getRawType()->getContext().pImpl->VectorConstants.remove(this); + getType()->getContext().pImpl->VectorConstants.remove(this); destroyConstantImpl(); } -/// This function will return true iff every element in this vector constant -/// is set to all ones. -/// @returns true iff this constant's emements are all set to all ones. -/// @brief Determine if the value is all ones. -bool ConstantVector::isAllOnesValue() const { - // Check out first element. - const Constant *Elt = getOperand(0); - const ConstantInt *CI = dyn_cast(Elt); - if (!CI || !CI->isAllOnesValue()) return false; - // Then make sure all remaining elements point to the same value. - for (unsigned I = 1, E = getNumOperands(); I < E; ++I) { - if (getOperand(I) != Elt) return false; - } - return true; -} - /// getSplatValue - If this is a splat constant, where all of the /// elements have the same value, return that value. Otherwise return null. Constant *ConstantVector::getSplatValue() const { @@ -1081,21 +1220,27 @@ Constant *ConstantVector::getSplatValue() const { Constant *Elt = getOperand(0); // Then make sure all remaining elements point to the same value. for (unsigned I = 1, E = getNumOperands(); I < E; ++I) - if (getOperand(I) != Elt) return 0; + if (getOperand(I) != Elt) + return 0; return Elt; } //---- ConstantPointerNull::get() implementation. // -ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { - return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0); +ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { + ConstantPointerNull *&Entry = Ty->getContext().pImpl->CPNConstants[Ty]; + if (Entry == 0) + Entry = new ConstantPointerNull(Ty); + + return Entry; } // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { - getRawType()->getContext().pImpl->NullPtrConstants.remove(this); + getContext().pImpl->CPNConstants.erase(getType()); + // Free the constant and any dangling references to it. destroyConstantImpl(); } @@ -1103,14 +1248,19 @@ void ConstantPointerNull::destroyConstant() { //---- UndefValue::get() implementation. // -UndefValue *UndefValue::get(const Type *Ty) { - return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0); +UndefValue *UndefValue::get(Type *Ty) { + UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty]; + if (Entry == 0) + Entry = new UndefValue(Ty); + + return Entry; } // destroyConstant - Remove the constant from the constant table. // void UndefValue::destroyConstant() { - getRawType()->getContext().pImpl->UndefValueConstants.remove(this); + // Free the constant and any dangling references to it. + getContext().pImpl->UVConstants.erase(getType()); destroyConstantImpl(); } @@ -1127,7 +1277,7 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)]; if (BA == 0) BA = new BlockAddress(F, BB); - + assert(BA->getFunction() == F && "Basic block moved between functions"); return BA; } @@ -1144,7 +1294,7 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) // destroyConstant - Remove the constant from the constant table. // void BlockAddress::destroyConstant() { - getFunction()->getRawType()->getContext().pImpl + getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); getBasicBlock()->AdjustBlockAddressRefCount(-1); destroyConstantImpl(); @@ -1155,19 +1305,19 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { // case, we have to remove the map entry. Function *NewF = getFunction(); BasicBlock *NewBB = getBasicBlock(); - + if (U == &Op<0>()) NewF = cast(To); else NewBB = cast(To); - + // See if the 'new' entry already exists, if not, just update this in place // and return early. BlockAddress *&NewBA = getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)]; if (NewBA == 0) { getBasicBlock()->AdjustBlockAddressRefCount(-1); - + // Remove the old entry, this can't cause the map to rehash (just a // tombstone will get added). getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(), @@ -1181,10 +1331,10 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { // Otherwise, I do need to replace this with an existing value. assert(NewBA != this && "I didn't contain From!"); - + // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(NewBA); - + replaceAllUsesWith(NewBA); + destroyConstant(); } @@ -1194,7 +1344,7 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { /// This is a utility function to handle folding of casts and lookup of the /// cast in the ExprConstants map. It is used by the various get* methods below. static inline Constant *getFoldedCast( - Instruction::CastOps opc, Constant *C, const Type *Ty) { + Instruction::CastOps opc, Constant *C, Type *Ty) { assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); // Fold a few common cases if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty)) @@ -1205,11 +1355,11 @@ static inline Constant *getFoldedCast( // Look up the constant in the table first to ensure uniqueness std::vector argVec(1, C); ExprMapKeyType Key(opc, argVec); - + return pImpl->ExprConstants.getOrCreate(Ty, Key); } - -Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { + +Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) { Instruction::CastOps opc = Instruction::CastOps(oc); assert(Instruction::isCast(opc) && "opcode out of range"); assert(C && Ty && "Null arguments to getCast"); @@ -1218,7 +1368,6 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { switch (opc) { default: llvm_unreachable("Invalid cast opcode"); - break; case Instruction::Trunc: return getTrunc(C, Ty); case Instruction::ZExt: return getZExt(C, Ty); case Instruction::SExt: return getSExt(C, Ty); @@ -1232,28 +1381,27 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { case Instruction::IntToPtr: return getIntToPtr(C, Ty); case Instruction::BitCast: return getBitCast(C, Ty); } - return 0; -} +} -Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getZExtOrBitCast(Constant *C, Type *Ty) { if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getBitCast(C, Ty); return getZExt(C, Ty); } -Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getSExtOrBitCast(Constant *C, Type *Ty) { if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getBitCast(C, Ty); return getSExt(C, Ty); } -Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) { if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return getBitCast(C, Ty); return getTrunc(C, Ty); } -Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) { +Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { assert(S->getType()->isPointerTy() && "Invalid cast"); assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"); @@ -1262,7 +1410,7 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) { return getBitCast(S, Ty); } -Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, +Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid cast"); @@ -1275,7 +1423,7 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, return getCast(opcode, C, Ty); } -Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getFPCast(Constant *C, Type *Ty) { assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); @@ -1287,7 +1435,7 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { return getCast(opcode, C, Ty); } -Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1301,7 +1449,7 @@ Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::Trunc, C, Ty); } -Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getSExt(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1315,7 +1463,7 @@ Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::SExt, C, Ty); } -Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getZExt(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1329,7 +1477,7 @@ Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::ZExt, C, Ty); } -Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1341,7 +1489,7 @@ Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::FPTrunc, C, Ty); } -Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1353,7 +1501,7 @@ Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::FPExt, C, Ty); } -Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1364,7 +1512,7 @@ Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::UIToFP, C, Ty); } -Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1375,7 +1523,7 @@ Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::SIToFP, C, Ty); } -Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1386,7 +1534,7 @@ Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::FPToUI, C, Ty); } -Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1397,72 +1545,50 @@ Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) { return getFoldedCast(Instruction::FPToSI, C, Ty); } -Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) { - assert(C->getType()->isPointerTy() && "PtrToInt source must be pointer"); - assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral"); +Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy) { + assert(C->getType()->getScalarType()->isPointerTy() && + "PtrToInt source must be pointer or pointer vector"); + assert(DstTy->getScalarType()->isIntegerTy() && + "PtrToInt destination must be integer or integer vector"); + assert(isa(C->getType()) == isa(DstTy)); + if (isa(C->getType())) + assert(C->getType()->getVectorNumElements()==DstTy->getVectorNumElements()&& + "Invalid cast between a different number of vector elements"); return getFoldedCast(Instruction::PtrToInt, C, DstTy); } -Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) { - assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral"); - assert(DstTy->isPointerTy() && "IntToPtr destination must be a pointer"); +Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) { + assert(C->getType()->getScalarType()->isIntegerTy() && + "IntToPtr source must be integer or integer vector"); + assert(DstTy->getScalarType()->isPointerTy() && + "IntToPtr destination must be a pointer or pointer vector"); + assert(isa(C->getType()) == isa(DstTy)); + if (isa(C->getType())) + assert(C->getType()->getVectorNumElements()==DstTy->getVectorNumElements()&& + "Invalid cast between a different number of vector elements"); return getFoldedCast(Instruction::IntToPtr, C, DstTy); } -Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { +Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) { assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) && "Invalid constantexpr bitcast!"); - + // It is common to ask for a bitcast of a value to its own type, handle this // speedily. if (C->getType() == DstTy) return C; - + return getFoldedCast(Instruction::BitCast, C, DstTy); } -Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, - Constant *C1, Constant *C2, - unsigned Flags) { - // Check the operands for consistency first +Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) { + // Check the operands for consistency first. assert(Opcode >= Instruction::BinaryOpsBegin && Opcode < Instruction::BinaryOpsEnd && "Invalid opcode in binary constant expression"); assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); - if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext())) - if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) - return FC; // Fold a few common cases... - - std::vector argVec(1, C1); argVec.push_back(C2); - ExprMapKeyType Key(Opcode, argVec, 0, Flags); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getCompareTy(unsigned short predicate, - Constant *C1, Constant *C2) { - switch (predicate) { - default: llvm_unreachable("Invalid CmpInst predicate"); - case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT: - case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE: - case CmpInst::FCMP_ONE: case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO: - case CmpInst::FCMP_UEQ: case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE: - case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE: - case CmpInst::FCMP_TRUE: - return getFCmp(predicate, C1, C2); - - case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT: - case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE: - case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT: - case CmpInst::ICMP_SLE: - return getICmp(predicate, C1, C2); - } -} - -Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, - unsigned Flags) { #ifndef NDEBUG switch (Opcode) { case Instruction::Add: @@ -1521,39 +1647,47 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, } #endif - return getTy(C1->getType(), Opcode, C1, C2, Flags); + if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) + return FC; // Fold a few common cases. + + std::vector argVec(1, C1); + argVec.push_back(C2); + ExprMapKeyType Key(Opcode, argVec, 0, Flags); + + LLVMContextImpl *pImpl = C1->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(C1->getType(), Key); } -Constant *ConstantExpr::getSizeOf(const Type* Ty) { +Constant *ConstantExpr::getSizeOf(Type* Ty) { // sizeof is implemented as: (i64) gep (Ty*)null, 1 // Note that a non-inbounds gep is used, as null isn't within any object. Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1); + Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } -Constant *ConstantExpr::getAlignOf(const Type* Ty) { +Constant *ConstantExpr::getAlignOf(Type* Ty) { // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1 // Note that a non-inbounds gep is used, as null isn't within any object. - const Type *AligningTy = StructType::get(Ty->getContext(), - Type::getInt1Ty(Ty->getContext()), Ty, NULL); - Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); + Type *AligningTy = + StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); + Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo(Ty)); Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0); Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *Indices[2] = { Zero, One }; - Constant *GEP = getGetElementPtr(NullPtr, Indices, 2); + Constant *GEP = getGetElementPtr(NullPtr, Indices); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } -Constant *ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) { +Constant *ConstantExpr::getOffsetOf(StructType* STy, unsigned FieldNo) { return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()), FieldNo)); } -Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) { +Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) { // offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo // Note that a non-inbounds gep is used, as null isn't within any object. Constant *GEPIdx[] = { @@ -1561,82 +1695,74 @@ Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) { FieldNo }; Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2); + Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } -Constant *ConstantExpr::getCompare(unsigned short pred, - Constant *C1, Constant *C2) { +Constant *ConstantExpr::getCompare(unsigned short Predicate, + Constant *C1, Constant *C2) { assert(C1->getType() == C2->getType() && "Op types should be identical!"); - return getCompareTy(pred, C1, C2); + + switch (Predicate) { + default: llvm_unreachable("Invalid CmpInst predicate"); + case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT: + case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE: + case CmpInst::FCMP_ONE: case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO: + case CmpInst::FCMP_UEQ: case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE: + case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE: + case CmpInst::FCMP_TRUE: + return getFCmp(Predicate, C1, C2); + + case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT: + case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE: + case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT: + case CmpInst::ICMP_SLE: + return getICmp(Predicate, C1, C2); + } } -Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, - Constant *V1, Constant *V2) { +Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) { assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands"); - if (ReqTy == V1->getType()) - if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) - return SC; // Fold common cases + if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) + return SC; // Fold common cases std::vector argVec(3, C); argVec[1] = V1; argVec[2] = V2; ExprMapKeyType Key(Instruction::Select, argVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} -template -Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, - IndexTy const *Idxs, - unsigned NumIdx, bool InBounds) { - assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, - Idxs+NumIdx) == - cast(ReqTy)->getElementType() && - "GEP indices invalid!"); + LLVMContextImpl *pImpl = C->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); +} - if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx)) +Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef Idxs, + bool InBounds) { + if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) return FC; // Fold a few common cases. + // Get the result type of the getelementptr! + Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs); + assert(Ty && "GEP indices invalid!"); + unsigned AS = C->getType()->getPointerAddressSpace(); + Type *ReqTy = Ty->getPointerTo(AS); + assert(C->getType()->isPointerTy() && "Non-pointer type for constant GetElementPtr expression"); // Look up the constant in the table first to ensure uniqueness std::vector ArgVec; - ArgVec.reserve(NumIdx+1); + ArgVec.reserve(1 + Idxs.size()); ArgVec.push_back(C); - for (unsigned i = 0; i != NumIdx; ++i) + for (unsigned i = 0, e = Idxs.size(); i != e; ++i) ArgVec.push_back(cast(Idxs[i])); const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, InBounds ? GEPOperator::IsInBounds : 0); - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -template -Constant *ConstantExpr::getGetElementPtrImpl(Constant *C, IndexTy const *Idxs, - unsigned NumIdx, bool InBounds) { - // Get the result type of the getelementptr! - const Type *Ty = - GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx); - assert(Ty && "GEP indices invalid!"); - unsigned As = cast(C->getType())->getAddressSpace(); - return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds); -} - -Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, - unsigned NumIdx, bool InBounds) { - return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); -} - -Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant *const *Idxs, - unsigned NumIdx, bool InBounds) { - return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); -} - Constant * ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { assert(LHS->getType() == RHS->getType()); @@ -1653,8 +1779,8 @@ ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { // Get the key type with both the opcode and predicate const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred); - const Type *ResultTy = Type::getInt1Ty(LHS->getContext()); - if (const VectorType *VT = dyn_cast(LHS->getType())) + Type *ResultTy = Type::getInt1Ty(LHS->getContext()); + if (VectorType *VT = dyn_cast(LHS->getType())) ResultTy = VectorType::get(ResultTy, VT->getNumElements()); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; @@ -1676,38 +1802,42 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { // Get the key type with both the opcode and predicate const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred); - const Type *ResultTy = Type::getInt1Ty(LHS->getContext()); - if (const VectorType *VT = dyn_cast(LHS->getType())) + Type *ResultTy = Type::getInt1Ty(LHS->getContext()); + if (VectorType *VT = dyn_cast(LHS->getType())) ResultTy = VectorType::get(ResultTy, VT->getNumElements()); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ResultTy, Key); } -Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, - Constant *Idx) { +Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { + assert(Val->getType()->isVectorTy() && + "Tried to create extractelement operation on non-vector type!"); + assert(Idx->getType()->isIntegerTy(32) && + "Extractelement index must be i32 type!"); + if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) return FC; // Fold a few common cases. + // Look up the constant in the table first to ensure uniqueness std::vector ArgVec(1, Val); ArgVec.push_back(Idx); const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + + LLVMContextImpl *pImpl = Val->getContext().pImpl; + Type *ReqTy = Val->getType()->getVectorElementType(); return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { +Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, + Constant *Idx) { assert(Val->getType()->isVectorTy() && - "Tried to create extractelement operation on non-vector type!"); + "Tried to create insertelement operation on non-vector type!"); + assert(Elt->getType() == Val->getType()->getVectorElementType() && + "Insertelement types must match!"); assert(Idx->getType()->isIntegerTy(32) && - "Extractelement index must be i32 type!"); - return getExtractElementTy(cast(Val->getType())->getElementType(), - Val, Idx); -} + "Insertelement index must be i32 type!"); -Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, - Constant *Elt, Constant *Idx) { if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) return FC; // Fold a few common cases. // Look up the constant in the table first to ensure uniqueness @@ -1715,99 +1845,61 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, ArgVec.push_back(Elt); ArgVec.push_back(Idx); const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} -Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, - Constant *Idx) { - assert(Val->getType()->isVectorTy() && - "Tried to create insertelement operation on non-vector type!"); - assert(Elt->getType() == cast(Val->getType())->getElementType() - && "Insertelement types must match!"); - assert(Idx->getType()->isIntegerTy(32) && - "Insertelement index must be i32 type!"); - return getInsertElementTy(Val->getType(), Val, Elt, Idx); + LLVMContextImpl *pImpl = Val->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(Val->getType(), Key); } -Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, - Constant *V2, Constant *Mask) { +Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, + Constant *Mask) { + assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector constant expr operands!"); + if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) - return FC; // Fold a few common cases... + return FC; // Fold a few common cases. + + unsigned NElts = Mask->getType()->getVectorNumElements(); + Type *EltTy = V1->getType()->getVectorElementType(); + Type *ShufTy = VectorType::get(EltTy, NElts); + // Look up the constant in the table first to ensure uniqueness std::vector ArgVec(1, V1); ArgVec.push_back(V2); ArgVec.push_back(Mask); const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) { - assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && - "Invalid shuffle vector constant expr operands!"); - unsigned NElts = cast(Mask->getType())->getNumElements(); - const Type *EltTy = cast(V1->getType())->getElementType(); - const Type *ShufTy = VectorType::get(EltTy, NElts); - return getShuffleVectorTy(ShufTy, V1, V2, Mask); + LLVMContextImpl *pImpl = ShufTy->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ShufTy, Key); } -Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg, - Constant *Val, - const unsigned *Idxs, unsigned NumIdx) { - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs, - Idxs+NumIdx) == Val->getType() && +Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, + ArrayRef Idxs) { + assert(ExtractValueInst::getIndexedType(Agg->getType(), + Idxs) == Val->getType() && "insertvalue indices invalid!"); - assert(Agg->getType() == ReqTy && - "insertvalue type invalid!"); assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant InsertValue expression"); - Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx); - assert(FC && "InsertValue constant expr couldn't be folded!"); + "Non-first-class type for constant insertvalue expression"); + Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs); + assert(FC && "insertvalue constant expr couldn't be folded!"); return FC; } -Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx) { +Constant *ConstantExpr::getExtractValue(Constant *Agg, + ArrayRef Idxs) { assert(Agg->getType()->isFirstClassType() && - "Tried to create insertelement operation on non-first-class type!"); + "Tried to create extractelement operation on non-first-class type!"); - const Type *ReqTy = Agg->getType(); -#ifndef NDEBUG - const Type *ValTy = - ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx); -#endif - assert(ValTy == Val->getType() && "insertvalue indices invalid!"); - return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx); -} + Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs); + (void)ReqTy; + assert(ReqTy && "extractvalue indices invalid!"); -Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg, - const unsigned *Idxs, unsigned NumIdx) { - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs, - Idxs+NumIdx) == ReqTy && - "extractvalue indices invalid!"); assert(Agg->getType()->isFirstClassType() && "Non-first-class type for constant extractvalue expression"); - Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx); + Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs); assert(FC && "ExtractValue constant expr couldn't be folded!"); return FC; } -Constant *ConstantExpr::getExtractValue(Constant *Agg, - const unsigned *IdxList, unsigned NumIdx) { - assert(Agg->getType()->isFirstClassType() && - "Tried to create extractelement operation on non-first-class type!"); - - const Type *ReqTy = - ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx); - assert(ReqTy && "extractvalue indices invalid!"); - return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); -} - Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); @@ -1915,10 +2007,51 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { isExact ? PossiblyExactOperator::IsExact : 0); } +/// getBinOpIdentity - Return the identity for the given binary operation, +/// i.e. a constant C such that X op C = X and C op X = X for every X. It +/// returns null if the operator doesn't have an identity. +Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) { + switch (Opcode) { + default: + // Doesn't have an identity. + return 0; + + case Instruction::Add: + case Instruction::Or: + case Instruction::Xor: + return Constant::getNullValue(Ty); + + case Instruction::Mul: + return ConstantInt::get(Ty, 1); + + case Instruction::And: + return Constant::getAllOnesValue(Ty); + } +} + +/// getBinOpAbsorber - Return the absorbing element for the given binary +/// operation, i.e. a constant C such that X op C = C and C op X = C for +/// every X. For example, this returns zero for integer multiplication. +/// It returns null if the operator doesn't have an absorbing element. +Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { + switch (Opcode) { + default: + // Doesn't have an absorber. + return 0; + + case Instruction::Or: + return Constant::getAllOnesValue(Ty); + + case Instruction::And: + case Instruction::Mul: + return Constant::getNullValue(Ty); + } +} + // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { - getRawType()->getContext().pImpl->ExprConstants.remove(this); + getType()->getContext().pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -1929,8 +2062,8 @@ const char *ConstantExpr::getOpcodeName() const { GetElementPtrConstantExpr:: -GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy) +GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, + Type *DestTy) : ConstantExpr(DestTy, Instruction::GetElementPtr, OperandTraits::op_end(this) - (IdxList.size()+1), IdxList.size()+1) { @@ -1939,6 +2072,369 @@ GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, OperandList[i+1] = IdxList[i]; } +//===----------------------------------------------------------------------===// +// ConstantData* implementations + +void ConstantDataArray::anchor() {} +void ConstantDataVector::anchor() {} + +/// getElementType - Return the element type of the array/vector. +Type *ConstantDataSequential::getElementType() const { + return getType()->getElementType(); +} + +StringRef ConstantDataSequential::getRawDataValues() const { + return StringRef(DataElements, getNumElements()*getElementByteSize()); +} + +/// isElementTypeCompatible - Return true if a ConstantDataSequential can be +/// formed with a vector or array of the specified element type. +/// ConstantDataArray only works with normal float and int types that are +/// stored densely in memory, not with things like i42 or x86_f80. +bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) { + if (Ty->isFloatTy() || Ty->isDoubleTy()) return true; + if (const IntegerType *IT = dyn_cast(Ty)) { + switch (IT->getBitWidth()) { + case 8: + case 16: + case 32: + case 64: + return true; + default: break; + } + } + return false; +} + +/// getNumElements - Return the number of elements in the array or vector. +unsigned ConstantDataSequential::getNumElements() const { + if (ArrayType *AT = dyn_cast(getType())) + return AT->getNumElements(); + return getType()->getVectorNumElements(); +} + + +/// getElementByteSize - Return the size in bytes of the elements in the data. +uint64_t ConstantDataSequential::getElementByteSize() const { + return getElementType()->getPrimitiveSizeInBits()/8; +} + +/// getElementPointer - Return the start of the specified element. +const char *ConstantDataSequential::getElementPointer(unsigned Elt) const { + assert(Elt < getNumElements() && "Invalid Elt"); + return DataElements+Elt*getElementByteSize(); +} + + +/// isAllZeros - return true if the array is empty or all zeros. +static bool isAllZeros(StringRef Arr) { + for (StringRef::iterator I = Arr.begin(), E = Arr.end(); I != E; ++I) + if (*I != 0) + return false; + return true; +} + +/// getImpl - This is the underlying implementation of all of the +/// ConstantDataSequential::get methods. They all thunk down to here, providing +/// the correct element type. We take the bytes in as a StringRef because +/// we *want* an underlying "char*" to avoid TBAA type punning violations. +Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { + assert(isElementTypeCompatible(Ty->getSequentialElementType())); + // If the elements are all zero or there are no elements, return a CAZ, which + // is more dense and canonical. + if (isAllZeros(Elements)) + return ConstantAggregateZero::get(Ty); + + // Do a lookup to see if we have already formed one of these. + StringMap::MapEntryTy &Slot = + Ty->getContext().pImpl->CDSConstants.GetOrCreateValue(Elements); + + // The bucket can point to a linked list of different CDS's that have the same + // body but different types. For example, 0,0,0,1 could be a 4 element array + // of i8, or a 1-element array of i32. They'll both end up in the same + /// StringMap bucket, linked up by their Next pointers. Walk the list. + ConstantDataSequential **Entry = &Slot.getValue(); + for (ConstantDataSequential *Node = *Entry; Node != 0; + Entry = &Node->Next, Node = *Entry) + if (Node->getType() == Ty) + return Node; + + // Okay, we didn't get a hit. Create a node of the right class, link it in, + // and return it. + if (isa(Ty)) + return *Entry = new ConstantDataArray(Ty, Slot.getKeyData()); + + assert(isa(Ty)); + return *Entry = new ConstantDataVector(Ty, Slot.getKeyData()); +} + +void ConstantDataSequential::destroyConstant() { + // Remove the constant from the StringMap. + StringMap &CDSConstants = + getType()->getContext().pImpl->CDSConstants; + + StringMap::iterator Slot = + CDSConstants.find(getRawDataValues()); + + assert(Slot != CDSConstants.end() && "CDS not found in uniquing table"); + + ConstantDataSequential **Entry = &Slot->getValue(); + + // Remove the entry from the hash table. + if ((*Entry)->Next == 0) { + // If there is only one value in the bucket (common case) it must be this + // entry, and removing the entry should remove the bucket completely. + assert((*Entry) == this && "Hash mismatch in ConstantDataSequential"); + getContext().pImpl->CDSConstants.erase(Slot); + } else { + // Otherwise, there are multiple entries linked off the bucket, unlink the + // node we care about but keep the bucket around. + for (ConstantDataSequential *Node = *Entry; ; + Entry = &Node->Next, Node = *Entry) { + assert(Node && "Didn't find entry in its uniquing hash table!"); + // If we found our entry, unlink it from the list and we're done. + if (Node == this) { + *Entry = Node->Next; + break; + } + } + } + + // If we were part of a list, make sure that we don't delete the list that is + // still owned by the uniquing map. + Next = 0; + + // Finally, actually delete it. + destroyConstantImpl(); +} + +/// get() constructors - Return a constant with array type with an element +/// count and element type matching the ArrayRef passed in. Note that this +/// can return a ConstantAggregateZero object. +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { + Type *Ty = ArrayType::get(Type::getInt8Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*1), Ty); +} +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = ArrayType::get(Type::getInt16Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*2), Ty); +} +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = ArrayType::get(Type::getInt32Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*4), Ty); +} +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = ArrayType::get(Type::getInt64Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); +} +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { + Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*4), Ty); +} +Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { + Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); +} + +/// getString - This method constructs a CDS and initializes it with a text +/// string. The default behavior (AddNull==true) causes a null terminator to +/// be placed at the end of the array (increasing the length of the string by +/// one more than the StringRef would normally indicate. Pass AddNull=false +/// to disable this behavior. +Constant *ConstantDataArray::getString(LLVMContext &Context, + StringRef Str, bool AddNull) { + if (!AddNull) { + const uint8_t *Data = reinterpret_cast(Str.data()); + return get(Context, ArrayRef(const_cast(Data), + Str.size())); + } + + SmallVector ElementVals; + ElementVals.append(Str.begin(), Str.end()); + ElementVals.push_back(0); + return get(Context, ElementVals); +} + +/// get() constructors - Return a constant with vector type with an element +/// count and element type matching the ArrayRef passed in. Note that this +/// can return a ConstantAggregateZero object. +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = VectorType::get(Type::getInt8Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*1), Ty); +} +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = VectorType::get(Type::getInt16Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*2), Ty); +} +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = VectorType::get(Type::getInt32Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*4), Ty); +} +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts){ + Type *Ty = VectorType::get(Type::getInt64Ty(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); +} +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*4), Ty); +} +Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); +} + +Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) { + assert(isElementTypeCompatible(V->getType()) && + "Element type not compatible with ConstantData"); + if (ConstantInt *CI = dyn_cast(V)) { + if (CI->getType()->isIntegerTy(8)) { + SmallVector Elts(NumElts, CI->getZExtValue()); + return get(V->getContext(), Elts); + } + if (CI->getType()->isIntegerTy(16)) { + SmallVector Elts(NumElts, CI->getZExtValue()); + return get(V->getContext(), Elts); + } + if (CI->getType()->isIntegerTy(32)) { + SmallVector Elts(NumElts, CI->getZExtValue()); + return get(V->getContext(), Elts); + } + assert(CI->getType()->isIntegerTy(64) && "Unsupported ConstantData type"); + SmallVector Elts(NumElts, CI->getZExtValue()); + return get(V->getContext(), Elts); + } + + if (ConstantFP *CFP = dyn_cast(V)) { + if (CFP->getType()->isFloatTy()) { + SmallVector Elts(NumElts, CFP->getValueAPF().convertToFloat()); + return get(V->getContext(), Elts); + } + if (CFP->getType()->isDoubleTy()) { + SmallVector Elts(NumElts, + CFP->getValueAPF().convertToDouble()); + return get(V->getContext(), Elts); + } + } + return ConstantVector::getSplat(NumElts, V); +} + + +/// getElementAsInteger - If this is a sequential container of integers (of +/// any size), return the specified element in the low bits of a uint64_t. +uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const { + assert(isa(getElementType()) && + "Accessor can only be used when element is an integer"); + const char *EltPtr = getElementPointer(Elt); + + // The data is stored in host byte order, make sure to cast back to the right + // type to load with the right endianness. + switch (getElementType()->getIntegerBitWidth()) { + default: llvm_unreachable("Invalid bitwidth for CDS"); + case 8: + return *const_cast(reinterpret_cast(EltPtr)); + case 16: + return *const_cast(reinterpret_cast(EltPtr)); + case 32: + return *const_cast(reinterpret_cast(EltPtr)); + case 64: + return *const_cast(reinterpret_cast(EltPtr)); + } +} + +/// getElementAsAPFloat - If this is a sequential container of floating point +/// type, return the specified element as an APFloat. +APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const { + const char *EltPtr = getElementPointer(Elt); + + switch (getElementType()->getTypeID()) { + default: + llvm_unreachable("Accessor can only be used when element is float/double!"); + case Type::FloatTyID: { + const float *FloatPrt = reinterpret_cast(EltPtr); + return APFloat(*const_cast(FloatPrt)); + } + case Type::DoubleTyID: { + const double *DoublePtr = reinterpret_cast(EltPtr); + return APFloat(*const_cast(DoublePtr)); + } + } +} + +/// getElementAsFloat - If this is an sequential container of floats, return +/// the specified element as a float. +float ConstantDataSequential::getElementAsFloat(unsigned Elt) const { + assert(getElementType()->isFloatTy() && + "Accessor can only be used when element is a 'float'"); + const float *EltPtr = reinterpret_cast(getElementPointer(Elt)); + return *const_cast(EltPtr); +} + +/// getElementAsDouble - If this is an sequential container of doubles, return +/// the specified element as a float. +double ConstantDataSequential::getElementAsDouble(unsigned Elt) const { + assert(getElementType()->isDoubleTy() && + "Accessor can only be used when element is a 'float'"); + const double *EltPtr = + reinterpret_cast(getElementPointer(Elt)); + return *const_cast(EltPtr); +} + +/// getElementAsConstant - Return a Constant for a specified index's element. +/// Note that this has to compute a new constant to return, so it isn't as +/// efficient as getElementAsInteger/Float/Double. +Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const { + if (getElementType()->isFloatTy() || getElementType()->isDoubleTy()) + return ConstantFP::get(getContext(), getElementAsAPFloat(Elt)); + + return ConstantInt::get(getElementType(), getElementAsInteger(Elt)); +} + +/// isString - This method returns true if this is an array of i8. +bool ConstantDataSequential::isString() const { + return isa(getType()) && getElementType()->isIntegerTy(8); +} + +/// isCString - This method returns true if the array "isString", ends with a +/// nul byte, and does not contains any other nul bytes. +bool ConstantDataSequential::isCString() const { + if (!isString()) + return false; + + StringRef Str = getAsString(); + + // The last value must be nul. + if (Str.back() != 0) return false; + + // Other elements must be non-nul. + return Str.drop_back().find(0) == StringRef::npos; +} + +/// getSplatValue - If this is a splat constant, meaning that all of the +/// elements have the same value, return that value. Otherwise return NULL. +Constant *ConstantDataVector::getSplatValue() const { + const char *Base = getRawDataValues().data(); + + // Compare elements 1+ to the 0'th element. + unsigned EltSize = getElementByteSize(); + for (unsigned i = 1, e = getNumElements(); i != e; ++i) + if (memcmp(Base, Base+i*EltSize, EltSize)) + return 0; + + // If they're all the same, return the 0th one as a representative. + return getElementAsConstant(0); +} //===----------------------------------------------------------------------===// // replaceUsesOfWithOnConstant implementations @@ -1959,59 +2455,49 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; - - std::pair Lookup; - Lookup.first.first = cast(getRawType()); - Lookup.second = this; + LLVMContextImpl *pImpl = getType()->getContext().pImpl; - std::vector &Values = Lookup.first.second; + SmallVector Values; + LLVMContextImpl::ArrayConstantsTy::LookupKey Lookup; + Lookup.first = cast(getType()); Values.reserve(getNumOperands()); // Build replacement array. - // Fill values with the modified operands of the constant array. Also, + // Fill values with the modified operands of the constant array. Also, // compute whether this turns into an all-zeros array. - bool isAllZeros = false; unsigned NumUpdated = 0; - if (!ToC->isNullValue()) { - for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { - Constant *Val = cast(O->get()); - if (Val == From) { - Val = ToC; - ++NumUpdated; - } - Values.push_back(Val); - } - } else { - isAllZeros = true; - for (Use *O = OperandList, *E = OperandList+getNumOperands();O != E; ++O) { - Constant *Val = cast(O->get()); - if (Val == From) { - Val = ToC; - ++NumUpdated; - } - Values.push_back(Val); - if (isAllZeros) isAllZeros = Val->isNullValue(); + + // Keep track of whether all the values in the array are "ToC". + bool AllSame = true; + for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { + Constant *Val = cast(O->get()); + if (Val == From) { + Val = ToC; + ++NumUpdated; } + Values.push_back(Val); + AllSame &= Val == ToC; } - + Constant *Replacement = 0; - if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + if (AllSame && ToC->isNullValue()) { + Replacement = ConstantAggregateZero::get(getType()); + } else if (AllSame && isa(ToC)) { + Replacement = UndefValue::get(getType()); } else { // Check to see if we have this array type already. - bool Exists; + Lookup.second = makeArrayRef(Values); LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I = - pImpl->ArrayConstants.InsertOrGetItem(Lookup, Exists); - - if (Exists) { - Replacement = I->second; + pImpl->ArrayConstants.find(Lookup); + + if (I != pImpl->ArrayConstants.map_end()) { + Replacement = I->first; } else { // Okay, the new shape doesn't exist in the system yet. Instead of // creating a new constant array, inserting it, replaceallusesof'ing the // old with the new, then deleting the old... just update the current one // in place! - pImpl->ArrayConstants.MoveConstantToNewSlot(this, I); - + pImpl->ArrayConstants.remove(this); + // Update to the new value. Optimize for the case when we have a single // operand that we're changing, but handle bulk updates efficiently. if (NumUpdated == 1) { @@ -2024,16 +2510,17 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, if (getOperand(i) == From) setOperand(i, ToC); } + pImpl->ArrayConstants.insert(this); return; } } - + // Otherwise, I do need to replace this with an existing value. assert(Replacement != this && "I didn't contain From!"); - + // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); - + replaceAllUsesWith(Replacement); + // Delete the old constant! destroyConstant(); } @@ -2046,60 +2533,69 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, unsigned OperandToUpdate = U-OperandList; assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); - std::pair Lookup; - Lookup.first.first = cast(getRawType()); - Lookup.second = this; - std::vector &Values = Lookup.first.second; + SmallVector Values; + LLVMContextImpl::StructConstantsTy::LookupKey Lookup; + Lookup.first = cast(getType()); Values.reserve(getNumOperands()); // Build replacement struct. - - - // Fill values with the modified operands of the constant struct. Also, + + // Fill values with the modified operands of the constant struct. Also, // compute whether this turns into an all-zeros struct. bool isAllZeros = false; - if (!ToC->isNullValue()) { - for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) - Values.push_back(cast(O->get())); - } else { + bool isAllUndef = false; + if (ToC->isNullValue()) { isAllZeros = true; for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { Constant *Val = cast(O->get()); Values.push_back(Val); if (isAllZeros) isAllZeros = Val->isNullValue(); } + } else if (isa(ToC)) { + isAllUndef = true; + for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { + Constant *Val = cast(O->get()); + Values.push_back(Val); + if (isAllUndef) isAllUndef = isa(Val); + } + } else { + for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) + Values.push_back(cast(O->get())); } Values[OperandToUpdate] = ToC; - - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; - + + LLVMContextImpl *pImpl = getContext().pImpl; + Constant *Replacement = 0; if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + Replacement = ConstantAggregateZero::get(getType()); + } else if (isAllUndef) { + Replacement = UndefValue::get(getType()); } else { // Check to see if we have this struct type already. - bool Exists; + Lookup.second = makeArrayRef(Values); LLVMContextImpl::StructConstantsTy::MapTy::iterator I = - pImpl->StructConstants.InsertOrGetItem(Lookup, Exists); - - if (Exists) { - Replacement = I->second; + pImpl->StructConstants.find(Lookup); + + if (I != pImpl->StructConstants.map_end()) { + Replacement = I->first; } else { // Okay, the new shape doesn't exist in the system yet. Instead of // creating a new constant struct, inserting it, replaceallusesof'ing the // old with the new, then deleting the old... just update the current one // in place! - pImpl->StructConstants.MoveConstantToNewSlot(this, I); - + pImpl->StructConstants.remove(this); + // Update to the new value. setOperand(OperandToUpdate, ToC); + pImpl->StructConstants.insert(this); return; } } - + assert(Replacement != this && "I didn't contain From!"); - + // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); - + replaceAllUsesWith(Replacement); + // Delete the old constant! destroyConstant(); } @@ -2107,21 +2603,21 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); - - std::vector Values; + + SmallVector Values; Values.reserve(getNumOperands()); // Build replacement array... for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { Constant *Val = getOperand(i); if (Val == From) Val = cast(To); Values.push_back(Val); } - - Constant *Replacement = get(cast(getRawType()), Values); + + Constant *Replacement = get(Values); assert(Replacement != this && "I didn't contain From!"); - + // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); - + replaceAllUsesWith(Replacement); + // Delete the old constant! destroyConstant(); } @@ -2130,98 +2626,19 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Use *U) { assert(isa(ToV) && "Cannot make Constant refer to non-constant!"); Constant *To = cast(ToV); - - Constant *Replacement = 0; - if (getOpcode() == Instruction::GetElementPtr) { - SmallVector Indices; - Constant *Pointer = getOperand(0); - Indices.reserve(getNumOperands()-1); - if (Pointer == From) Pointer = To; - - for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { - Constant *Val = getOperand(i); - if (Val == From) Val = To; - Indices.push_back(Val); - } - Replacement = ConstantExpr::getGetElementPtr(Pointer, - &Indices[0], Indices.size(), - cast(this)->isInBounds()); - } else if (getOpcode() == Instruction::ExtractValue) { - Constant *Agg = getOperand(0); - if (Agg == From) Agg = To; - - ArrayRef Indices = getIndices(); - Replacement = ConstantExpr::getExtractValue(Agg, - &Indices[0], Indices.size()); - } else if (getOpcode() == Instruction::InsertValue) { - Constant *Agg = getOperand(0); - Constant *Val = getOperand(1); - if (Agg == From) Agg = To; - if (Val == From) Val = To; - - ArrayRef Indices = getIndices(); - Replacement = ConstantExpr::getInsertValue(Agg, Val, - &Indices[0], Indices.size()); - } else if (isCast()) { - assert(getOperand(0) == From && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(getOpcode(), To, getRawType()); - } else if (getOpcode() == Instruction::Select) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - Constant *C3 = getOperand(2); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - if (C3 == From) C3 = To; - Replacement = ConstantExpr::getSelect(C1, C2, C3); - } else if (getOpcode() == Instruction::ExtractElement) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - Replacement = ConstantExpr::getExtractElement(C1, C2); - } else if (getOpcode() == Instruction::InsertElement) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - Constant *C3 = getOperand(1); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - if (C3 == From) C3 = To; - Replacement = ConstantExpr::getInsertElement(C1, C2, C3); - } else if (getOpcode() == Instruction::ShuffleVector) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - Constant *C3 = getOperand(2); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - if (C3 == From) C3 = To; - Replacement = ConstantExpr::getShuffleVector(C1, C2, C3); - } else if (isCompare()) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - if (getOpcode() == Instruction::ICmp) - Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2); - else { - assert(getOpcode() == Instruction::FCmp); - Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2); - } - } else if (getNumOperands() == 2) { - Constant *C1 = getOperand(0); - Constant *C2 = getOperand(1); - if (C1 == From) C1 = To; - if (C2 == From) C2 = To; - Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassOptionalData); - } else { - llvm_unreachable("Unknown ConstantExpr type!"); - return; + + SmallVector NewOps; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + Constant *Op = getOperand(i); + NewOps.push_back(Op == From ? To : Op); } - + + Constant *Replacement = getWithOperands(NewOps); assert(Replacement != this && "I didn't contain From!"); - + // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); - + replaceAllUsesWith(Replacement); + // Delete the old constant! destroyConstant(); }