X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=ba309d9ca0714a96a6e11a4ad13ec65e152ab0e4;hb=559c277aa9242dd5b32d2f2ccc353d938f886ee9;hp=2d3d71b6863c71f1897a9dafd1b33102f9325eb5;hpb=3821176b2eb9fe5e66929f3df6f204fa6cb2e4d6;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 2d3d71b6863..ba309d9ca07 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the Constant* classes... +// This file implements the Constant* classes. // //===----------------------------------------------------------------------===// @@ -29,36 +29,74 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/System/Mutex.h" -#include "llvm/System/RWMutex.h" -#include "llvm/System/Threading.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include -#include +#include using namespace llvm; //===----------------------------------------------------------------------===// // Constant Class //===----------------------------------------------------------------------===// +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 + if (const ConstantVector *CV = dyn_cast(this)) + return CV->isAllOnesValue(); + + return false; +} // Constructor to create a '0' constant of arbitrary type... -static const uint64_t zero[2] = {0, 0}; -Constant *Constant::getNullValue(const Type *Ty) { +Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); case Type::FloatTyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(32, 0))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEsingle)); case Type::DoubleTyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(64, 0))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::IEEEdouble)); case Type::X86_FP80TyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(80, 2, zero))); + return ConstantFP::get(Ty->getContext(), + APFloat::getZero(APFloat::x87DoubleExtended)); case Type::FP128TyID: return ConstantFP::get(Ty->getContext(), - APFloat(APInt(128, 2, zero), true)); + APFloat::getZero(APFloat::IEEEquad)); case Type::PPC_FP128TyID: - return ConstantFP::get(Ty->getContext(), APFloat(APInt(128, 2, zero))); + return ConstantFP::get(Ty->getContext(), + APFloat(APInt::getNullValue(128))); case Type::PointerTyID: return ConstantPointerNull::get(cast(Ty)); case Type::StructTyID: @@ -72,32 +110,38 @@ Constant *Constant::getNullValue(const Type *Ty) { } } -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)) + if (VectorType *VTy = dyn_cast(Ty)) C = ConstantVector::get(std::vector(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())); - - std::vector Elts; - const VectorType *VTy = cast(Ty); + + if (Ty->isFloatingPointTy()) { + APFloat FL = APFloat::getAllOnesValue(Ty->getPrimitiveSizeInBits(), + !Ty->isPPC_FP128Ty()); + return ConstantFP::get(Ty->getContext(), FL); + } + + SmallVector Elts; + VectorType *VTy = cast(Ty); Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); - assert(Elts[0] && "Not a vector integer type!"); + assert(Elts[0] && "Invalid AllOnes value!"); return cast(ConstantVector::get(Elts)); } @@ -113,7 +157,7 @@ void Constant::destroyConstantImpl() { Value *V = use_back(); #ifndef NDEBUG // Only in -g mode... if (!isa(V)) { - errs() << "While deleting: " << *this + dbgs() << "While deleting: " << *this << "\n\nUse still stuck around after Def is destroyed: " << *V << "\n\n"; } @@ -160,6 +204,21 @@ bool Constant::canTrap() const { } } +/// isConstantUsed - Return true if the constant has users other than constant +/// exprs and other dangling things. +bool Constant::isConstantUsed() const { + for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { + const Constant *UC = dyn_cast(*UI); + if (UC == 0 || isa(UC)) + return true; + + if (UC->isConstantUsed()) + return true; + } + return false; +} + + /// getRelocationInfo - This method classifies the entry according to /// whether or not it may generate a relocation entry. This must be @@ -185,6 +244,24 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { if (const BlockAddress *BA = dyn_cast(this)) return BA->getFunction()->getRelocationInfo(); + // While raw uses of blockaddress need to be relocated, differences between + // two of them don't when they are for labels in the same function. This is a + // common idiom when creating a table for the indirect goto extension, so we + // handle it efficiently here. + if (const ConstantExpr *CE = dyn_cast(this)) + if (CE->getOpcode() == Instruction::Sub) { + ConstantExpr *LHS = dyn_cast(CE->getOperand(0)); + ConstantExpr *RHS = dyn_cast(CE->getOperand(1)); + if (LHS && RHS && + LHS->getOpcode() == Instruction::PtrToInt && + RHS->getOpcode() == Instruction::PtrToInt && + isa(LHS->getOperand(0)) && + isa(RHS->getOperand(0)) && + cast(LHS->getOperand(0))->getFunction() == + cast(RHS->getOperand(0))->getFunction()) + return NoRelocation; + } + PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) Result = std::max(Result, @@ -198,9 +275,8 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { /// 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(LLVMContext &Context, - SmallVectorImpl &Elts) const { - assert(isa(getType()) && "Not a vector constant!"); +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) @@ -208,7 +284,7 @@ void Constant::getVectorElements(LLVMContext &Context, return; } - const VectorType *VT = cast(getType()); + VectorType *VT = cast(getType()); if (isa(this)) { Elts.assign(VT->getNumElements(), Constant::getNullValue(VT->getElementType())); @@ -224,32 +300,107 @@ void Constant::getVectorElements(LLVMContext &Context, } +/// 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; +} + + +/// removeDeadConstantUsers - If there are any dead constant users dangling +/// off of this constant, remove them. This method is useful for clients +/// that want to check to see if a global is unused, but don't want to deal +/// with potentially dead constants hanging off of the globals. +void Constant::removeDeadConstantUsers() const { + Value::const_use_iterator I = use_begin(), E = use_end(); + Value::const_use_iterator LastNonDeadUser = E; + while (I != E) { + const Constant *User = dyn_cast(*I); + if (User == 0) { + LastNonDeadUser = I; + ++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. + LastNonDeadUser = I; + ++I; + continue; + } + + // If the constant was dead, then the iterator is invalidated. + if (LastNonDeadUser == E) { + I = use_begin(); + if (I == E) break; + } else { + I = LastNonDeadUser; + ++I; + } + } +} + + //===----------------------------------------------------------------------===// // ConstantInt //===----------------------------------------------------------------------===// -ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V) +ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V) : Constant(Ty, ConstantIntVal, 0, 0), Val(V) { assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } -ConstantInt* ConstantInt::getTrue(LLVMContext &Context) { +ConstantInt *ConstantInt::getTrue(LLVMContext &Context) { LLVMContextImpl *pImpl = Context.pImpl; - if (pImpl->TheTrueVal) - return pImpl->TheTrueVal; - else - return (pImpl->TheTrueVal = - ConstantInt::get(IntegerType::get(Context, 1), 1)); + if (!pImpl->TheTrueVal) + pImpl->TheTrueVal = ConstantInt::get(Type::getInt1Ty(Context), 1); + return pImpl->TheTrueVal; } -ConstantInt* ConstantInt::getFalse(LLVMContext &Context) { +ConstantInt *ConstantInt::getFalse(LLVMContext &Context) { LLVMContextImpl *pImpl = Context.pImpl; - if (pImpl->TheFalseVal) - return pImpl->TheFalseVal; - else - return (pImpl->TheFalseVal = - ConstantInt::get(IntegerType::get(Context, 1), 0)); + if (!pImpl->TheFalseVal) + pImpl->TheFalseVal = ConstantInt::get(Type::getInt1Ty(Context), 0); + return pImpl->TheFalseVal; +} + +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); +} + +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); } @@ -258,9 +409,9 @@ ConstantInt* ConstantInt::getFalse(LLVMContext &Context) { // operator== and operator!= to ensure that the DenseMap doesn't attempt to // compare APInt's of different widths, which would violate an APInt class // invariant which generates an assertion. -ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { +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]; @@ -268,45 +419,44 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { return Slot; } -Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) { - Constant *C = get(cast(Ty->getScalarType()), - V, 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( - std::vector(VTy->getNumElements(), C)); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::get(SmallVector(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)) + if (VectorType *VTy = dyn_cast(Ty)) return ConstantVector::get( - std::vector(VTy->getNumElements(), C)); + SmallVector(VTy->getNumElements(), C)); return C; } -ConstantInt* ConstantInt::get(const IntegerType* Ty, const StringRef& Str, +ConstantInt* ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) { return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); } @@ -315,7 +465,7 @@ ConstantInt* ConstantInt::get(const IntegerType* Ty, const StringRef& Str, // ConstantFP //===----------------------------------------------------------------------===// -static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { +static const fltSemantics *TypeToFloatSemantics(Type *Ty) { if (Ty->isFloatTy()) return &APFloat::IEEEsingle; if (Ty->isDoubleTy()) @@ -332,7 +482,7 @@ static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { /// 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); @@ -342,30 +492,30 @@ 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)) + if (VectorType *VTy = dyn_cast(Ty)) return ConstantVector::get( - std::vector(VTy->getNumElements(), C)); + SmallVector(VTy->getNumElements(), C)); return C; } -Constant* ConstantFP::get(const Type* Ty, const 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)) + if (VectorType *VTy = dyn_cast(Ty)) return ConstantVector::get( - std::vector(VTy->getNumElements(), C)); + SmallVector(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(); apf.changeSign(); @@ -373,15 +523,15 @@ ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) { } -Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) { - if (const VectorType *PTy = dyn_cast(Ty)) - if (PTy->getElementType()->isFloatingPoint()) { - std::vector zeros(PTy->getNumElements(), +Constant *ConstantFP::getZeroValueForNegation(Type* Ty) { + if (VectorType *PTy = dyn_cast(Ty)) + if (PTy->getElementType()->isFloatingPointTy()) { + SmallVector zeros(PTy->getNumElements(), getNegativeZero(PTy->getElementType())); - return ConstantVector::get(PTy, zeros); + return ConstantVector::get(zeros); } - if (Ty->isFloatingPoint()) + if (Ty->isFloatingPointTy()) return getNegativeZero(Ty); return Constant::getNullValue(Ty); @@ -397,7 +547,7 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { ConstantFP *&Slot = pImpl->FPConstants[Key]; if (!Slot) { - const Type *Ty; + Type *Ty; if (&V.getSemantics() == &APFloat::IEEEsingle) Ty = Type::getFloatTy(Context); else if (&V.getSemantics() == &APFloat::IEEEdouble) @@ -417,23 +567,19 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& 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 { +bool ConstantFP::isExactlyValue(const APFloat &V) const { return Val.bitwiseIsEqual(V); } @@ -442,25 +588,19 @@ bool ConstantFP::isExactlyValue(const APFloat& V) const { //===----------------------------------------------------------------------===// -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) { for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); @@ -469,36 +609,27 @@ Constant *ConstantArray::get(const ArrayType *Ty, // If this is an all-zero array, return a ConstantAggregateZero object if (!V.empty()) { Constant *C = V[0]; - if (!C->isNullValue()) { - // Implicitly locked. + if (!C->isNullValue()) return pImpl->ArrayConstants.getOrCreate(Ty, V); - } + for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - // Implicitly locked. + if (V[i] != C) return pImpl->ArrayConstants.getOrCreate(Ty, V); - } } return ConstantAggregateZero::get(Ty); } - -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)); -} - /// 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, const StringRef &Str, +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])); @@ -511,78 +642,78 @@ Constant* ConstantArray::get(LLVMContext &Context, const StringRef &Str, return get(ATy, ElementVals); } +/// 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) { + SmallVector EltTypes; + for (unsigned i = 0, e = V.size(); i != e; ++i) + EltTypes.push_back(V[i]->getType()); + + return StructType::get(Context, EltTypes, Packed); +} + + +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... +Constant *ConstantStruct::get(StructType *ST, ArrayRef V) { + // Create a ConstantAggregateZero value if all elements are zeros. for (unsigned i = 0, e = V.size(); i != e; ++i) if (!V[i]->isNullValue()) - // Implicitly locked. - return pImpl->StructConstants.getOrCreate(T, V); - - return ConstantAggregateZero::get(T); -} + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V); -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); + assert((ST->isOpaque() || ST->getNumElements() == V.size()) && + "Incorrect # elements specified to ConstantStruct::get"); + return ConstantAggregateZero::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); +Constant *ConstantStruct::get(StructType *T, ...) { + va_list ap; + SmallVector Values; + va_start(ap, T); + while (Constant *Val = va_arg(ap, llvm::Constant*)) + Values.push_back(Val); + va_end(ap); + 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) { - assert(!V.empty() && "Vectors can't be empty"); - LLVMContext &Context = T->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; - - // If this is an all-undef or alll-zero vector, return a +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 // ConstantAggregateZero or UndefValue. Constant *C = V[0]; bool isZero = C->isNullValue(); @@ -601,35 +732,9 @@ Constant* ConstantVector::get(const VectorType* T, if (isUndef) return UndefValue::get(T); - // Implicitly locked. return pImpl->VectorConstants.getOrCreate(T, V); } -Constant* ConstantVector::get(const std::vector& V) { - assert(!V.empty() && "Cannot infer type if V is empty"); - return get(VectorType::get(V.front()->getType(),V.size()), V); -} - -Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) { - // FIXME: make this the primary ctor method. - return get(std::vector(Vals, Vals+NumVals)); -} - -Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::SDiv, C1, C2, - SDivOperator::IsExact); -} - // 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 @@ -645,7 +750,7 @@ bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const { if (getOpcode() != Instruction::GetElementPtr) return false; gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this); - User::const_op_iterator OI = next(this->op_begin()); + User::const_op_iterator OI = llvm::next(this->op_begin()); // Skip the first index, as it has no static limit. ++GEPI; @@ -656,7 +761,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; @@ -671,7 +776,7 @@ bool ConstantExpr::hasIndices() const { getOpcode() == Instruction::InsertValue; } -const SmallVector &ConstantExpr::getIndices() const { +ArrayRef ConstantExpr::getIndices() const { if (const ExtractValueConstantExpr *EVCE = dyn_cast(this)) return EVCE->Indices; @@ -680,8 +785,7 @@ const SmallVector &ConstantExpr::getIndices() const { } unsigned ConstantExpr::getPredicate() const { - assert(getOpcode() == Instruction::FCmp || - getOpcode() == Instruction::ICmp); + assert(isCompare()); return ((const CompareConstantExpr*)this)->predicate; } @@ -735,34 +839,32 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { 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()); + return + ConstantExpr::getGetElementPtr(Op, Ops, + cast(this)->isInBounds()); Ops[OpNo-1] = Op; - return cast(this)->isInBounds() ? - ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) : - ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); + return + ConstantExpr::getGetElementPtr(getOperand(0), Ops, + cast(this)->isInBounds()); } 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, SubclassData); + return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassOptionalData); } } /// 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(Constant* const *Ops, unsigned NumOps) const { - assert(NumOps == getNumOperands() && "Operand count mismatch!"); - bool AnyChange = false; - for (unsigned i = 0; i != NumOps; ++i) { - assert(Ops[i]->getType() == getOperand(i)->getType() && - "Operand type mismatch!"); +getWithOperands(ArrayRef Ops, Type *Ty) const { + assert(Ops.size() == getNumOperands() && "Operand count 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); @@ -779,7 +881,7 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) 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: @@ -789,15 +891,15 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { 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], NumOps-1) : - ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-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]); default: assert(getNumOperands() == 2 && "Must be binary operator?"); - return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData); + return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData); } } @@ -805,7 +907,7 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { //===----------------------------------------------------------------------===// // isValueValidForType implementations -bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { +bool ConstantInt::isValueValidForType(Type *Ty, uint64_t Val) { unsigned NumBits = cast(Ty)->getBitWidth(); // assert okay if (Ty == Type::getInt1Ty(Ty->getContext())) return Val == 0 || Val == 1; @@ -815,7 +917,7 @@ bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { return Val <= Max; } -bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) { +bool ConstantInt::isValueValidForType(Type *Ty, int64_t Val) { unsigned NumBits = cast(Ty)->getBitWidth(); // assert okay if (Ty == Type::getInt1Ty(Ty->getContext())) return Val == 0 || Val == 1 || Val == -1; @@ -826,7 +928,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; @@ -866,19 +968,17 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { //===----------------------------------------------------------------------===// // Factory Function Implementation -ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { - assert((isa(Ty) || isa(Ty) || isa(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; - // Implicitly locked. return pImpl->AggZeroConstants.getOrCreate(Ty, 0); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantAggregateZero::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->AggZeroConstants.remove(this); destroyConstantImpl(); } @@ -886,7 +986,6 @@ void ConstantAggregateZero::destroyConstant() { /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } @@ -895,7 +994,7 @@ void ConstantArray::destroyConstant() { /// if the elements of the array are all ConstantInt's. bool ConstantArray::isString() const { // Check the element type for i8... - if (getType()->getElementType() != Type::getInt8Ty(getContext())) + if (!getType()->getElementType()->isIntegerTy(8)) return false; // Check the elements to make sure they are all integers, not constant // expressions. @@ -910,7 +1009,7 @@ bool ConstantArray::isString() const { /// null bytes except its terminator. bool ConstantArray::isCString() const { // Check the element type for i8... - if (getType()->getElementType() != Type::getInt8Ty(getContext())) + if (!getType()->getElementType()->isIntegerTy(8)) return false; // Last element must be a null. @@ -927,31 +1026,40 @@ bool ConstantArray::isCString() const { } -/// 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. +/// convertToString - Helper function for getAsString() and getAsCString(). +static std::string convertToString(const User *U, unsigned len) { + std::string Result; + Result.reserve(len); + for (unsigned i = 0; i != len; ++i) + Result.push_back((char)cast(U->getOperand(i))->getZExtValue()); + return Result; +} + +/// getAsString - If this array is isString(), 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; + return convertToString(this, getNumOperands()); } -//---- ConstantStruct::get() implementation... -// +/// getAsCString - If this array is isCString(), then this method converts the +/// array (without the trailing null byte) to an std::string and returns it. +/// Otherwise, it asserts out. +/// +std::string ConstantArray::getAsCString() const { + assert(isCString() && "Not a string!"); + return convertToString(this, getNumOperands() - 1); +} -namespace llvm { -} +//---- ConstantStruct::get() implementation... +// // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } @@ -959,50 +1067,52 @@ void ConstantStruct::destroyConstant() { // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { - // Implicitly locked. 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. +/// @returns true iff this constant's elements 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; + const ConstantFP *CF = dyn_cast(Elt); + // 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; + for (unsigned I = 1, E = getNumOperands(); I < E; ++I) + if (getOperand(I) != Elt) + return false; + + // First value is all-ones. + return (CI && CI->isAllOnesValue()) || + (CF && CF->isAllOnesValue()); } /// 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() { +Constant *ConstantVector::getSplatValue() const { // Check out first element. 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) { - // Implicitly locked. +ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0); } // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->NullPtrConstants.remove(this); destroyConstantImpl(); } @@ -1011,7 +1121,7 @@ void ConstantPointerNull::destroyConstant() { //---- UndefValue::get() implementation. // -UndefValue *UndefValue::get(const Type *Ty) { +UndefValue *UndefValue::get(Type *Ty) { return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0); } @@ -1043,8 +1153,8 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { BlockAddress::BlockAddress(Function *F, BasicBlock *BB) : Constant(Type::getInt8PtrTy(F->getContext()), Value::BlockAddressVal, &Op<0>(), 2) { - Op<0>() = F; - Op<1>() = BB; + setOperand(0, F); + setOperand(1, BB); BB->AdjustBlockAddressRefCount(1); } @@ -1074,13 +1184,16 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { 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(), getBasicBlock())); NewBA = this; - Op<0>() = NewF; - Op<1>() = NewBB; + setOperand(0, NewF); + setOperand(1, NewBB); + getBasicBlock()->AdjustBlockAddressRefCount(1); return; } @@ -1088,7 +1201,7 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(NewBA != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(NewBA); + replaceAllUsesWith(NewBA); destroyConstant(); } @@ -1099,10 +1212,10 @@ 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(Ty->getContext(), opc, C, Ty)) + if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty)) return FC; LLVMContextImpl *pImpl = Ty->getContext().pImpl; @@ -1111,67 +1224,66 @@ static inline Constant *getFoldedCast( std::vector argVec(1, C); ExprMapKeyType Key(opc, argVec); - // Implicitly locked. 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"); - assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); + assert(CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"); 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); - case Instruction::FPTrunc: return getFPTrunc(C, Ty); - case Instruction::FPExt: return getFPExtend(C, Ty); - case Instruction::UIToFP: return getUIToFP(C, Ty); - case Instruction::SIToFP: return getSIToFP(C, Ty); - case Instruction::FPToUI: return getFPToUI(C, Ty); - case Instruction::FPToSI: return getFPToSI(C, Ty); - case Instruction::PtrToInt: return getPtrToInt(C, Ty); - case Instruction::IntToPtr: return getIntToPtr(C, Ty); - case Instruction::BitCast: return getBitCast(C, Ty); + 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); + case Instruction::FPTrunc: return getFPTrunc(C, Ty); + case Instruction::FPExt: return getFPExtend(C, Ty); + case Instruction::UIToFP: return getUIToFP(C, Ty); + case Instruction::SIToFP: return getSIToFP(C, Ty); + case Instruction::FPToUI: return getFPToUI(C, Ty); + case Instruction::FPToSI: return getFPToSI(C, Ty); + case Instruction::PtrToInt: return getPtrToInt(C, 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 getCast(Instruction::BitCast, C, Ty); - return getCast(Instruction::ZExt, C, Ty); + 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 getCast(Instruction::BitCast, C, Ty); - return getCast(Instruction::SExt, C, Ty); + 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 getCast(Instruction::BitCast, C, Ty); - return getCast(Instruction::Trunc, C, Ty); + return getBitCast(C, Ty); + return getTrunc(C, Ty); } -Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) { - assert(isa(S->getType()) && "Invalid cast"); - assert((Ty->isInteger() || isa(Ty)) && "Invalid cast"); +Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { + assert(S->getType()->isPointerTy() && "Invalid cast"); + assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"); - if (Ty->isInteger()) - return getCast(Instruction::PtrToInt, S, Ty); - return getCast(Instruction::BitCast, S, Ty); + if (Ty->isIntegerTy()) + return getPtrToInt(S, 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()->isIntOrIntVector() && - Ty->isIntOrIntVector() && "Invalid cast"); + assert(C->getType()->isIntOrIntVectorTy() && + Ty->isIntOrIntVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = @@ -1181,155 +1293,143 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, return getCast(opcode, C, Ty); } -Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { - assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && +Constant *ConstantExpr::getFPCast(Constant *C, Type *Ty) { + assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); if (SrcBits == DstBits) return C; // Avoid a useless cast Instruction::CastOps opcode = - (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt); + (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer"); - assert(Ty->isIntOrIntVector() && "Trunc produces only integral"); + assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer"); + assert(Ty->isIntOrIntVectorTy() && "Trunc produces only integral"); assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "SrcTy must be larger than DestTy for Trunc!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral"); - assert(Ty->isIntOrIntVector() && "SExt produces only integer"); + assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral"); + assert(Ty->isIntOrIntVectorTy() && "SExt produces only integer"); assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for SExt!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral"); - assert(Ty->isIntOrIntVector() && "ZExt produces only integer"); + assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral"); + assert(Ty->isIntOrIntVectorTy() && "ZExt produces only integer"); assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for ZExt!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && + assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "This is an illegal floating point truncation!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && + assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "This is an illegal floating point extension!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() && + assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && "This is an illegal uint to floating point cast!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() && + assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && "This is an illegal sint to floating point cast!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() && + assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && "This is an illegal floating point to uint cast!"); 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; #endif assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); - assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() && + assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && "This is an illegal floating point to sint cast!"); return getFoldedCast(Instruction::FPToSI, C, Ty); } -Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) { - assert(isa(C->getType()) && "PtrToInt source must be pointer"); - assert(DstTy->isInteger() && "PtrToInt destination must be integral"); +Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy) { + assert(C->getType()->isPointerTy() && "PtrToInt source must be pointer"); + assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral"); return getFoldedCast(Instruction::PtrToInt, C, DstTy); } -Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) { - assert(C->getType()->isInteger() && "IntToPtr source must be integral"); - assert(isa(DstTy) && "IntToPtr destination must be a pointer"); +Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) { + assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral"); + assert(DstTy->isPointerTy() && "IntToPtr destination must be a pointer"); return getFoldedCast(Instruction::IntToPtr, C, DstTy); } -Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { - // BitCast implies a no-op cast of type only. No bits change. However, you - // can't cast pointers to anything but pointers. -#ifndef NDEBUG - const Type *SrcTy = C->getType(); - assert((isa(SrcTy) == isa(DstTy)) && - "BitCast cannot cast pointer to non-pointer and vice versa"); - - // Now we know we're not dealing with mismatched pointer casts (ptr->nonptr - // or nonptr->ptr). For all the other types, the cast is okay if source and - // destination bit widths are identical. - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DstBitSize = DstTy->getPrimitiveSizeInBits(); -#endif - assert(SrcBitSize == DstBitSize && "BitCast requires types of same width"); +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. @@ -1338,109 +1438,66 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { 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(ReqTy->getContext(), - 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; - // Implicitly locked. - 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) { - // API compatibility: Adjust integer opcodes to floating-point opcodes. - if (C1->getType()->isFPOrFPVector()) { - if (Opcode == Instruction::Add) Opcode = Instruction::FAdd; - else if (Opcode == Instruction::Sub) Opcode = Instruction::FSub; - else if (Opcode == Instruction::Mul) Opcode = Instruction::FMul; - } #ifndef NDEBUG switch (Opcode) { case Instruction::Add: case Instruction::Sub: case Instruction::Mul: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntOrIntVector() && + assert(C1->getType()->isIntOrIntVectorTy() && "Tried to create an integer operation on a non-integer type!"); break; case Instruction::FAdd: case Instruction::FSub: case Instruction::FMul: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isFPOrFPVector() && + assert(C1->getType()->isFPOrFPVectorTy() && "Tried to create a floating-point operation on a " "non-floating-point type!"); break; case Instruction::UDiv: case Instruction::SDiv: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntOrIntVector() && + assert(C1->getType()->isIntOrIntVectorTy() && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::FDiv: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isFPOrFPVector() && + assert(C1->getType()->isFPOrFPVectorTy() && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::URem: case Instruction::SRem: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntOrIntVector() && + assert(C1->getType()->isIntOrIntVectorTy() && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::FRem: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isFPOrFPVector() && + assert(C1->getType()->isFPOrFPVectorTy() && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::And: case Instruction::Or: case Instruction::Xor: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntOrIntVector() && + assert(C1->getType()->isIntOrIntVectorTy() && "Tried to create a logical operation on a non-integral type!"); break; case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntOrIntVector() && + assert(C1->getType()->isIntOrIntVectorTy() && "Tried to create a shift operation on a non-integer type!"); break; default: @@ -1448,172 +1505,129 @@ 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); - return getCast(Instruction::PtrToInt, GEP, - Type::getInt64Ty(Ty->getContext())); + Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); + return getPtrToInt(GEP, + Type::getInt64Ty(Ty->getContext())); } -Constant* ConstantExpr::getAlignOf(const Type* Ty) { - // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1 +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::getInt8Ty(Ty->getContext()), Ty, NULL); + Type *AligningTy = + StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); - Constant *Zero = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 0); + 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); - return getCast(Instruction::PtrToInt, GEP, - Type::getInt32Ty(Ty->getContext())); + 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(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[] = { - ConstantInt::get(Type::getInt64Ty(STy->getContext()), 0), - ConstantInt::get(Type::getInt32Ty(STy->getContext()), FieldNo) + ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0), + FieldNo }; Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(STy)), GEPIdx, 2); - return getCast(Instruction::PtrToInt, GEP, - Type::getInt64Ty(STy->getContext())); + 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( - ReqTy->getContext(), 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; - - // Implicitly locked. - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, - Value* const *Idxs, - unsigned NumIdx) { - assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, - Idxs+NumIdx) == - cast(ReqTy)->getElementType() && - "GEP indices invalid!"); - - if (Constant *FC = ConstantFoldGetElementPtr( - ReqTy->getContext(), C, /*inBounds=*/false, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... - - assert(isa(C->getType()) && - "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.push_back(C); - for (unsigned i = 0; i != NumIdx; ++i) - ArgVec.push_back(cast(Idxs[i])); - const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); + LLVMContextImpl *pImpl = C->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); } -Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, - Constant *C, - Value* const *Idxs, - unsigned NumIdx) { - assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, - Idxs+NumIdx) == - cast(ReqTy)->getElementType() && - "GEP indices invalid!"); - - if (Constant *FC = ConstantFoldGetElementPtr( - ReqTy->getContext(), C, /*inBounds=*/true, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... +Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef Idxs, + bool InBounds) { + if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) + return FC; // Fold a few common cases. - assert(isa(C->getType()) && + // Get the result type of the getelementptr! + Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs); + assert(Ty && "GEP indices invalid!"); + unsigned AS = cast(C->getType())->getAddressSpace(); + 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, - GEPOperator::IsInBounds); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - - // Implicitly locked. + InBounds ? GEPOperator::IsInBounds : 0); + + LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, - unsigned NumIdx) { - // 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); -} - -Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, - Value* const *Idxs, - unsigned NumIdx) { - // 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 getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); -} - -Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs, - unsigned NumIdx) { - return getGetElementPtr(C, (Value* const *)Idxs, NumIdx); -} - -Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, - Constant* const *Idxs, - unsigned NumIdx) { - return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx); -} - Constant * -ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) { +ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { assert(LHS->getType() == RHS->getType()); assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate"); - if (Constant *FC = ConstantFoldCompareInstruction( - LHS->getContext(), pred, LHS, RHS)) + if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness @@ -1623,20 +1637,20 @@ 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); - LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; + Type *ResultTy = Type::getInt1Ty(LHS->getContext()); + if (VectorType *VT = dyn_cast(LHS->getType())) + ResultTy = VectorType::get(ResultTy, VT->getNumElements()); - // Implicitly locked. - return - pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); + LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ResultTy, Key); } Constant * -ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { +ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { assert(LHS->getType() == RHS->getType()); assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate"); - if (Constant *FC = ConstantFoldCompareInstruction( - LHS->getContext(), pred, LHS, RHS)) + if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness @@ -1645,82 +1659,53 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { ArgVec.push_back(RHS); // Get the key type with both the opcode and predicate const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred); - - LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; - - // Implicitly locked. - return - pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); -} -Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, - Constant *Idx) { - if (Constant *FC = ConstantFoldExtractElementInstruction( - ReqTy->getContext(), 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; - - // Implicitly locked. - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); + 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::getExtractElement(Constant *Val, Constant *Idx) { - assert(isa(Val->getType()) && + assert(Val->getType()->isVectorTy() && "Tried to create extractelement operation on non-vector type!"); - assert(Idx->getType() == Type::getInt32Ty(Val->getContext()) && + assert(Idx->getType()->isIntegerTy(32) && "Extractelement index must be i32 type!"); - return getExtractElementTy(cast(Val->getType())->getElementType(), - Val, Idx); -} - -Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, - Constant *Elt, Constant *Idx) { - if (Constant *FC = ConstantFoldInsertElementInstruction( - ReqTy->getContext(), Val, Elt, Idx)) - return FC; // Fold a few common cases... + + 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(Elt); ArgVec.push_back(Idx); - const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec); - // Implicitly locked. + LLVMContextImpl *pImpl = Val->getContext().pImpl; + Type *ReqTy = cast(Val->getType())->getElementType(); return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, Constant *Idx) { - assert(isa(Val->getType()) && + 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() == Type::getInt32Ty(Val->getContext()) && + assert(Idx->getType()->isIntegerTy(32) && "Insertelement index must be i32 type!"); - return getInsertElementTy(Val->getType(), Val, Elt, Idx); -} -Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, - Constant *V2, Constant *Mask) { - if (Constant *FC = ConstantFoldShuffleVectorInstruction( - ReqTy->getContext(), V1, V2, Mask)) - return FC; // Fold a few common cases... + 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 - std::vector ArgVec(1, V1); - ArgVec.push_back(V2); - ArgVec.push_back(Mask); - const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + std::vector ArgVec(1, Val); + ArgVec.push_back(Elt); + ArgVec.push_back(Idx); + const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); - // Implicitly locked. - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); + LLVMContextImpl *pImpl = Val->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(Val->getType(), Key); } Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, @@ -1728,169 +1713,162 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, 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. + 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); -} + Type *EltTy = cast(V1->getType())->getElementType(); + Type *ShufTy = VectorType::get(EltTy, NElts); -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() && - "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( - ReqTy->getContext(), Agg, Val, Idxs, NumIdx); - assert(FC && "InsertValue constant expr couldn't be folded!"); - return FC; + // 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 = ShufTy->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ShufTy, Key); } Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx) { - assert(Agg->getType()->isFirstClassType() && - "Tried to create insertelement 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); -} - -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!"); + ArrayRef Idxs) { + assert(ExtractValueInst::getIndexedType(Agg->getType(), + Idxs) == Val->getType() && + "insertvalue indices invalid!"); assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant extractvalue expression"); - Constant *FC = ConstantFoldExtractValueInstruction( - ReqTy->getContext(), Agg, Idxs, NumIdx); - assert(FC && "ExtractValue 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::getExtractValue(Constant *Agg, - const unsigned *IdxList, unsigned NumIdx) { + ArrayRef Idxs) { assert(Agg->getType()->isFirstClassType() && "Tried to create extractelement operation on non-first-class type!"); - const Type *ReqTy = - ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx); + Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs); + (void)ReqTy; assert(ReqTy && "extractvalue indices invalid!"); - return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); + + assert(Agg->getType()->isFirstClassType() && + "Non-first-class type for constant extractvalue expression"); + Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs); + assert(FC && "ExtractValue constant expr couldn't be folded!"); + return FC; } -Constant* ConstantExpr::getNeg(Constant* C) { - // API compatibility: Adjust integer opcodes to floating-point opcodes. - if (C->getType()->isFPOrFPVector()) - return getFNeg(C); - assert(C->getType()->isIntOrIntVector() && +Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { + assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); - return get(Instruction::Sub, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getSub(ConstantFP::getZeroValueForNegation(C->getType()), + C, HasNUW, HasNSW); } -Constant* ConstantExpr::getFNeg(Constant* C) { - assert(C->getType()->isFPOrFPVector() && +Constant *ConstantExpr::getFNeg(Constant *C) { + assert(C->getType()->isFPOrFPVectorTy() && "Cannot FNEG a non-floating-point value!"); - return get(Instruction::FSub, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getFSub(ConstantFP::getZeroValueForNegation(C->getType()), C); } -Constant* ConstantExpr::getNot(Constant* C) { - assert(C->getType()->isIntOrIntVector() && +Constant *ConstantExpr::getNot(Constant *C) { + assert(C->getType()->isIntOrIntVectorTy() && "Cannot NOT a nonintegral value!"); return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType())); } -Constant* ConstantExpr::getAdd(Constant* C1, Constant* C2) { - return get(Instruction::Add, C1, C2); +Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Add, C1, C2, Flags); } -Constant* ConstantExpr::getFAdd(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) { return get(Instruction::FAdd, C1, C2); } -Constant* ConstantExpr::getSub(Constant* C1, Constant* C2) { - return get(Instruction::Sub, C1, C2); +Constant *ConstantExpr::getSub(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Sub, C1, C2, Flags); } -Constant* ConstantExpr::getFSub(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) { return get(Instruction::FSub, C1, C2); } -Constant* ConstantExpr::getMul(Constant* C1, Constant* C2) { - return get(Instruction::Mul, C1, C2); +Constant *ConstantExpr::getMul(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Mul, C1, C2, Flags); } -Constant* ConstantExpr::getFMul(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) { return get(Instruction::FMul, C1, C2); } -Constant* ConstantExpr::getUDiv(Constant* C1, Constant* C2) { - return get(Instruction::UDiv, C1, C2); +Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::UDiv, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -Constant* ConstantExpr::getSDiv(Constant* C1, Constant* C2) { - return get(Instruction::SDiv, C1, C2); +Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::SDiv, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -Constant* ConstantExpr::getFDiv(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { return get(Instruction::FDiv, C1, C2); } -Constant* ConstantExpr::getURem(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) { return get(Instruction::URem, C1, C2); } -Constant* ConstantExpr::getSRem(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) { return get(Instruction::SRem, C1, C2); } -Constant* ConstantExpr::getFRem(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) { return get(Instruction::FRem, C1, C2); } -Constant* ConstantExpr::getAnd(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) { return get(Instruction::And, C1, C2); } -Constant* ConstantExpr::getOr(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) { return get(Instruction::Or, C1, C2); } -Constant* ConstantExpr::getXor(Constant* C1, Constant* C2) { +Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) { return get(Instruction::Xor, C1, C2); } -Constant* ConstantExpr::getShl(Constant* C1, Constant* C2) { - return get(Instruction::Shl, C1, C2); +Constant *ConstantExpr::getShl(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Shl, C1, C2, Flags); } -Constant* ConstantExpr::getLShr(Constant* C1, Constant* C2) { - return get(Instruction::LShr, C1, C2); +Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::LShr, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } -Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) { - return get(Instruction::AShr, C1, C2); +Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { + return get(Instruction::AShr, C1, C2, + isExact ? PossiblyExactOperator::IsExact : 0); } // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { - // Implicitly locked. - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - pImpl->ExprConstants.remove(this); + getType()->getContext().pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -1898,6 +1876,20 @@ const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } + + +GetElementPtrConstantExpr:: +GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, + Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + OperandTraits::op_end(this) + - (IdxList.size()+1), IdxList.size()+1) { + OperandList[0] = C; + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + OperandList[i+1] = IdxList[i]; +} + + //===----------------------------------------------------------------------===// // replaceUsesOfWithOnConstant implementations @@ -1917,11 +1909,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); - LLVMContext &Context = getType()->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; + LLVMContextImpl *pImpl = getType()->getContext().pImpl; std::pair Lookup; - Lookup.first.first = getType(); + Lookup.first.first = cast(getType()); Lookup.second = this; std::vector &Values = Lookup.first.second; @@ -1991,7 +1982,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); @@ -2006,7 +1997,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); std::pair Lookup; - Lookup.first.first = getType(); + Lookup.first.first = cast(getType()); Lookup.second = this; std::vector &Values = Lookup.first.second; Values.reserve(getNumOperands()); // Build replacement struct. @@ -2028,14 +2019,13 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - LLVMContext &Context = getType()->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; + LLVMContextImpl *pImpl = getContext().pImpl; Constant *Replacement = 0; if (isAllZeros) { Replacement = ConstantAggregateZero::get(getType()); } else { - // Check to see if we have this array type already. + // Check to see if we have this struct type already. bool Exists; LLVMContextImpl::StructConstantsTy::MapTy::iterator I = pImpl->StructConstants.InsertOrGetItem(Lookup, Exists); @@ -2058,7 +2048,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); @@ -2076,11 +2066,11 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Values.push_back(Val); } - Constant *Replacement = get(getType(), 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(); @@ -2103,24 +2093,22 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (Val == From) Val = To; Indices.push_back(Val); } - Replacement = ConstantExpr::getGetElementPtr(Pointer, - &Indices[0], Indices.size()); + Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices, + cast(this)->isInBounds()); } else if (getOpcode() == Instruction::ExtractValue) { Constant *Agg = getOperand(0); if (Agg == From) Agg = To; - const SmallVector &Indices = getIndices(); - Replacement = ConstantExpr::getExtractValue(Agg, - &Indices[0], Indices.size()); + ArrayRef Indices = getIndices(); + Replacement = ConstantExpr::getExtractValue(Agg, Indices); } else if (getOpcode() == Instruction::InsertValue) { Constant *Agg = getOperand(0); Constant *Val = getOperand(1); if (Agg == From) Agg = To; if (Val == From) Val = To; - const SmallVector &Indices = getIndices(); - Replacement = ConstantExpr::getInsertValue(Agg, Val, - &Indices[0], Indices.size()); + ArrayRef Indices = getIndices(); + Replacement = ConstantExpr::getInsertValue(Agg, Val, Indices); } else if (isCast()) { assert(getOperand(0) == From && "Cast only has one use!"); Replacement = ConstantExpr::getCast(getOpcode(), To, getType()); @@ -2170,7 +2158,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Constant *C2 = getOperand(1); if (C1 == From) C1 = To; if (C2 == From) C2 = To; - Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData); + Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassOptionalData); } else { llvm_unreachable("Unknown ConstantExpr type!"); return; @@ -2179,7 +2167,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant();