aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Constants.cpp')
-rw-r--r--lib/IR/Constants.cpp509
1 files changed, 295 insertions, 214 deletions
diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp
index b815936..e0cb835 100644
--- a/lib/IR/Constants.cpp
+++ b/lib/IR/Constants.cpp
@@ -107,6 +107,28 @@ bool Constant::isAllOnesValue() const {
return false;
}
+bool Constant::isOneValue() const {
+ // Check for 1 integers
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
+ return CI->isOne();
+
+ // Check for FP which are bitcasted from 1 integers
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
+ return CFP->getValueAPF().bitcastToAPInt() == 1;
+
+ // Check for constant vectors which are splats of 1 values.
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(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<ConstantDataVector>(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<ConstantInt>(this))
@@ -129,6 +151,29 @@ bool Constant::isMinSignedValue() const {
return false;
}
+bool Constant::isNotMinSignedValue() const {
+ // Check for INT_MIN integers
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
+ return !CI->isMinValue(/*isSigned=*/true);
+
+ // Check for FP which are bitcasted from INT_MIN integers
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
+ return !CFP->getValueAPF().bitcastToAPInt().isMinSignedValue();
+
+ // Check for constant vectors which are splats of INT_MIN values.
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(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<ConstantDataVector>(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()) {
@@ -261,7 +306,7 @@ void Constant::destroyConstantImpl() {
}
static bool canTrapImpl(const Constant *C,
- SmallPtrSet<const ConstantExpr *, 4> &NonTrappingOps) {
+ SmallPtrSetImpl<const ConstantExpr *> &NonTrappingOps) {
assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
// The only thing that could possibly trap are constant exprs.
const ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
@@ -271,7 +316,7 @@ static bool canTrapImpl(const Constant *C,
// ConstantExpr traps if any operands can trap.
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
if (ConstantExpr *Op = dyn_cast<ConstantExpr>(CE->getOperand(i))) {
- if (NonTrappingOps.insert(Op) && canTrapImpl(Op, NonTrappingOps))
+ if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps))
return true;
}
}
@@ -318,7 +363,7 @@ ConstHasGlobalValuePredicate(const Constant *C,
const Constant *ConstOp = dyn_cast<Constant>(Op);
if (!ConstOp)
continue;
- if (Visited.insert(ConstOp))
+ if (Visited.insert(ConstOp).second)
WorkList.push_back(ConstOp);
}
}
@@ -781,6 +826,11 @@ ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
}
Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
+ if (Constant *C = getImpl(Ty, V))
+ return C;
+ return Ty->getContext().pImpl->ArrayConstants.getOrCreate(Ty, V);
+}
+Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
// Empty arrays are canonicalized to ConstantAggregateZero.
if (V.empty())
return ConstantAggregateZero::get(Ty);
@@ -789,7 +839,6 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> 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
@@ -871,7 +920,7 @@ Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
}
// 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
@@ -959,9 +1008,14 @@ ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
// ConstantVector accessors.
Constant *ConstantVector::get(ArrayRef<Constant*> 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<Constant*> 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.
@@ -1053,7 +1107,7 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) {
// 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) {
@@ -1141,8 +1195,8 @@ 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<Constant*> Ops, Type *Ty) const {
+Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
+ bool OnlyIfReduced) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
bool AnyChange = Ty != getType();
for (unsigned i = 0; i != Ops.size(); ++i)
@@ -1151,6 +1205,7 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const {
if (!AnyChange) // No operands changed, return self.
return const_cast<ConstantExpr*>(this);
+ Type *OnlyIfReducedTy = OnlyIfReduced ? Ty : nullptr;
switch (getOpcode()) {
case Instruction::Trunc:
case Instruction::ZExt:
@@ -1165,28 +1220,34 @@ getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const {
case Instruction::IntToPtr:
case Instruction::BitCast:
case Instruction::AddrSpaceCast:
- return ConstantExpr::getCast(getOpcode(), Ops[0], Ty);
+ 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]);
+ return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
+ OnlyIfReducedTy);
case Instruction::GetElementPtr:
return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1),
- cast<GEPOperator>(this)->isInBounds());
+ cast<GEPOperator>(this)->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);
}
}
@@ -1447,27 +1508,21 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
// and return early.
BlockAddress *&NewBA =
getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)];
- if (!NewBA) {
- 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);
+ if (NewBA) {
+ replaceUsesOfWithOnConstantImpl(NewBA);
return;
}
- // Otherwise, I do need to replace this with an existing value.
- assert(NewBA != this && "I didn't contain From!");
-
- // Everyone using this now uses the replacement.
- replaceAllUsesWith(NewBA);
+ getBasicBlock()->AdjustBlockAddressRefCount(-1);
- destroyConstant();
+ // 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);
}
//---- ConstantExpr::get() implementations.
@@ -1475,22 +1530,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.
- ExprMapKeyType Key(opc, C);
+ 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");
@@ -1499,19 +1558,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::AddrSpaceCast: return getAddrSpaceCast(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);
}
}
@@ -1584,7 +1656,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;
@@ -1595,10 +1667,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;
@@ -1609,10 +1681,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;
@@ -1623,10 +1695,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;
@@ -1635,10 +1707,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;
@@ -1647,10 +1719,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;
@@ -1658,10 +1730,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;
@@ -1669,10 +1741,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;
@@ -1680,10 +1752,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;
@@ -1691,10 +1763,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() &&
@@ -1703,10 +1776,11 @@ Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy) {
if (isa<VectorType>(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() &&
@@ -1715,10 +1789,11 @@ Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy) {
if (isa<VectorType>(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!");
@@ -1726,10 +1801,11 @@ 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) {
+Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
+ bool OnlyIfReduced) {
assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
"Invalid constantexpr addrspacecast!");
@@ -1746,11 +1822,11 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) {
}
C = getBitCast(C, MidTy);
}
- return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy);
+ 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 &&
@@ -1819,8 +1895,11 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases.
+ if (OnlyIfReducedTy == C1->getType())
+ return nullptr;
+
Constant *ArgVec[] = { C1, C2 };
- ExprMapKeyType Key(Opcode, ArgVec, 0, Flags);
+ ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags);
LLVMContextImpl *pImpl = C1->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
@@ -1840,7 +1919,7 @@ 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);
+ 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);
@@ -1868,8 +1947,8 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) {
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) {
@@ -1880,31 +1959,35 @@ 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
+ if (OnlyIfReducedTy == V1->getType())
+ return nullptr;
+
Constant *ArgVec[] = { C, V1, V2 };
- ExprMapKeyType Key(Instruction::Select, ArgVec);
+ ConstantExprKeyType Key(Instruction::Select, ArgVec);
LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
}
Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
- bool InBounds) {
+ bool InBounds, Type *OnlyIfReducedTy) {
assert(C->getType()->isPtrOrPtrVectorTy() &&
"Non-pointer type for constant GetElementPtr expression");
@@ -1919,6 +2002,9 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
if (VectorType *VecTy = dyn_cast<VectorType>(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<Constant*> ArgVec;
ArgVec.reserve(1 + Idxs.size());
@@ -1932,15 +2018,15 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
"getelementptr index type missmatch");
ArgVec.push_back(cast<Constant>(Idxs[i]));
}
- const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
- InBounds ? GEPOperator::IsInBounds : 0);
+ const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
+ InBounds ? GEPOperator::IsInBounds : 0);
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");
@@ -1948,10 +2034,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
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<VectorType>(LHS->getType()))
@@ -1961,18 +2050,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
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<VectorType>(LHS->getType()))
@@ -1982,7 +2074,8 @@ 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() &&
@@ -1991,17 +2084,20 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
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
Constant *ArgVec[] = { Val, Idx };
- const ExprMapKeyType Key(Instruction::ExtractElement, ArgVec);
+ 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() &&
@@ -2011,16 +2107,20 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
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
Constant *ArgVec[] = { Val, Elt, Idx };
- const ExprMapKeyType Key(Instruction::InsertElement, ArgVec);
+ 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!");
@@ -2031,16 +2131,20 @@ 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
Constant *ArgVec[] = { V1, V2, Mask };
- const ExprMapKeyType Key(Instruction::ShuffleVector, ArgVec);
+ 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<unsigned> Idxs) {
+ ArrayRef<unsigned> Idxs,
+ Type *OnlyIfReducedTy) {
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant insertvalue expression");
@@ -2052,15 +2156,18 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs))
return FC;
+ if (OnlyIfReducedTy == ReqTy)
+ return nullptr;
+
Constant *ArgVec[] = { Agg, Val };
- const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs);
+ 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<unsigned> Idxs) {
+Constant *ConstantExpr::getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
+ Type *OnlyIfReducedTy) {
assert(Agg->getType()->isFirstClassType() &&
"Tried to create extractelement operation on non-first-class type!");
@@ -2073,8 +2180,11 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg,
if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs))
return FC;
+ if (OnlyIfReducedTy == ReqTy)
+ return nullptr;
+
Constant *ArgVec[] = { Agg };
- const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs);
+ const ConstantExprKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs);
LLVMContextImpl *pImpl = Agg->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
@@ -2326,14 +2436,16 @@ 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<ConstantDataSequential*>::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();
+ ConstantDataSequential **Entry = &Slot.second;
for (ConstantDataSequential *Node = *Entry; Node;
Entry = &Node->Next, Node = *Entry)
if (Node->getType() == Ty)
@@ -2342,10 +2454,10 @@ 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<ArrayType>(Ty))
- return *Entry = new ConstantDataArray(Ty, Slot.getKeyData());
+ return *Entry = new ConstantDataArray(Ty, Slot.first().data());
assert(isa<VectorType>(Ty));
- return *Entry = new ConstantDataVector(Ty, Slot.getKeyData());
+ return *Entry = new ConstantDataVector(Ty, Slot.first().data());
}
void ConstantDataSequential::destroyConstant() {
@@ -2431,7 +2543,7 @@ Constant *ConstantDataArray::getString(LLVMContext &Context,
StringRef Str, bool AddNull) {
if (!AddNull) {
const uint8_t *Data = reinterpret_cast<const uint8_t *>(Str.data());
- return get(Context, ArrayRef<uint8_t>(const_cast<uint8_t *>(Data),
+ return get(Context, makeArrayRef(const_cast<uint8_t *>(Data),
Str.size()));
}
@@ -2602,7 +2714,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();
@@ -2630,16 +2742,23 @@ Constant *ConstantDataVector::getSplatValue() const {
/// work, but would be really slow because it would have to unique each updated
/// array instance.
///
+void Constant::replaceUsesOfWithOnConstantImpl(Constant *Replacement) {
+ // 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();
+}
+
void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
-
SmallVector<Constant*, 8> Values;
- LLVMContextImpl::ArrayConstantsTy::LookupKey Lookup;
- Lookup.first = cast<ArrayType>(getType());
Values.reserve(getNumOperands()); // Build replacement array.
// Fill values with the modified operands of the constant array. Also,
@@ -2658,51 +2777,25 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
AllSame &= Val == ToC;
}
- Constant *Replacement = nullptr;
if (AllSame && ToC->isNullValue()) {
- Replacement = ConstantAggregateZero::get(getType());
- } else if (AllSame && isa<UndefValue>(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;
- }
+ replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType()));
+ return;
+ }
+ if (AllSame && isa<UndefValue>(ToC)) {
+ replaceUsesOfWithOnConstantImpl(UndefValue::get(getType()));
+ return;
}
- // Otherwise, I do need to replace this with an existing value.
- assert(Replacement != this && "I didn't contain From!");
-
- // Everyone using this now uses the replacement.
- replaceAllUsesWith(Replacement);
+ // Check for any other type of constant-folding.
+ if (Constant *C = getImpl(getType(), Values)) {
+ replaceUsesOfWithOnConstantImpl(C);
+ return;
+ }
- // Delete the old constant!
- destroyConstant();
+ // Update to the new value.
+ if (Constant *C = getContext().pImpl->ArrayConstants.replaceOperandsInPlace(
+ Values, this, From, ToC, NumUpdated, U - OperandList))
+ replaceUsesOfWithOnConstantImpl(C);
}
void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
@@ -2714,8 +2807,6 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
SmallVector<Constant*, 8> Values;
- LLVMContextImpl::StructConstantsTy::LookupKey Lookup;
- Lookup.first = cast<StructType>(getType());
Values.reserve(getNumOperands()); // Build replacement struct.
// Fill values with the modified operands of the constant struct. Also,
@@ -2742,64 +2833,47 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
}
Values[OperandToUpdate] = ToC;
- LLVMContextImpl *pImpl = getContext().pImpl;
-
- Constant *Replacement = nullptr;
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;
- }
+ replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType()));
+ return;
+ }
+ if (isAllUndef) {
+ replaceUsesOfWithOnConstantImpl(UndefValue::get(getType()));
+ return;
}
- assert(Replacement != this && "I didn't contain From!");
-
- // Everyone using this now uses the replacement.
- replaceAllUsesWith(Replacement);
-
- // Delete the old constant!
- destroyConstant();
+ // Update to the new value.
+ if (Constant *C = getContext().pImpl->StructConstants.replaceOperandsInPlace(
+ Values, this, From, ToC))
+ replaceUsesOfWithOnConstantImpl(C);
}
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+ Constant *ToC = cast<Constant>(To);
SmallVector<Constant*, 8> 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<Constant>(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)) {
+ replaceUsesOfWithOnConstantImpl(C);
+ return;
+ }
- // Delete the old constant!
- destroyConstant();
+ // Update to the new value.
+ if (Constant *C = getContext().pImpl->VectorConstants.replaceOperandsInPlace(
+ Values, this, From, ToC, NumUpdated, U - OperandList))
+ replaceUsesOfWithOnConstantImpl(C);
}
void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
@@ -2808,19 +2882,26 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
Constant *To = cast<Constant>(ToV);
SmallVector<Constant*, 8> 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)) {
+ replaceUsesOfWithOnConstantImpl(C);
+ return;
+ }
- // Delete the old constant!
- destroyConstant();
+ // Update to the new value.
+ if (Constant *C = getContext().pImpl->ExprConstants.replaceOperandsInPlace(
+ NewOps, this, From, To, NumUpdated, U - OperandList))
+ replaceUsesOfWithOnConstantImpl(C);
}
Instruction *ConstantExpr::getAsInstruction() {