X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FIR%2FConstants.cpp;h=798ea2470fadc4f16e554b3279834abdd3b58861;hp=812692f3fae9680a22e2df64b61be257c1d537a1;hb=81e467d35217e7c331048c474f13bc91c942a911;hpb=935e35d2b9f889566207b76a7026b63a1619742c diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index 812692f3fae..798ea2470fa 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" @@ -28,7 +29,6 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -47,10 +47,22 @@ bool Constant::isNegativeZeroValue() const { if (const ConstantFP *CFP = dyn_cast(this)) return CFP->isZero() && CFP->isNegative(); + // Equivalent for a vector of -0.0's. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (ConstantFP *SplatCFP = dyn_cast_or_null(CV->getSplatValue())) + if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative()) + return true; + + // We've already handled true FP case; any other FP vectors can't represent -0.0. + if (getType()->isFPOrFPVectorTy()) + return false; + // Otherwise, just use +0.0. return isNullValue(); } +// Return true iff this constant is positive zero (floating point), negative +// zero (floating point), or a null value. bool Constant::isZeroValue() const { // Floating point values have an explicit -0.0 value. if (const ConstantFP *CFP = dyn_cast(this)) @@ -95,6 +107,73 @@ bool Constant::isAllOnesValue() const { return false; } +bool Constant::isOneValue() const { + // Check for 1 integers + if (const ConstantInt *CI = dyn_cast(this)) + return CI->isOne(); + + // Check for FP which are bitcasted from 1 integers + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->getValueAPF().bitcastToAPInt() == 1; + + // Check for constant vectors which are splats of 1 values. + if (const ConstantVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isOneValue(); + + // Check for constant vectors which are splats of 1 values. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isOneValue(); + + return false; +} + +bool Constant::isMinSignedValue() const { + // Check for INT_MIN integers + if (const ConstantInt *CI = dyn_cast(this)) + return CI->isMinValue(/*isSigned=*/true); + + // Check for FP which are bitcasted from INT_MIN integers + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->getValueAPF().bitcastToAPInt().isMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isMinSignedValue(); + + return false; +} + +bool Constant::isNotMinSignedValue() const { + // Check for INT_MIN integers + if (const ConstantInt *CI = dyn_cast(this)) + return !CI->isMinValue(/*isSigned=*/true); + + // Check for FP which are bitcasted from INT_MIN integers + if (const ConstantFP *CFP = dyn_cast(this)) + return !CFP->getValueAPF().bitcastToAPInt().isMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isNotMinSignedValue(); + + // Check for constant vectors which are splats of INT_MIN values. + if (const ConstantDataVector *CV = dyn_cast(this)) + if (Constant *Splat = CV->getSplatValue()) + return Splat->isNotMinSignedValue(); + + // It *may* contain INT_MIN, we can't tell. + return false; +} + // Constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { @@ -117,7 +196,8 @@ Constant *Constant::getNullValue(Type *Ty) { APFloat::getZero(APFloat::IEEEquad)); case Type::PPC_FP128TyID: return ConstantFP::get(Ty->getContext(), - APFloat(APInt::getNullValue(128))); + APFloat(APFloat::PPCDoubleDouble, + APInt::getNullValue(128))); case Type::PointerTyID: return ConstantPointerNull::get(cast(Ty)); case Type::StructTyID: @@ -169,34 +249,46 @@ Constant *Constant::getAllOnesValue(Type *Ty) { /// 'this' is a constant expr. Constant *Constant::getAggregateElement(unsigned Elt) const { if (const ConstantStruct *CS = dyn_cast(this)) - return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : 0; + return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : nullptr; if (const ConstantArray *CA = dyn_cast(this)) - return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : 0; + return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : nullptr; if (const ConstantVector *CV = dyn_cast(this)) - return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : 0; + return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr; - if (const ConstantAggregateZero *CAZ =dyn_cast(this)) - return CAZ->getElementValue(Elt); + if (const ConstantAggregateZero *CAZ = dyn_cast(this)) + return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr; if (const UndefValue *UV = dyn_cast(this)) - return UV->getElementValue(Elt); + return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr; if (const ConstantDataSequential *CDS =dyn_cast(this)) - return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0; - return 0; + return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) + : nullptr; + return nullptr; } Constant *Constant::getAggregateElement(Constant *Elt) const { assert(isa(Elt->getType()) && "Index must be an integer"); if (ConstantInt *CI = dyn_cast(Elt)) return getAggregateElement(CI->getZExtValue()); - return 0; + return nullptr; } +void Constant::destroyConstant() { + /// First call destroyConstantImpl on the subclass. This gives the subclass + /// a chance to remove the constant from any maps/pools it's contained in. + switch (getValueID()) { + default: + llvm_unreachable("Not a constant!"); +#define HANDLE_CONSTANT(Name) \ + case Value::Name##Val: \ + cast(this)->destroyConstantImpl(); \ + break; +#include "llvm/IR/Value.def" + } -void Constant::destroyConstantImpl() { // When a Constant is destroyed, there may be lingering // references to the constant by other constants in the constant pool. These // constants are implicitly dependent on the module that is being deleted, @@ -205,37 +297,40 @@ void Constant::destroyConstantImpl() { // Constants) that they are, in fact, invalid now and should be deleted. // while (!use_empty()) { - Value *V = use_back(); -#ifndef NDEBUG // Only in -g mode... + Value *V = user_back(); +#ifndef NDEBUG // Only in -g mode... if (!isa(V)) { dbgs() << "While deleting: " << *this - << "\n\nUse still stuck around after Def is destroyed: " - << *V << "\n\n"; + << "\n\nUse still stuck around after Def is destroyed: " << *V + << "\n\n"; } #endif assert(isa(V) && "References remain to Constant being destroyed"); cast(V)->destroyConstant(); // The constant should remove itself from our use list... - assert((use_empty() || use_back() != V) && "Constant not removed!"); + assert((use_empty() || user_back() != V) && "Constant not removed!"); } // Value has no outstanding references it is safe to delete it now... delete this; } -/// canTrap - Return true if evaluation of this constant could trap. This is -/// true for things like constant expressions that could divide by zero. -bool Constant::canTrap() const { - assert(getType()->isFirstClassType() && "Cannot evaluate aggregate vals!"); +static bool canTrapImpl(const Constant *C, + SmallPtrSetImpl &NonTrappingOps) { + assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!"); // The only thing that could possibly trap are constant exprs. - const ConstantExpr *CE = dyn_cast(this); - if (!CE) return false; + const ConstantExpr *CE = dyn_cast(C); + if (!CE) + return false; // ConstantExpr traps if any operands can trap. - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (CE->getOperand(i)->canTrap()) - return true; + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + if (ConstantExpr *Op = dyn_cast(CE->getOperand(i))) { + if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps)) + return true; + } + } // Otherwise, only specific operations can trap. switch (CE->getOpcode()) { @@ -254,39 +349,59 @@ bool Constant::canTrap() const { } } -/// isThreadDependent - Return true if the value can vary between threads. -bool Constant::isThreadDependent() const { - SmallPtrSet Visited; - SmallVector WorkList; - WorkList.push_back(this); - Visited.insert(this); +/// canTrap - Return true if evaluation of this constant could trap. This is +/// true for things like constant expressions that could divide by zero. +bool Constant::canTrap() const { + SmallPtrSet NonTrappingOps; + return canTrapImpl(this, NonTrappingOps); +} - while (!WorkList.empty()) { - const Constant *C = WorkList.pop_back_val(); +/// Check if C contains a GlobalValue for which Predicate is true. +static bool +ConstHasGlobalValuePredicate(const Constant *C, + bool (*Predicate)(const GlobalValue *)) { + SmallPtrSet Visited; + SmallVector WorkList; + WorkList.push_back(C); + Visited.insert(C); - if (const GlobalVariable *GV = dyn_cast(C)) { - if (GV->isThreadLocal()) + while (!WorkList.empty()) { + const Constant *WorkItem = WorkList.pop_back_val(); + if (const auto *GV = dyn_cast(WorkItem)) + if (Predicate(GV)) return true; - } - - for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) { - const Constant *D = dyn_cast(C->getOperand(I)); - if (!D) + for (const Value *Op : WorkItem->operands()) { + const Constant *ConstOp = dyn_cast(Op); + if (!ConstOp) continue; - if (Visited.insert(D)) - WorkList.push_back(D); + if (Visited.insert(ConstOp).second) + WorkList.push_back(ConstOp); } } - return false; } -/// isConstantUsed - Return true if the constant has users other than constant -/// exprs and other dangling things. +/// Return true if the value can vary between threads. +bool Constant::isThreadDependent() const { + auto DLLImportPredicate = [](const GlobalValue *GV) { + return GV->isThreadLocal(); + }; + return ConstHasGlobalValuePredicate(this, DLLImportPredicate); +} + +bool Constant::isDLLImportDependent() const { + auto DLLImportPredicate = [](const GlobalValue *GV) { + return GV->hasDLLImportStorageClass(); + }; + return ConstHasGlobalValuePredicate(this, DLLImportPredicate); +} + +/// 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)) + for (const User *U : users()) { + const Constant *UC = dyn_cast(U); + if (!UC || isa(UC)) return true; if (UC->isConstantUsed()) @@ -354,7 +469,7 @@ 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()); + const Constant *User = dyn_cast(C->user_back()); if (!User) return false; // Non-constant usage; if (!removeDeadUsersOfConstant(User)) return false; // Constant wasn't dead @@ -370,11 +485,11 @@ static bool removeDeadUsersOfConstant(const Constant *C) { /// 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; + Value::const_user_iterator I = user_begin(), E = user_end(); + Value::const_user_iterator LastNonDeadUser = E; while (I != E) { const Constant *User = dyn_cast(*I); - if (User == 0) { + if (!User) { LastNonDeadUser = I; ++I; continue; @@ -390,7 +505,7 @@ void Constant::removeDeadConstantUsers() const { // If the constant was dead, then the iterator is invalidated. if (LastNonDeadUser == E) { - I = use_begin(); + I = user_begin(); if (I == E) break; } else { I = LastNonDeadUser; @@ -408,7 +523,7 @@ void Constant::removeDeadConstantUsers() const { void ConstantInt::anchor() { } ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V) - : Constant(Ty, ConstantIntVal, 0, 0), Val(V) { + : Constant(Ty, ConstantIntVal, nullptr, 0), Val(V) { assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } @@ -450,19 +565,17 @@ Constant *ConstantInt::getFalse(Type *Ty) { ConstantInt::getFalse(Ty->getContext())); } - -// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap -// as the key, is a DenseMapAPIntKeyInfo::KeyTy which has provided the -// 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. +// Get a ConstantInt from an APInt. ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { - // Get the corresponding integer type for the bit width of the value. - 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]; - if (!Slot) Slot = new ConstantInt(ITy, V); + LLVMContextImpl *pImpl = Context.pImpl; + ConstantInt *&Slot = pImpl->IntConstants[V]; + if (!Slot) { + // Get the corresponding integer type for the bit width of the value. + IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); + Slot = new ConstantInt(ITy, V); + } + assert(Slot->getType() == IntegerType::get(Context, V.getBitWidth())); return Slot; } @@ -506,6 +619,11 @@ ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); } +/// Remove the constant from the constant table. +void ConstantInt::destroyConstantImpl() { + llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!"); +} + //===----------------------------------------------------------------------===// // ConstantFP //===----------------------------------------------------------------------===// @@ -561,23 +679,32 @@ Constant *ConstantFP::get(Type *Ty, StringRef Str) { return C; } +Constant *ConstantFP::getNaN(Type *Ty, bool Negative, unsigned Type) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType()); + APFloat NaN = APFloat::getNaN(Semantics, Negative, Type); + Constant *C = get(Ty->getContext(), NaN); -ConstantFP *ConstantFP::getNegativeZero(Type *Ty) { - LLVMContext &Context = Ty->getContext(); - APFloat apf = cast(Constant::getNullValue(Ty))->getValueAPF(); - apf.changeSign(); - return get(Context, apf); + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + + return C; +} + +Constant *ConstantFP::getNegativeZero(Type *Ty) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType()); + APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true); + Constant *C = get(Ty->getContext(), NegZero); + + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + + return C; } Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { - Type *ScalarTy = Ty->getScalarType(); - if (ScalarTy->isFloatingPointTy()) { - Constant *C = getNegativeZero(ScalarTy); - if (VectorType *VTy = dyn_cast(Ty)) - return ConstantVector::getSplat(VTy->getNumElements(), C); - return C; - } + if (Ty->isFPOrFPVectorTy()) + return getNegativeZero(Ty); return Constant::getNullValue(Ty); } @@ -585,11 +712,9 @@ Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { // ConstantFP accessors. ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { - DenseMapAPFloatKeyInfo::KeyTy Key(V); - LLVMContextImpl* pImpl = Context.pImpl; - ConstantFP *&Slot = pImpl->FPConstants[Key]; + ConstantFP *&Slot = pImpl->FPConstants[V]; if (!Slot) { Type *Ty; @@ -614,14 +739,18 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { return Slot; } -ConstantFP *ConstantFP::getInfinity(Type *Ty, bool Negative) { - const fltSemantics &Semantics = *TypeToFloatSemantics(Ty); - return ConstantFP::get(Ty->getContext(), - APFloat::getInf(Semantics, Negative)); +Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType()); + Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative)); + + if (VectorType *VTy = dyn_cast(Ty)) + return ConstantVector::getSplat(VTy->getNumElements(), C); + + return C; } ConstantFP::ConstantFP(Type *Ty, const APFloat& V) - : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { + : Constant(Ty, ConstantFPVal, nullptr, 0), Val(V) { assert(&V.getSemantics() == TypeToFloatSemantics(Ty) && "FP type Mismatch"); } @@ -630,6 +759,11 @@ bool ConstantFP::isExactlyValue(const APFloat &V) const { return Val.bitwiseIsEqual(V); } +/// Remove the constant from the constant table. +void ConstantFP::destroyConstantImpl() { + llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!"); +} + //===----------------------------------------------------------------------===// // ConstantAggregateZero Implementation //===----------------------------------------------------------------------===// @@ -662,6 +796,14 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const { return getStructElement(Idx); } +unsigned ConstantAggregateZero::getNumElements() const { + Type *Ty = getType(); + if (auto *AT = dyn_cast(Ty)) + return AT->getNumElements(); + if (auto *VT = dyn_cast(Ty)) + return VT->getNumElements(); + return Ty->getStructNumElements(); +} //===----------------------------------------------------------------------===// // UndefValue Implementation @@ -695,7 +837,14 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const { return getStructElement(Idx); } - +unsigned UndefValue::getNumElements() const { + Type *Ty = getType(); + if (auto *AT = dyn_cast(Ty)) + return AT->getNumElements(); + if (auto *VT = dyn_cast(Ty)) + return VT->getNumElements(); + return Ty->getStructNumElements(); +} //===----------------------------------------------------------------------===// // ConstantXXX Classes @@ -722,6 +871,11 @@ ConstantArray::ConstantArray(ArrayType *T, ArrayRef V) } Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { + if (Constant *C = getImpl(Ty, V)) + return C; + return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V); +} +Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef V) { // Empty arrays are canonicalized to ConstantAggregateZero. if (V.empty()) return ConstantAggregateZero::get(Ty); @@ -730,7 +884,6 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); } - LLVMContextImpl *pImpl = Ty->getContext().pImpl; // If this is an all-zero array, return a ConstantAggregateZero object. If // all undef, return an UndefValue, if "all simple", then return a @@ -790,29 +943,31 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { if (ConstantFP *CFP = dyn_cast(C)) { if (CFP->getType()->isFloatTy()) { - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0, e = V.size(); i != e; ++i) if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back(CFP->getValueAPF().convertToFloat()); + Elts.push_back( + CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); else break; if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); + return ConstantDataArray::getFP(C->getContext(), Elts); } else if (CFP->getType()->isDoubleTy()) { - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0, e = V.size(); i != e; ++i) if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back(CFP->getValueAPF().convertToDouble()); + Elts.push_back( + CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); else break; if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); + return ConstantDataArray::getFP(C->getContext(), Elts); } } } // Otherwise, we really do want to create a ConstantArray. - return pImpl->ArrayConstants.getOrCreate(Ty, V); + return nullptr; } /// getTypeForElements - Return an anonymous struct type to use for a constant @@ -900,9 +1055,14 @@ ConstantVector::ConstantVector(VectorType *T, ArrayRef V) // ConstantVector accessors. Constant *ConstantVector::get(ArrayRef V) { + if (Constant *C = getImpl(V)) + return C; + VectorType *Ty = VectorType::get(V.front()->getType(), V.size()); + return Ty->getContext().pImpl->VectorConstants.getOrCreate(Ty, V); +} +Constant *ConstantVector::getImpl(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. @@ -971,30 +1131,32 @@ Constant *ConstantVector::get(ArrayRef V) { if (ConstantFP *CFP = dyn_cast(C)) { if (CFP->getType()->isFloatTy()) { - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0, e = V.size(); i != e; ++i) if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back(CFP->getValueAPF().convertToFloat()); + Elts.push_back( + CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); else break; if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); + return ConstantDataVector::getFP(C->getContext(), Elts); } else if (CFP->getType()->isDoubleTy()) { - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0, e = V.size(); i != e; ++i) if (ConstantFP *CFP = dyn_cast(V[i])) - Elts.push_back(CFP->getValueAPF().convertToDouble()); + Elts.push_back( + CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); else break; if (Elts.size() == V.size()) - return ConstantDataVector::get(C->getContext(), Elts); + return ConstantDataVector::getFP(C->getContext(), Elts); } } } // Otherwise, the element type isn't compatible with ConstantDataVector, or // the operand list constants a ConstantExpr or something else strange. - return pImpl->VectorConstants.getOrCreate(T, V); + return nullptr; } Constant *ConstantVector::getSplat(unsigned NumElts, Constant *V) { @@ -1024,7 +1186,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 = llvm::next(this->op_begin()); + User::const_op_iterator OI = std::next(this->op_begin()); // Skip the first index, as it has no static limit. ++GEPI; @@ -1082,16 +1244,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 array must /// have the same number of operands as our current one. -Constant *ConstantExpr:: -getWithOperands(ArrayRef Ops, Type *Ty) const { +Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, + bool OnlyIfReduced, Type *SrcTy) 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. + // If no operands changed return self. + if (Ty == getType() && std::equal(Ops.begin(), Ops.end(), op_begin())) return const_cast(this); + Type *OnlyIfReducedTy = OnlyIfReduced ? Ty : nullptr; switch (getOpcode()) { case Instruction::Trunc: case Instruction::ZExt: @@ -1105,28 +1266,38 @@ getWithOperands(ArrayRef Ops, Type *Ty) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: - return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); + case Instruction::AddrSpaceCast: + return ConstantExpr::getCast(getOpcode(), Ops[0], Ty, OnlyIfReduced); case Instruction::Select: - return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); + return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2], OnlyIfReducedTy); case Instruction::InsertElement: - return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); + return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2], + OnlyIfReducedTy); case Instruction::ExtractElement: - return ConstantExpr::getExtractElement(Ops[0], Ops[1]); + return ConstantExpr::getExtractElement(Ops[0], Ops[1], OnlyIfReducedTy); case Instruction::InsertValue: - return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices()); + return ConstantExpr::getInsertValue(Ops[0], Ops[1], getIndices(), + OnlyIfReducedTy); case Instruction::ExtractValue: - return ConstantExpr::getExtractValue(Ops[0], getIndices()); + return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy); case Instruction::ShuffleVector: - return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); - case Instruction::GetElementPtr: - return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1), - cast(this)->isInBounds()); + return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2], + OnlyIfReducedTy); + case Instruction::GetElementPtr: { + auto *GEPO = cast(this); + assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType())); + return ConstantExpr::getGetElementPtr( + SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1), + GEPO->isInBounds(), OnlyIfReducedTy); + } case Instruction::ICmp: case Instruction::FCmp: - return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); + return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1], + OnlyIfReducedTy); default: assert(getNumOperands() == 2 && "Must be binary operator?"); - return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData); + return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData, + OnlyIfReducedTy); } } @@ -1211,7 +1382,7 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { "Cannot create an aggregate zero of non-aggregate type!"); ConstantAggregateZero *&Entry = Ty->getContext().pImpl->CAZConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new ConstantAggregateZero(Ty); return Entry; @@ -1219,16 +1390,14 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { /// destroyConstant - Remove the constant from the constant table. /// -void ConstantAggregateZero::destroyConstant() { +void ConstantAggregateZero::destroyConstantImpl() { getContext().pImpl->CAZConstants.erase(getType()); - destroyConstantImpl(); } /// destroyConstant - Remove the constant from the constant table... /// -void ConstantArray::destroyConstant() { +void ConstantArray::destroyConstantImpl() { getType()->getContext().pImpl->ArrayConstants.remove(this); - destroyConstantImpl(); } @@ -1237,16 +1406,14 @@ void ConstantArray::destroyConstant() { // destroyConstant - Remove the constant from the constant table... // -void ConstantStruct::destroyConstant() { +void ConstantStruct::destroyConstantImpl() { getType()->getContext().pImpl->StructConstants.remove(this); - destroyConstantImpl(); } // destroyConstant - Remove the constant from the constant table... // -void ConstantVector::destroyConstant() { +void ConstantVector::destroyConstantImpl() { getType()->getContext().pImpl->VectorConstants.remove(this); - destroyConstantImpl(); } /// getSplatValue - If this is a splat vector constant, meaning that all of @@ -1259,7 +1426,7 @@ Constant *Constant::getSplatValue() const { return CV->getSplatValue(); if (const ConstantVector *CV = dyn_cast(this)) return CV->getSplatValue(); - return 0; + return nullptr; } /// getSplatValue - If this is a splat constant, where all of the @@ -1270,7 +1437,7 @@ Constant *ConstantVector::getSplatValue() const { // 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; + return nullptr; return Elt; } @@ -1285,13 +1452,12 @@ const APInt &Constant::getUniqueInteger() const { return cast(C)->getValue(); } - //---- ConstantPointerNull::get() implementation. // ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { ConstantPointerNull *&Entry = Ty->getContext().pImpl->CPNConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new ConstantPointerNull(Ty); return Entry; @@ -1299,10 +1465,8 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) { // destroyConstant - Remove the constant from the constant table... // -void ConstantPointerNull::destroyConstant() { +void ConstantPointerNull::destroyConstantImpl() { getContext().pImpl->CPNConstants.erase(getType()); - // Free the constant and any dangling references to it. - destroyConstantImpl(); } @@ -1311,7 +1475,7 @@ void ConstantPointerNull::destroyConstant() { UndefValue *UndefValue::get(Type *Ty) { UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty]; - if (Entry == 0) + if (!Entry) Entry = new UndefValue(Ty); return Entry; @@ -1319,24 +1483,23 @@ UndefValue *UndefValue::get(Type *Ty) { // destroyConstant - Remove the constant from the constant table. // -void UndefValue::destroyConstant() { +void UndefValue::destroyConstantImpl() { // Free the constant and any dangling references to it. getContext().pImpl->UVConstants.erase(getType()); - destroyConstantImpl(); } //---- BlockAddress::get() implementation. // BlockAddress *BlockAddress::get(BasicBlock *BB) { - assert(BB->getParent() != 0 && "Block must have a parent"); + assert(BB->getParent() && "Block must have a parent"); return get(BB->getParent(), BB); } BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { BlockAddress *&BA = F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)]; - if (BA == 0) + if (!BA) BA = new BlockAddress(F, BB); assert(BA->getFunction() == F && "Basic block moved between functions"); @@ -1351,24 +1514,34 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) BB->AdjustBlockAddressRefCount(1); } +BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { + if (!BB->hasAddressTaken()) + return nullptr; + + const Function *F = BB->getParent(); + assert(F && "Block must have a parent"); + BlockAddress *BA = + F->getContext().pImpl->BlockAddresses.lookup(std::make_pair(F, BB)); + assert(BA && "Refcount and block address map disagree!"); + return BA; +} // destroyConstant - Remove the constant from the constant table. // -void BlockAddress::destroyConstant() { +void BlockAddress::destroyConstantImpl() { getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); getBasicBlock()->AdjustBlockAddressRefCount(-1); - destroyConstantImpl(); } -void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { +Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To, Use *U) { // This could be replacing either the Basic Block or the Function. In either // case, we have to remove the map entry. Function *NewF = getFunction(); BasicBlock *NewBB = getBasicBlock(); if (U == &Op<0>()) - NewF = cast(To); + NewF = cast(To->stripPointerCasts()); else NewBB = cast(To); @@ -1376,27 +1549,23 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { // and return early. BlockAddress *&NewBA = getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)]; - if (NewBA == 0) { - getBasicBlock()->AdjustBlockAddressRefCount(-1); - - // Remove the old entry, this can't cause the map to rehash (just a - // tombstone will get added). - getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(), - getBasicBlock())); - NewBA = this; - setOperand(0, NewF); - setOperand(1, NewBB); - getBasicBlock()->AdjustBlockAddressRefCount(1); - return; - } + if (NewBA) + return NewBA; - // Otherwise, I do need to replace this with an existing value. - assert(NewBA != this && "I didn't contain From!"); + getBasicBlock()->AdjustBlockAddressRefCount(-1); - // Everyone using this now uses the replacement. - replaceAllUsesWith(NewBA); + // 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; + setOperand(0, NewF); + setOperand(1, NewBB); + getBasicBlock()->AdjustBlockAddressRefCount(1); - destroyConstant(); + // If we just want to keep the existing value, then return null. + // Callers know that this means we shouldn't delete this value. + return nullptr; } //---- ConstantExpr::get() implementations. @@ -1404,23 +1573,26 @@ 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, Type *Ty) { +static Constant *getFoldedCast(Instruction::CastOps opc, Constant *C, Type *Ty, + bool OnlyIfReduced = false) { assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); // Fold a few common cases if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty)) return FC; + if (OnlyIfReduced) + return nullptr; + LLVMContextImpl *pImpl = Ty->getContext().pImpl; - // Look up the constant in the table first to ensure uniqueness - std::vector argVec(1, C); - ExprMapKeyType Key(opc, argVec); + // Look up the constant in the table first to ensure uniqueness. + ConstantExprKeyType Key(opc, C); return pImpl->ExprConstants.getOrCreate(Ty, Key); } -Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) { +Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty, + bool OnlyIfReduced) { Instruction::CastOps opc = Instruction::CastOps(oc); assert(Instruction::isCast(opc) && "opcode out of range"); assert(C && Ty && "Null arguments to getCast"); @@ -1429,18 +1601,32 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty) { switch (opc) { default: llvm_unreachable("Invalid cast opcode"); - 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); + case Instruction::Trunc: + return getTrunc(C, Ty, OnlyIfReduced); + case Instruction::ZExt: + return getZExt(C, Ty, OnlyIfReduced); + case Instruction::SExt: + return getSExt(C, Ty, OnlyIfReduced); + case Instruction::FPTrunc: + return getFPTrunc(C, Ty, OnlyIfReduced); + case Instruction::FPExt: + return getFPExtend(C, Ty, OnlyIfReduced); + case Instruction::UIToFP: + return getUIToFP(C, Ty, OnlyIfReduced); + case Instruction::SIToFP: + return getSIToFP(C, Ty, OnlyIfReduced); + case Instruction::FPToUI: + return getFPToUI(C, Ty, OnlyIfReduced); + case Instruction::FPToSI: + return getFPToSI(C, Ty, OnlyIfReduced); + case Instruction::PtrToInt: + return getPtrToInt(C, Ty, OnlyIfReduced); + case Instruction::IntToPtr: + return getIntToPtr(C, Ty, OnlyIfReduced); + case Instruction::BitCast: + return getBitCast(C, Ty, OnlyIfReduced); + case Instruction::AddrSpaceCast: + return getAddrSpaceCast(C, Ty, OnlyIfReduced); } } @@ -1463,15 +1649,32 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) { } Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) { - assert(S->getType()->isPointerTy() && "Invalid cast"); - assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"); + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && + "Invalid cast"); - if (Ty->isIntegerTy()) + if (Ty->isIntOrIntVectorTy()) return getPtrToInt(S, Ty); + + unsigned SrcAS = S->getType()->getPointerAddressSpace(); + if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + + return getBitCast(S, Ty); +} + +Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S, + Type *Ty) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return getAddrSpaceCast(S, Ty); + return getBitCast(S, Ty); } -Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, +Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid cast"); @@ -1496,7 +1699,7 @@ Constant *ConstantExpr::getFPCast(Constant *C, Type *Ty) { return getCast(opcode, C, Ty); } -Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty) { +Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1507,10 +1710,10 @@ Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty) { assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "SrcTy must be larger than DestTy for Trunc!"); - return getFoldedCast(Instruction::Trunc, C, Ty); + return getFoldedCast(Instruction::Trunc, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getSExt(Constant *C, Type *Ty) { +Constant *ConstantExpr::getSExt(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1521,10 +1724,10 @@ Constant *ConstantExpr::getSExt(Constant *C, Type *Ty) { assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for SExt!"); - return getFoldedCast(Instruction::SExt, C, Ty); + return getFoldedCast(Instruction::SExt, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getZExt(Constant *C, Type *Ty) { +Constant *ConstantExpr::getZExt(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1535,10 +1738,10 @@ Constant *ConstantExpr::getZExt(Constant *C, Type *Ty) { assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for ZExt!"); - return getFoldedCast(Instruction::ZExt, C, Ty); + return getFoldedCast(Instruction::ZExt, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty) { +Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1547,10 +1750,10 @@ Constant *ConstantExpr::getFPTrunc(Constant *C, Type *Ty) { assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&& "This is an illegal floating point truncation!"); - return getFoldedCast(Instruction::FPTrunc, C, Ty); + return getFoldedCast(Instruction::FPTrunc, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty) { +Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1559,10 +1762,10 @@ Constant *ConstantExpr::getFPExtend(Constant *C, Type *Ty) { assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "This is an illegal floating point extension!"); - return getFoldedCast(Instruction::FPExt, C, Ty); + return getFoldedCast(Instruction::FPExt, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty) { +Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1570,10 +1773,10 @@ Constant *ConstantExpr::getUIToFP(Constant *C, Type *Ty) { assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && "This is an illegal uint to floating point cast!"); - return getFoldedCast(Instruction::UIToFP, C, Ty); + return getFoldedCast(Instruction::UIToFP, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty) { +Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1581,10 +1784,10 @@ Constant *ConstantExpr::getSIToFP(Constant *C, Type *Ty) { assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() && "This is an illegal sint to floating point cast!"); - return getFoldedCast(Instruction::SIToFP, C, Ty); + return getFoldedCast(Instruction::SIToFP, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty) { +Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1592,10 +1795,10 @@ Constant *ConstantExpr::getFPToUI(Constant *C, Type *Ty) { assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && "This is an illegal floating point to uint cast!"); - return getFoldedCast(Instruction::FPToUI, C, Ty); + return getFoldedCast(Instruction::FPToUI, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty) { +Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced) { #ifndef NDEBUG bool fromVec = C->getType()->getTypeID() == Type::VectorTyID; bool toVec = Ty->getTypeID() == Type::VectorTyID; @@ -1603,10 +1806,11 @@ Constant *ConstantExpr::getFPToSI(Constant *C, Type *Ty) { assert((fromVec == toVec) && "Cannot convert from scalar to/from vector"); assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() && "This is an illegal floating point to sint cast!"); - return getFoldedCast(Instruction::FPToSI, C, Ty); + return getFoldedCast(Instruction::FPToSI, C, Ty, OnlyIfReduced); } -Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy) { +Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy, + bool OnlyIfReduced) { assert(C->getType()->getScalarType()->isPointerTy() && "PtrToInt source must be pointer or pointer vector"); assert(DstTy->getScalarType()->isIntegerTy() && @@ -1615,10 +1819,11 @@ Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy) { if (isa(C->getType())) assert(C->getType()->getVectorNumElements()==DstTy->getVectorNumElements()&& "Invalid cast between a different number of vector elements"); - return getFoldedCast(Instruction::PtrToInt, C, DstTy); + return getFoldedCast(Instruction::PtrToInt, C, DstTy, OnlyIfReduced); } -Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) { +Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy, + bool OnlyIfReduced) { assert(C->getType()->getScalarType()->isIntegerTy() && "IntToPtr source must be integer or integer vector"); assert(DstTy->getScalarType()->isPointerTy() && @@ -1627,10 +1832,11 @@ Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) { if (isa(C->getType())) assert(C->getType()->getVectorNumElements()==DstTy->getVectorNumElements()&& "Invalid cast between a different number of vector elements"); - return getFoldedCast(Instruction::IntToPtr, C, DstTy); + return getFoldedCast(Instruction::IntToPtr, C, DstTy, OnlyIfReduced); } -Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) { +Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy, + bool OnlyIfReduced) { assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) && "Invalid constantexpr bitcast!"); @@ -1638,11 +1844,32 @@ Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy) { // speedily. if (C->getType() == DstTy) return C; - return getFoldedCast(Instruction::BitCast, C, DstTy); + return getFoldedCast(Instruction::BitCast, C, DstTy, OnlyIfReduced); +} + +Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy, + bool OnlyIfReduced) { + assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) && + "Invalid constantexpr addrspacecast!"); + + // Canonicalize addrspacecasts between different pointer types by first + // bitcasting the pointer type and then converting the address space. + PointerType *SrcScalarTy = cast(C->getType()->getScalarType()); + PointerType *DstScalarTy = cast(DstTy->getScalarType()); + Type *DstElemTy = DstScalarTy->getElementType(); + if (SrcScalarTy->getElementType() != DstElemTy) { + Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace()); + if (VectorType *VT = dyn_cast(DstTy)) { + // Handle vectors of pointers. + MidTy = VectorType::get(MidTy, VT->getNumElements()); + } + C = getBitCast(C, MidTy); + } + return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy, OnlyIfReduced); } Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, - unsigned Flags) { + unsigned Flags, Type *OnlyIfReducedTy) { // Check the operands for consistency first. assert(Opcode >= Instruction::BinaryOpsBegin && Opcode < Instruction::BinaryOpsEnd && @@ -1711,9 +1938,11 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, 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); + if (OnlyIfReducedTy == C1->getType()) + return nullptr; + + Constant *ArgVec[] = { C1, C2 }; + ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags); LLVMContextImpl *pImpl = C1->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(C1->getType(), Key); @@ -1724,7 +1953,7 @@ Constant *ConstantExpr::getSizeOf(Type* Ty) { // 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); + Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } @@ -1733,12 +1962,12 @@ 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. Type *AligningTy = - StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); - Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); + StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, nullptr); + Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo(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); + Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } @@ -1756,13 +1985,13 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) { FieldNo }; Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); + Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } -Constant *ConstantExpr::getCompare(unsigned short Predicate, - Constant *C1, Constant *C2) { +Constant *ConstantExpr::getCompare(unsigned short Predicate, Constant *C1, + Constant *C2, bool OnlyIfReduced) { assert(C1->getType() == C2->getType() && "Op types should be identical!"); switch (Predicate) { @@ -1773,47 +2002,57 @@ Constant *ConstantExpr::getCompare(unsigned short Predicate, 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); + return getFCmp(Predicate, C1, C2, OnlyIfReduced); 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); + return getICmp(Predicate, C1, C2, OnlyIfReduced); } } -Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) { +Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2, + Type *OnlyIfReducedTy) { assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands"); 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); + if (OnlyIfReducedTy == V1->getType()) + return nullptr; + + Constant *ArgVec[] = { C, V1, V2 }; + ConstantExprKeyType Key(Instruction::Select, ArgVec); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef Idxs, - bool InBounds) { - assert(C->getType()->isPtrOrPtrVectorTy() && - "Non-pointer type for constant GetElementPtr expression"); +Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, + ArrayRef Idxs, bool InBounds, + Type *OnlyIfReducedTy) { + if (!Ty) + Ty = cast(C->getType()->getScalarType())->getElementType(); + else + assert( + Ty == + cast(C->getType()->getScalarType())->getContainedType(0u)); - if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) + if (Constant *FC = ConstantFoldGetElementPtr(Ty, C, InBounds, Idxs)) return FC; // Fold a few common cases. // Get the result type of the getelementptr! - Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs); - assert(Ty && "GEP indices invalid!"); + Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs); + assert(DestTy && "GEP indices invalid!"); unsigned AS = C->getType()->getPointerAddressSpace(); - Type *ReqTy = Ty->getPointerTo(AS); + Type *ReqTy = DestTy->getPointerTo(AS); if (VectorType *VecTy = dyn_cast(C->getType())) ReqTy = VectorType::get(ReqTy, VecTy->getNumElements()); + if (OnlyIfReducedTy == ReqTy) + return nullptr; + // Look up the constant in the table first to ensure uniqueness std::vector ArgVec; ArgVec.reserve(1 + Idxs.size()); @@ -1827,15 +2066,16 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef Idxs, "getelementptr index type missmatch"); ArgVec.push_back(cast(Idxs[i])); } - const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - InBounds ? GEPOperator::IsInBounds : 0); + const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0, + InBounds ? GEPOperator::IsInBounds : 0, None, + Ty); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant * -ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { +Constant *ConstantExpr::getICmp(unsigned short pred, Constant *LHS, + Constant *RHS, bool OnlyIfReduced) { assert(LHS->getType() == RHS->getType()); assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate"); @@ -1843,12 +2083,13 @@ ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) return FC; // Fold a few common cases... + if (OnlyIfReduced) + return nullptr; + // Look up the constant in the table first to ensure uniqueness - std::vector ArgVec; - ArgVec.push_back(LHS); - ArgVec.push_back(RHS); + Constant *ArgVec[] = { LHS, RHS }; // Get the key type with both the opcode and predicate - const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred); + const ConstantExprKeyType Key(Instruction::ICmp, ArgVec, pred); Type *ResultTy = Type::getInt1Ty(LHS->getContext()); if (VectorType *VT = dyn_cast(LHS->getType())) @@ -1858,20 +2099,21 @@ ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { return pImpl->ExprConstants.getOrCreate(ResultTy, Key); } -Constant * -ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { +Constant *ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, + Constant *RHS, bool OnlyIfReduced) { assert(LHS->getType() == RHS->getType()); assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate"); if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) return FC; // Fold a few common cases... + if (OnlyIfReduced) + return nullptr; + // Look up the constant in the table first to ensure uniqueness - std::vector ArgVec; - ArgVec.push_back(LHS); - ArgVec.push_back(RHS); + Constant *ArgVec[] = { LHS, RHS }; // Get the key type with both the opcode and predicate - const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred); + const ConstantExprKeyType Key(Instruction::FCmp, ArgVec, pred); Type *ResultTy = Type::getInt1Ty(LHS->getContext()); if (VectorType *VT = dyn_cast(LHS->getType())) @@ -1881,48 +2123,53 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { return pImpl->ExprConstants.getOrCreate(ResultTy, Key); } -Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { +Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx, + Type *OnlyIfReducedTy) { assert(Val->getType()->isVectorTy() && "Tried to create extractelement operation on non-vector type!"); - assert(Idx->getType()->isIntegerTy(32) && - "Extractelement index must be i32 type!"); + assert(Idx->getType()->isIntegerTy() && + "Extractelement index must be an integer type!"); if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) return FC; // Fold a few common cases. + Type *ReqTy = Val->getType()->getVectorElementType(); + if (OnlyIfReducedTy == ReqTy) + return nullptr; + // 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); + Constant *ArgVec[] = { Val, Idx }; + const ConstantExprKeyType Key(Instruction::ExtractElement, ArgVec); LLVMContextImpl *pImpl = Val->getContext().pImpl; - Type *ReqTy = Val->getType()->getVectorElementType(); return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, - Constant *Idx) { +Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, + Constant *Idx, Type *OnlyIfReducedTy) { assert(Val->getType()->isVectorTy() && "Tried to create insertelement operation on non-vector type!"); assert(Elt->getType() == Val->getType()->getVectorElementType() && "Insertelement types must match!"); - assert(Idx->getType()->isIntegerTy(32) && + assert(Idx->getType()->isIntegerTy() && "Insertelement index must be i32 type!"); if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) return FC; // Fold a few common cases. + + if (OnlyIfReducedTy == Val->getType()) + return nullptr; + // 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); + Constant *ArgVec[] = { Val, Elt, Idx }; + const ConstantExprKeyType Key(Instruction::InsertElement, ArgVec); LLVMContextImpl *pImpl = Val->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(Val->getType(), Key); } -Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) { +Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, + Constant *Mask, Type *OnlyIfReducedTy) { assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && "Invalid shuffle vector constant expr operands!"); @@ -1933,30 +2180,43 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, Type *EltTy = V1->getType()->getVectorElementType(); Type *ShufTy = VectorType::get(EltTy, NElts); + if (OnlyIfReducedTy == ShufTy) + return nullptr; + // 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); + Constant *ArgVec[] = { V1, V2, Mask }; + const ConstantExprKeyType Key(Instruction::ShuffleVector, ArgVec); LLVMContextImpl *pImpl = ShufTy->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ShufTy, Key); } Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, - ArrayRef Idxs) { + ArrayRef Idxs, + Type *OnlyIfReducedTy) { + assert(Agg->getType()->isFirstClassType() && + "Non-first-class type for constant insertvalue expression"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == Val->getType() && "insertvalue indices invalid!"); - assert(Agg->getType()->isFirstClassType() && - "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; + Type *ReqTy = Val->getType(); + + if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs)) + return FC; + + if (OnlyIfReducedTy == ReqTy) + return nullptr; + + Constant *ArgVec[] = { Agg, Val }; + const ConstantExprKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs); + + LLVMContextImpl *pImpl = Agg->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -Constant *ConstantExpr::getExtractValue(Constant *Agg, - ArrayRef Idxs) { +Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef Idxs, + Type *OnlyIfReducedTy) { assert(Agg->getType()->isFirstClassType() && "Tried to create extractelement operation on non-first-class type!"); @@ -1966,9 +2226,17 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, 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; + if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs)) + return FC; + + if (OnlyIfReducedTy == ReqTy) + return nullptr; + + Constant *ArgVec[] = { Agg }; + const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs); + + LLVMContextImpl *pImpl = Agg->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { @@ -2085,7 +2353,7 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) { switch (Opcode) { default: // Doesn't have an identity. - return 0; + return nullptr; case Instruction::Add: case Instruction::Or: @@ -2108,7 +2376,7 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { switch (Opcode) { default: // Doesn't have an absorber. - return 0; + return nullptr; case Instruction::Or: return Constant::getAllOnesValue(Ty); @@ -2121,28 +2389,31 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) { // destroyConstant - Remove the constant from the constant table... // -void ConstantExpr::destroyConstant() { +void ConstantExpr::destroyConstantImpl() { getType()->getContext().pImpl->ExprConstants.remove(this); - destroyConstantImpl(); } const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - - -GetElementPtrConstantExpr:: -GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, - Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - OperandTraits::op_end(this) - - (IdxList.size()+1), IdxList.size()+1) { - OperandList[0] = C; +GetElementPtrConstantExpr::GetElementPtrConstantExpr( + Type *SrcElementTy, Constant *C, ArrayRef IdxList, Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + OperandTraits::op_end(this) - + (IdxList.size() + 1), + IdxList.size() + 1), + SrcElementTy(SrcElementTy) { + Op<0>() = C; + Use *OperandList = getOperandList(); for (unsigned i = 0, E = IdxList.size(); i != E; ++i) OperandList[i+1] = IdxList[i]; } +Type *GetElementPtrConstantExpr::getSourceElementType() const { + return SrcElementTy; +} + //===----------------------------------------------------------------------===// // ConstantData* implementations @@ -2162,9 +2433,9 @@ StringRef ConstantDataSequential::getRawDataValues() const { /// formed with a vector or array of the specified element type. /// ConstantDataArray only works with normal float and int types that are /// stored densely in memory, not with things like i42 or x86_f80. -bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) { +bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) { if (Ty->isFloatTy() || Ty->isDoubleTy()) return true; - if (const IntegerType *IT = dyn_cast(Ty)) { + if (auto *IT = dyn_cast(Ty)) { switch (IT->getBitWidth()) { case 8: case 16: @@ -2217,15 +2488,17 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { return ConstantAggregateZero::get(Ty); // Do a lookup to see if we have already formed one of these. - StringMap::MapEntryTy &Slot = - Ty->getContext().pImpl->CDSConstants.GetOrCreateValue(Elements); + auto &Slot = + *Ty->getContext() + .pImpl->CDSConstants.insert(std::make_pair(Elements, nullptr)) + .first; // The bucket can point to a linked list of different CDS's that have the same // body but different types. For example, 0,0,0,1 could be a 4 element array // of i8, or a 1-element array of i32. They'll both end up in the same /// StringMap bucket, linked up by their Next pointers. Walk the list. - ConstantDataSequential **Entry = &Slot.getValue(); - for (ConstantDataSequential *Node = *Entry; Node != 0; + ConstantDataSequential **Entry = &Slot.second; + for (ConstantDataSequential *Node = *Entry; Node; Entry = &Node->Next, Node = *Entry) if (Node->getType() == Ty) return Node; @@ -2233,13 +2506,13 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { // Okay, we didn't get a hit. Create a node of the right class, link it in, // and return it. if (isa(Ty)) - return *Entry = new ConstantDataArray(Ty, Slot.getKeyData()); + return *Entry = new ConstantDataArray(Ty, Slot.first().data()); assert(isa(Ty)); - return *Entry = new ConstantDataVector(Ty, Slot.getKeyData()); + return *Entry = new ConstantDataVector(Ty, Slot.first().data()); } -void ConstantDataSequential::destroyConstant() { +void ConstantDataSequential::destroyConstantImpl() { // Remove the constant from the StringMap. StringMap &CDSConstants = getType()->getContext().pImpl->CDSConstants; @@ -2252,7 +2525,7 @@ void ConstantDataSequential::destroyConstant() { ConstantDataSequential **Entry = &Slot->getValue(); // Remove the entry from the hash table. - if ((*Entry)->Next == 0) { + if (!(*Entry)->Next) { // If there is only one value in the bucket (common case) it must be this // entry, and removing the entry should remove the bucket completely. assert((*Entry) == this && "Hash mismatch in ConstantDataSequential"); @@ -2273,10 +2546,7 @@ void ConstantDataSequential::destroyConstant() { // If we were part of a list, make sure that we don't delete the list that is // still owned by the uniquing map. - Next = 0; - - // Finally, actually delete it. - destroyConstantImpl(); + Next = nullptr; } /// get() constructors - Return a constant with array type with an element @@ -2310,7 +2580,31 @@ Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { Constant *ConstantDataArray::get(LLVMContext &Context, ArrayRef Elts) { Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size()); const char *Data = reinterpret_cast(Elts.data()); - return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); + return getImpl(StringRef(const_cast(Data), Elts.size() * 8), Ty); +} + +/// getFP() constructors - Return a constant with array type with an element +/// count and element type of float with precision matching the number of +/// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits, +/// double for 64bits) Note that this can return a ConstantAggregateZero +/// object. +Constant *ConstantDataArray::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 2), Ty); +} +Constant *ConstantDataArray::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 4), Ty); +} +Constant *ConstantDataArray::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 8), Ty); } /// getString - This method constructs a CDS and initializes it with a text @@ -2322,7 +2616,7 @@ Constant *ConstantDataArray::getString(LLVMContext &Context, StringRef Str, bool AddNull) { if (!AddNull) { const uint8_t *Data = reinterpret_cast(Str.data()); - return get(Context, ArrayRef(const_cast(Data), + return get(Context, makeArrayRef(const_cast(Data), Str.size())); } @@ -2363,7 +2657,31 @@ Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts) { Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef Elts) { Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size()); const char *Data = reinterpret_cast(Elts.data()); - return getImpl(StringRef(const_cast(Data), Elts.size()*8), Ty); + return getImpl(StringRef(const_cast(Data), Elts.size() * 8), Ty); +} + +/// getFP() constructors - Return a constant with vector type with an element +/// count and element type of float with the precision matching the number of +/// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits, +/// double for 64bits) Note that this can return a ConstantAggregateZero +/// object. +Constant *ConstantDataVector::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getHalfTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 2), Ty); +} +Constant *ConstantDataVector::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 4), Ty); +} +Constant *ConstantDataVector::getFP(LLVMContext &Context, + ArrayRef Elts) { + Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size()); + const char *Data = reinterpret_cast(Elts.data()); + return getImpl(StringRef(const_cast(Data), Elts.size() * 8), Ty); } Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) { @@ -2389,13 +2707,14 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) { if (ConstantFP *CFP = dyn_cast(V)) { if (CFP->getType()->isFloatTy()) { - SmallVector Elts(NumElts, CFP->getValueAPF().convertToFloat()); - return get(V->getContext(), Elts); + SmallVector Elts( + NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); + return getFP(V->getContext(), Elts); } if (CFP->getType()->isDoubleTy()) { - SmallVector Elts(NumElts, - CFP->getValueAPF().convertToDouble()); - return get(V->getContext(), Elts); + SmallVector Elts( + NumElts, CFP->getValueAPF().bitcastToAPInt().getLimitedValue()); + return getFP(V->getContext(), Elts); } } return ConstantVector::getSplat(NumElts, V); @@ -2433,13 +2752,13 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const { default: llvm_unreachable("Accessor can only be used when element is float/double!"); case Type::FloatTyID: { - const float *FloatPrt = reinterpret_cast(EltPtr); - return APFloat(*const_cast(FloatPrt)); - } + auto EltVal = *reinterpret_cast(EltPtr); + return APFloat(APFloat::IEEEsingle, APInt(32, EltVal)); + } case Type::DoubleTyID: { - const double *DoublePtr = reinterpret_cast(EltPtr); - return APFloat(*const_cast(DoublePtr)); - } + auto EltVal = *reinterpret_cast(EltPtr); + return APFloat(APFloat::IEEEdouble, APInt(64, EltVal)); + } } } @@ -2493,7 +2812,7 @@ bool ConstantDataSequential::isCString() const { } /// getSplatValue - If this is a splat constant, meaning that all of the -/// elements have the same value, return that value. Otherwise return NULL. +/// elements have the same value, return that value. Otherwise return nullptr. Constant *ConstantDataVector::getSplatValue() const { const char *Base = getRawDataValues().data(); @@ -2501,36 +2820,85 @@ Constant *ConstantDataVector::getSplatValue() const { unsigned EltSize = getElementByteSize(); for (unsigned i = 1, e = getNumElements(); i != e; ++i) if (memcmp(Base, Base+i*EltSize, EltSize)) - return 0; + return nullptr; // If they're all the same, return the 0th one as a representative. return getElementAsConstant(0); } //===----------------------------------------------------------------------===// -// replaceUsesOfWithOnConstant implementations +// handleOperandChange implementations -/// replaceUsesOfWithOnConstant - Update this constant array to change uses of +/// Update this constant array to change uses of /// 'From' to be uses of 'To'. This must update the uniquing data structures /// etc. /// /// Note that we intentionally replace all uses of From with To here. Consider /// a large array that uses 'From' 1000 times. By handling this case all here, -/// ConstantArray::replaceUsesOfWithOnConstant is only invoked once, and that +/// ConstantArray::handleOperandChange is only invoked once, and that /// single invocation handles all 1000 uses. Handling them one at a time would /// work, but would be really slow because it would have to unique each updated /// array instance. /// -void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +void Constant::handleOperandChange(Value *From, Value *To, Use *U) { + Value *Replacement = nullptr; + switch (getValueID()) { + default: + llvm_unreachable("Not a constant!"); +#define HANDLE_CONSTANT(Name) \ + case Value::Name##Val: \ + Replacement = cast(this)->handleOperandChangeImpl(From, To, U); \ + break; +#include "llvm/IR/Value.def" + } + + // If handleOperandChangeImpl returned nullptr, then it handled + // replacing itself and we don't want to delete or replace anything else here. + if (!Replacement) + return; + + // I do need to replace this with an existing value. + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement. + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + +Value *ConstantInt::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantFP::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *UndefValue::handleOperandChangeImpl(Value *From, Value *To, Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantPointerNull::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantAggregateZero::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantDataSequential::handleOperandChangeImpl(Value *From, Value *To, + Use *U) { + llvm_unreachable("Unsupported class for handleOperandChange()!"); +} + +Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - SmallVector Values; - LLVMContextImpl::ArrayConstantsTy::LookupKey Lookup; - Lookup.first = cast(getType()); Values.reserve(getNumOperands()); // Build replacement array. // Fill values with the modified operands of the constant array. Also, @@ -2539,6 +2907,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, // Keep track of whether all the values in the array are "ToC". bool AllSame = true; + Use *OperandList = getOperandList(); for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { Constant *Val = cast(O->get()); if (Val == From) { @@ -2549,64 +2918,30 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, AllSame &= Val == ToC; } - Constant *Replacement = 0; - if (AllSame && ToC->isNullValue()) { - Replacement = ConstantAggregateZero::get(getType()); - } else if (AllSame && isa(ToC)) { - Replacement = UndefValue::get(getType()); - } else { - // Check to see if we have this array type already. - Lookup.second = makeArrayRef(Values); - LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I = - pImpl->ArrayConstants.find(Lookup); - - if (I != pImpl->ArrayConstants.map_end()) { - Replacement = I->first; - } else { - // Okay, the new shape doesn't exist in the system yet. Instead of - // creating a new constant array, inserting it, replaceallusesof'ing the - // old with the new, then deleting the old... just update the current one - // in place! - pImpl->ArrayConstants.remove(this); - - // Update to the new value. Optimize for the case when we have a single - // operand that we're changing, but handle bulk updates efficiently. - if (NumUpdated == 1) { - unsigned OperandToUpdate = U - OperandList; - assert(getOperand(OperandToUpdate) == From && - "ReplaceAllUsesWith broken!"); - setOperand(OperandToUpdate, ToC); - } else { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i) == From) - setOperand(i, ToC); - } - pImpl->ArrayConstants.insert(this); - return; - } - } + if (AllSame && ToC->isNullValue()) + return ConstantAggregateZero::get(getType()); - // Otherwise, I do need to replace this with an existing value. - assert(Replacement != this && "I didn't contain From!"); + if (AllSame && isa(ToC)) + return UndefValue::get(getType()); - // Everyone using this now uses the replacement. - replaceAllUsesWith(Replacement); + // Check for any other type of constant-folding. + if (Constant *C = getImpl(getType(), Values)) + return C; - // Delete the old constant! - destroyConstant(); + // Update to the new value. + return getContext().pImpl->ArrayConstants.replaceOperandsInPlace( + Values, this, From, ToC, NumUpdated, U - OperandList); } -void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); + Use *OperandList = getOperandList(); unsigned OperandToUpdate = U-OperandList; assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); SmallVector Values; - LLVMContextImpl::StructConstantsTy::LookupKey Lookup; - Lookup.first = cast(getType()); Values.reserve(getNumOperands()); // Build replacement struct. // Fill values with the modified operands of the constant struct. Also, @@ -2633,92 +2968,69 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - LLVMContextImpl *pImpl = getContext().pImpl; - - Constant *Replacement = 0; - if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getType()); - } else if (isAllUndef) { - Replacement = UndefValue::get(getType()); - } else { - // Check to see if we have this struct type already. - Lookup.second = makeArrayRef(Values); - LLVMContextImpl::StructConstantsTy::MapTy::iterator I = - pImpl->StructConstants.find(Lookup); - - if (I != pImpl->StructConstants.map_end()) { - Replacement = I->first; - } else { - // Okay, the new shape doesn't exist in the system yet. Instead of - // creating a new constant struct, inserting it, replaceallusesof'ing the - // old with the new, then deleting the old... just update the current one - // in place! - pImpl->StructConstants.remove(this); - - // Update to the new value. - setOperand(OperandToUpdate, ToC); - pImpl->StructConstants.insert(this); - return; - } - } + if (isAllZeros) + return ConstantAggregateZero::get(getType()); - assert(Replacement != this && "I didn't contain From!"); + if (isAllUndef) + return UndefValue::get(getType()); - // Everyone using this now uses the replacement. - replaceAllUsesWith(Replacement); - - // Delete the old constant! - destroyConstant(); + // Update to the new value. + return getContext().pImpl->StructConstants.replaceOperandsInPlace( + Values, this, From, ToC); } -void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, - Use *U) { +Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); + Constant *ToC = cast(To); SmallVector Values; Values.reserve(getNumOperands()); // Build replacement array... + unsigned NumUpdated = 0; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { Constant *Val = getOperand(i); - if (Val == From) Val = cast(To); + if (Val == From) { + ++NumUpdated; + Val = ToC; + } Values.push_back(Val); } - Constant *Replacement = get(Values); - assert(Replacement != this && "I didn't contain From!"); - - // Everyone using this now uses the replacement. - replaceAllUsesWith(Replacement); + if (Constant *C = getImpl(Values)) + return C; - // Delete the old constant! - destroyConstant(); + // Update to the new value. + Use *OperandList = getOperandList(); + return getContext().pImpl->VectorConstants.replaceOperandsInPlace( + Values, this, From, ToC, NumUpdated, U - OperandList); } -void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, - Use *U) { +Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV, Use *U) { assert(isa(ToV) && "Cannot make Constant refer to non-constant!"); Constant *To = cast(ToV); SmallVector NewOps; + unsigned NumUpdated = 0; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { Constant *Op = getOperand(i); - NewOps.push_back(Op == From ? To : Op); + if (Op == From) { + ++NumUpdated; + Op = To; + } + NewOps.push_back(Op); } + assert(NumUpdated && "I didn't contain From!"); - Constant *Replacement = getWithOperands(NewOps); - assert(Replacement != this && "I didn't contain From!"); - - // Everyone using this now uses the replacement. - replaceAllUsesWith(Replacement); + if (Constant *C = getWithOperands(NewOps, getType(), true)) + return C; - // Delete the old constant! - destroyConstant(); + // Update to the new value. + Use *OperandList = getOperandList(); + return getContext().pImpl->ExprConstants.replaceOperandsInPlace( + NewOps, this, From, To, NumUpdated, U - OperandList); } Instruction *ConstantExpr::getAsInstruction() { - SmallVector ValueOperands; - for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) - ValueOperands.push_back(cast(I)); - + SmallVector ValueOperands(op_begin(), op_end()); ArrayRef Ops(ValueOperands); switch (getOpcode()) { @@ -2734,6 +3046,7 @@ Instruction *ConstantExpr::getAsInstruction() { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: + case Instruction::AddrSpaceCast: return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0], getType()); case Instruction::Select: @@ -2749,12 +3062,14 @@ Instruction *ConstantExpr::getAsInstruction() { case Instruction::ShuffleVector: return new ShuffleVectorInst(Ops[0], Ops[1], Ops[2]); - case Instruction::GetElementPtr: - if (cast(this)->isInBounds()) - return GetElementPtrInst::CreateInBounds(Ops[0], Ops.slice(1)); - else - return GetElementPtrInst::Create(Ops[0], Ops.slice(1)); - + case Instruction::GetElementPtr: { + const auto *GO = cast(this); + if (GO->isInBounds()) + return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(), + Ops[0], Ops.slice(1)); + return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0], + Ops.slice(1)); + } case Instruction::ICmp: case Instruction::FCmp: return CmpInst::Create((Instruction::OtherOps)getOpcode(),