X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=d3361ccfc4d0eee6d083b338034d9bbc2faabe74;hb=bda20650d2ec113bd78b8c809dbfafa7f7077152;hp=1553bd51342d23b5048afd590db3287e13c925cf;hpb=04e3b1ef788cfac266896c6e89050c4ff60114e2;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 1553bd51342..d3361ccfc4d 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -31,8 +31,9 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include -#include +#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -40,26 +41,28 @@ using namespace llvm; //===----------------------------------------------------------------------===// // Constructor to create a '0' constant of arbitrary type... -static const uint64_t zero[2] = {0, 0}; Constant *Constant::getNullValue(const 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: - case Type::UnionTyID: case Type::ArrayTyID: case Type::VectorTyID: return ConstantAggregateZero::get(Ty); @@ -70,7 +73,7 @@ Constant *Constant::getNullValue(const Type *Ty) { } } -Constant* Constant::getIntegerValue(const Type *Ty, const APInt &V) { +Constant *Constant::getIntegerValue(const Type *Ty, const APInt &V) { const Type *ScalarTy = Ty->getScalarType(); // Create the base integer constant. @@ -87,12 +90,18 @@ Constant* Constant::getIntegerValue(const Type *Ty, const APInt &V) { return C; } -Constant* Constant::getAllOnesValue(const Type *Ty) { +Constant *Constant::getAllOnesValue(const Type *Ty) { if (const IntegerType *ITy = dyn_cast(Ty)) return ConstantInt::get(Ty->getContext(), APInt::getAllOnesValue(ITy->getBitWidth())); - - std::vector Elts; + + if (Ty->isFloatingPointTy()) { + APFloat FL = APFloat::getAllOnesValue(Ty->getPrimitiveSizeInBits(), + !Ty->isPPC_FP128Ty()); + 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!"); @@ -254,6 +263,59 @@ void Constant::getVectorElements(SmallVectorImpl &Elts) const { } +/// 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 @@ -264,22 +326,44 @@ ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& 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(const Type *Ty) { + const 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(const Type *Ty) { + const 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); } @@ -288,7 +372,7 @@ 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()); // get an existing value or the insertion position @@ -298,14 +382,13 @@ 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(const 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)); + return ConstantVector::get(SmallVector(VTy->getNumElements(), C)); return C; } @@ -323,7 +406,7 @@ Constant *ConstantInt::getSigned(const Type *Ty, int64_t V) { return get(Ty, V, true); } -Constant* ConstantInt::get(const Type* Ty, const APInt& V) { +Constant *ConstantInt::get(const 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!"); @@ -331,7 +414,7 @@ Constant* ConstantInt::get(const Type* Ty, const APInt& V) { // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast(Ty)) return ConstantVector::get( - std::vector(VTy->getNumElements(), C)); + SmallVector(VTy->getNumElements(), C)); return C; } @@ -362,7 +445,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(const Type* Ty, double V) { LLVMContext &Context = Ty->getContext(); APFloat FV(V); @@ -374,13 +457,13 @@ Constant* ConstantFP::get(const Type* Ty, double V) { // For vectors, broadcast the value. if (const 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, StringRef Str) { +Constant *ConstantFP::get(const Type* Ty, StringRef Str) { LLVMContext &Context = Ty->getContext(); APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str); @@ -389,7 +472,7 @@ Constant* ConstantFP::get(const Type* Ty, StringRef Str) { // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast(Ty)) return ConstantVector::get( - std::vector(VTy->getNumElements(), C)); + SmallVector(VTy->getNumElements(), C)); return C; } @@ -403,12 +486,12 @@ ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) { } -Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) { +Constant *ConstantFP::getZeroValueForNegation(const Type* Ty) { if (const VectorType *PTy = dyn_cast(Ty)) if (PTy->getElementType()->isFloatingPointTy()) { - std::vector zeros(PTy->getNumElements(), + SmallVector zeros(PTy->getNumElements(), getNegativeZero(PTy->getElementType())); - return ConstantVector::get(PTy, zeros); + return ConstantVector::get(zeros); } if (Ty->isFloatingPointTy()) @@ -489,8 +572,7 @@ ConstantArray::ConstantArray(const ArrayType *T, } } -Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector &V) { +Constant *ConstantArray::get(const 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"); @@ -510,22 +592,16 @@ Constant *ConstantArray::get(const ArrayType *Ty, 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, 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])); @@ -538,6 +614,25 @@ Constant* ConstantArray::get(LLVMContext &Context, 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, @@ -545,91 +640,62 @@ ConstantStruct::ConstantStruct(const StructType *T, : Constant(T, ConstantStructVal, OperandTraits::op_end(this) - V.size(), V.size()) { - assert(V.size() == T->getNumElements() && + assert((T->isOpaque() || 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()) && + assert((T->isOpaque() || C->getType() == T->getElementType(I-V.begin())) && "Initializer for struct element doesn't match struct element type!"); *OL = C; } } // 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(const 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()) - return pImpl->StructConstants.getOrCreate(T, V); - - return ConstantAggregateZero::get(T); -} - -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); -} + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V); -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); + assert((ST->isOpaque() || ST->getNumElements() == V.size()) && + "Incorrect # elements specified to ConstantStruct::get"); + return ConstantAggregateZero::get(ST); } -ConstantUnion::ConstantUnion(const UnionType *T, Constant* V) - : Constant(T, ConstantUnionVal, - OperandTraits::op_end(this) - 1, 1) { - Use *OL = OperandList; - assert(T->getElementTypeIndex(V->getType()) >= 0 && - "Initializer for union element isn't a member of union type!"); - *OL = V; -} - -// ConstantUnion accessors. -Constant* ConstantUnion::get(const UnionType* T, Constant* V) { - LLVMContextImpl* pImpl = T->getContext().pImpl; - - // Create a ConstantAggregateZero value if all elements are zeros... - if (!V->isNullValue()) - return pImpl->UnionConstants.getOrCreate(T, V); - - return ConstantAggregateZero::get(T); +Constant* ConstantStruct::get(const 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) : 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 (std::vector::const_iterator I = V.begin(), E = V.end(); + I != E; ++I, ++OL) { + Constant *C = *I; + assert(C->getType() == T->getElementType() && "Initializer for vector element doesn't match vector element type!"); *OL = C; } } // 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"); + const 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(); @@ -651,63 +717,6 @@ Constant* ConstantVector::get(const VectorType* T, 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::getNSWNeg(Constant* C) { - assert(C->getType()->isIntOrIntVectorTy() && - "Cannot NEG a nonintegral value!"); - return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); -} - -Constant* ConstantExpr::getNUWNeg(Constant* C) { - assert(C->getType()->isIntOrIntVectorTy() && - "Cannot NEG a nonintegral value!"); - return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); -} - -Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -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 @@ -723,7 +732,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; @@ -749,7 +758,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; @@ -830,17 +839,15 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { } /// 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, const 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); @@ -857,7 +864,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: @@ -868,8 +875,8 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { 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); + ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], Ops.size()-1) : + ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1); case Instruction::ICmp: case Instruction::FCmp: return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); @@ -945,8 +952,7 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { // Factory Function Implementation ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { - assert((Ty->isStructTy() || Ty->isUnionTy() - || Ty->isArrayTy() || Ty->isVectorTy()) && + assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) && "Cannot create an aggregate zero of non-aggregate type!"); LLVMContextImpl *pImpl = Ty->getContext().pImpl; @@ -1003,17 +1009,32 @@ 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()); +} + + +/// 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); } @@ -1031,13 +1052,6 @@ void ConstantStruct::destroyConstant() { destroyConstantImpl(); } -// destroyConstant - Remove the constant from the constant table... -// -void ConstantUnion::destroyConstant() { - getType()->getContext().pImpl->UnionConstants.remove(this); - destroyConstantImpl(); -} - // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { @@ -1063,7 +1077,7 @@ bool ConstantVector::isAllOnesValue() const { /// 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. @@ -1224,20 +1238,20 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const 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) { 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) { 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) { @@ -1245,8 +1259,8 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) { assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"); if (Ty->isIntegerTy()) - return getCast(Instruction::PtrToInt, S, Ty); - return getCast(Instruction::BitCast, S, Ty); + return getPtrToInt(S, Ty); + return getBitCast(S, Ty); } Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, @@ -1270,7 +1284,7 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) { 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); } @@ -1450,12 +1464,6 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate, Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags) { - // API compatibility: Adjust integer opcodes to floating-point opcodes. - if (C1->getType()->isFPOrFPVectorTy()) { - 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: @@ -1517,36 +1525,36 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, return getTy(C1->getType(), Opcode, C1, C2, Flags); } -Constant* ConstantExpr::getSizeOf(const Type* Ty) { +Constant *ConstantExpr::getSizeOf(const 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())); + return getPtrToInt(GEP, + Type::getInt64Ty(Ty->getContext())); } -Constant* ConstantExpr::getAlignOf(const Type* Ty) { +Constant *ConstantExpr::getAlignOf(const 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); + const Type *AligningTy = + StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); 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::getInt64Ty(Ty->getContext())); + return getPtrToInt(GEP, + Type::getInt64Ty(Ty->getContext())); } -Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) { +Constant *ConstantExpr::getOffsetOf(const 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(const 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[] = { @@ -1555,8 +1563,8 @@ Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) { }; Constant *GEP = getGetElementPtr( Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2); - return getCast(Instruction::PtrToInt, GEP, - Type::getInt64Ty(Ty->getContext())); + return getPtrToInt(GEP, + Type::getInt64Ty(Ty->getContext())); } Constant *ConstantExpr::getCompare(unsigned short pred, @@ -1582,44 +1590,17 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } +template 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(C, /*inBounds=*/false, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... - - 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.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; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, - Constant *C, - Value *const *Idxs, - unsigned NumIdx) { + IndexTy const *Idxs, + unsigned NumIdx, bool InBounds) { assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx) == cast(ReqTy)->getElementType() && "GEP indices invalid!"); - if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/true, - (Constant**)Idxs, NumIdx)) - return FC; // Fold a few common cases... + if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx)) + return FC; // Fold a few common cases. assert(C->getType()->isPointerTy() && "Non-pointer type for constant GetElementPtr expression"); @@ -1630,42 +1611,31 @@ Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, for (unsigned i = 0; i != NumIdx; ++i) ArgVec.push_back(cast(Idxs[i])); const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - GEPOperator::IsInBounds); + InBounds ? GEPOperator::IsInBounds : 0); LLVMContextImpl *pImpl = ReqTy->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) { +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 getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); + return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs, - unsigned NumIdx) { - return getGetElementPtr(C, (Value* const *)Idxs, NumIdx); +Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, + unsigned NumIdx, bool InBounds) { + return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); } -Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, - Constant* const *Idxs, - unsigned NumIdx) { - return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx); +Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant *const *Idxs, + unsigned NumIdx, bool InBounds) { + return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); } Constant * @@ -1839,101 +1809,111 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); } -Constant* ConstantExpr::getNeg(Constant* C) { - // API compatibility: Adjust integer opcodes to floating-point opcodes. - if (C->getType()->isFPOrFPVectorTy()) - return getFNeg(C); +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) { +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) { +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... @@ -1980,11 +1960,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; @@ -2069,7 +2048,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. @@ -2091,14 +2070,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); @@ -2127,56 +2105,6 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, destroyConstant(); } -void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { - assert(isa(To) && "Cannot make Constant refer to non-constant!"); - Constant *ToC = cast(To); - - assert(U == OperandList && "Union constants can only have one use!"); - assert(getNumOperands() == 1 && "Union constants can only have one use!"); - assert(getOperand(0) == From && "ReplaceAllUsesWith broken!"); - - std::pair Lookup; - Lookup.first.first = getType(); - Lookup.second = this; - Lookup.first.second = ToC; - - LLVMContext &Context = getType()->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; - - Constant *Replacement = 0; - if (ToC->isNullValue()) { - Replacement = ConstantAggregateZero::get(getType()); - } else { - // Check to see if we have this union type already. - bool Exists; - LLVMContextImpl::UnionConstantsTy::MapTy::iterator I = - pImpl->UnionConstants.InsertOrGetItem(Lookup, Exists); - - if (Exists) { - Replacement = I->second; - } else { - // Okay, the new shape doesn't exist in the system yet. Instead of - // creating a new constant union, inserting it, replaceallusesof'ing the - // old with the new, then deleting the old... just update the current one - // in place! - pImpl->UnionConstants.MoveConstantToNewSlot(this, I); - - // Update to the new value. - setOperand(0, ToC); - return; - } - } - - assert(Replacement != this && "I didn't contain From!"); - - // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); - - // Delete the old constant! - destroyConstant(); -} - void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); @@ -2189,7 +2117,7 @@ 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. @@ -2217,12 +2145,13 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Indices.push_back(Val); } Replacement = ConstantExpr::getGetElementPtr(Pointer, - &Indices[0], Indices.size()); + &Indices[0], Indices.size(), + cast(this)->isInBounds()); } else if (getOpcode() == Instruction::ExtractValue) { Constant *Agg = getOperand(0); if (Agg == From) Agg = To; - const SmallVector &Indices = getIndices(); + ArrayRef Indices = getIndices(); Replacement = ConstantExpr::getExtractValue(Agg, &Indices[0], Indices.size()); } else if (getOpcode() == Instruction::InsertValue) { @@ -2231,7 +2160,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (Agg == From) Agg = To; if (Val == From) Val = To; - const SmallVector &Indices = getIndices(); + ArrayRef Indices = getIndices(); Replacement = ConstantExpr::getInsertValue(Agg, Val, &Indices[0], Indices.size()); } else if (isCast()) {