forked from OSchip/llvm-project
IR: Thread OnlyIfReduced through ConstantExpr::getWithOperands()
In order to change `ConstantExpr::replaceUsesOfWithOnConstant()` to work like other constants (e.g., using `ConstantArray::getImpl()`), thread `OnlyIfReduced` through as necessary. When `OnlyIfReduced` is false, there's no functionality change. When it's true, if there's no constant folding or type changes `nullptr` is returned instead of the new constant. `ConstantExpr::replaceUsesOfWithOnConstant()` will be updated to use the "true" version in a follow-up commit. llvm-svn: 216015
This commit is contained in:
parent
a5dbed4936
commit
170eb985da
|
@ -858,19 +858,25 @@ public:
|
|||
bool HasNUW = false, bool HasNSW = false);
|
||||
static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
|
||||
static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
|
||||
static Constant *getTrunc (Constant *C, Type *Ty);
|
||||
static Constant *getSExt (Constant *C, Type *Ty);
|
||||
static Constant *getZExt (Constant *C, Type *Ty);
|
||||
static Constant *getFPTrunc (Constant *C, Type *Ty);
|
||||
static Constant *getFPExtend(Constant *C, Type *Ty);
|
||||
static Constant *getUIToFP (Constant *C, Type *Ty);
|
||||
static Constant *getSIToFP (Constant *C, Type *Ty);
|
||||
static Constant *getFPToUI (Constant *C, Type *Ty);
|
||||
static Constant *getFPToSI (Constant *C, Type *Ty);
|
||||
static Constant *getPtrToInt(Constant *C, Type *Ty);
|
||||
static Constant *getIntToPtr(Constant *C, Type *Ty);
|
||||
static Constant *getBitCast (Constant *C, Type *Ty);
|
||||
static Constant *getAddrSpaceCast(Constant *C, Type *Ty);
|
||||
static Constant *getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getSExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getZExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getFPTrunc(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getFPExtend(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getUIToFP(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getSIToFP(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getFPToUI(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getFPToSI(Constant *C, Type *Ty, bool OnlyIfReduced = false);
|
||||
static Constant *getPtrToInt(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getIntToPtr(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getBitCast(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getAddrSpaceCast(Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
|
||||
static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
|
||||
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
|
||||
|
@ -925,13 +931,14 @@ public:
|
|||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
||||
|
||||
// @brief Convenience function for getting one of the casting operations
|
||||
// using a CastOps opcode.
|
||||
static Constant *getCast(
|
||||
unsigned ops, ///< The opcode for the conversion
|
||||
Constant *C, ///< The constant to be converted
|
||||
Type *Ty ///< The type to which the constant is converted
|
||||
);
|
||||
/// \brief Convenience function for getting a Cast operation.
|
||||
///
|
||||
/// \param ops The opcode for the conversion
|
||||
/// \param C The constant to be converted
|
||||
/// \param Ty The type to which the constant is converted
|
||||
/// \param OnlyIfReduced see \a getWithOperands() docs.
|
||||
static Constant *getCast(unsigned ops, Constant *C, Type *Ty,
|
||||
bool OnlyIfReduced = false);
|
||||
|
||||
// @brief Create a ZExt or BitCast cast constant expression
|
||||
static Constant *getZExtOrBitCast(
|
||||
|
@ -997,44 +1004,53 @@ public:
|
|||
|
||||
/// Select constant expr
|
||||
///
|
||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
|
||||
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
|
||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
|
||||
/// get - Return a binary or shift operator constant expression,
|
||||
/// folding if possible.
|
||||
///
|
||||
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
|
||||
static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
|
||||
unsigned Flags = 0);
|
||||
unsigned Flags = 0, Type *OnlyIfReducedTy = nullptr);
|
||||
|
||||
/// @brief Return an ICmp or FCmp comparison operator constant expression.
|
||||
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
|
||||
/// \brief Return an ICmp or FCmp comparison operator constant expression.
|
||||
///
|
||||
/// \param OnlyIfReduced see \a getWithOperands() docs.
|
||||
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2,
|
||||
bool OnlyIfReduced = false);
|
||||
|
||||
/// get* - Return some common constants without having to
|
||||
/// specify the full Instruction::OPCODE identifier.
|
||||
///
|
||||
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
|
||||
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS,
|
||||
bool OnlyIfReduced = false);
|
||||
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS,
|
||||
bool OnlyIfReduced = false);
|
||||
|
||||
/// Getelementptr form. Value* is only accepted for convenience;
|
||||
/// all elements must be Constant's.
|
||||
///
|
||||
static Constant *getGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList,
|
||||
bool InBounds = false) {
|
||||
/// \param OnlyIfReduced see \a getWithOperands() docs.
|
||||
static Constant *getGetElementPtr(Constant *C, ArrayRef<Constant *> IdxList,
|
||||
bool InBounds = false,
|
||||
Type *OnlyIfReducedTy = nullptr) {
|
||||
return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(),
|
||||
IdxList.size()),
|
||||
InBounds);
|
||||
}
|
||||
static Constant *getGetElementPtr(Constant *C,
|
||||
Constant *Idx,
|
||||
bool InBounds = false) {
|
||||
static Constant *getGetElementPtr(Constant *C, Constant *Idx,
|
||||
bool InBounds = false,
|
||||
Type *OnlyIfReducedTy = nullptr) {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return getGetElementPtr(C, cast<Value>(Idx), InBounds);
|
||||
}
|
||||
static Constant *getGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList,
|
||||
bool InBounds = false);
|
||||
static Constant *getGetElementPtr(Constant *C, ArrayRef<Value *> IdxList,
|
||||
bool InBounds = false,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
|
||||
/// Create an "inbounds" getelementptr. See the documentation for the
|
||||
/// "inbounds" flag in LangRef.html for details.
|
||||
|
@ -1054,12 +1070,17 @@ public:
|
|||
return getGetElementPtr(C, IdxList, true);
|
||||
}
|
||||
|
||||
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
|
||||
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
|
||||
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
|
||||
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
|
||||
static Constant *getExtractElement(Constant *Vec, Constant *Idx,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
static Constant *getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
static Constant *getInsertValue(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> Idxs);
|
||||
ArrayRef<unsigned> Idxs,
|
||||
Type *OnlyIfReducedTy = nullptr);
|
||||
|
||||
/// getOpcode - Return the opcode at the root of this constant expression
|
||||
unsigned getOpcode() const { return getSubclassDataFromValue(); }
|
||||
|
@ -1086,11 +1107,17 @@ public:
|
|||
return getWithOperands(Ops, getType());
|
||||
}
|
||||
|
||||
/// getWithOperands - This returns the current constant expression with the
|
||||
/// operands replaced with the specified values and with the specified result
|
||||
/// type. The specified array must have the same number of operands as our
|
||||
/// current one.
|
||||
Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
|
||||
/// \brief Get the current expression with the operands replaced.
|
||||
///
|
||||
/// Return the current constant expression with the operands replaced with \c
|
||||
/// Ops and the type with \c Ty. The new operands must have the same number
|
||||
/// as the current ones.
|
||||
///
|
||||
/// If \c OnlyIfReduced is \c true, nullptr will be returned unless something
|
||||
/// gets constant-folded, the type changes, or the expression is otherwise
|
||||
/// canonicalized. This parameter should almost always be \c false.
|
||||
Constant *getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
|
||||
bool OnlyIfReduced = false) const;
|
||||
|
||||
/// getAsInstruction - Returns an Instruction which implements the same operation
|
||||
/// as this ConstantExpr. The instruction is not linked to any basic block.
|
||||
|
|
|
@ -1172,8 +1172,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)
|
||||
|
@ -1182,6 +1182,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:
|
||||
|
@ -1196,28 +1197,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1500,13 +1507,16 @@ 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.
|
||||
|
@ -1515,7 +1525,8 @@ static inline Constant *getFoldedCast(
|
|||
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");
|
||||
|
@ -1524,19 +1535,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1609,7 +1633,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;
|
||||
|
@ -1620,10 +1644,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;
|
||||
|
@ -1634,10 +1658,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;
|
||||
|
@ -1648,10 +1672,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;
|
||||
|
@ -1660,10 +1684,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;
|
||||
|
@ -1672,10 +1696,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;
|
||||
|
@ -1683,10 +1707,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;
|
||||
|
@ -1694,10 +1718,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;
|
||||
|
@ -1705,10 +1729,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;
|
||||
|
@ -1716,10 +1740,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() &&
|
||||
|
@ -1728,10 +1753,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() &&
|
||||
|
@ -1740,10 +1766,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!");
|
||||
|
||||
|
@ -1751,10 +1778,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!");
|
||||
|
||||
|
@ -1771,11 +1799,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 &&
|
||||
|
@ -1844,6 +1872,9 @@ 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 };
|
||||
ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags);
|
||||
|
||||
|
@ -1893,8 +1924,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) {
|
||||
|
@ -1905,22 +1936,26 @@ 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 };
|
||||
ConstantExprKeyType Key(Instruction::Select, ArgVec);
|
||||
|
||||
|
@ -1929,7 +1964,7 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) {
|
|||
}
|
||||
|
||||
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");
|
||||
|
||||
|
@ -1944,6 +1979,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());
|
||||
|
@ -1964,8 +2002,8 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
|
|||
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");
|
||||
|
@ -1973,6 +2011,9 @@ 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
|
||||
|
@ -1986,14 +2027,17 @@ 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
|
||||
|
@ -2007,7 +2051,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() &&
|
||||
|
@ -2016,17 +2061,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 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() &&
|
||||
|
@ -2036,6 +2084,10 @@ 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 ConstantExprKeyType Key(Instruction::InsertElement, ArgVec);
|
||||
|
@ -2044,8 +2096,8 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
|
|||
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!");
|
||||
|
||||
|
@ -2056,6 +2108,9 @@ 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 ConstantExprKeyType Key(Instruction::ShuffleVector, ArgVec);
|
||||
|
@ -2065,7 +2120,8 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
|
|||
}
|
||||
|
||||
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");
|
||||
|
||||
|
@ -2077,6 +2133,9 @@ 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 ConstantExprKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs);
|
||||
|
||||
|
@ -2084,8 +2143,8 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
|
|||
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!");
|
||||
|
||||
|
@ -2098,6 +2157,9 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg,
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue