summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR/Constants.cpp')
-rw-r--r--contrib/llvm/lib/IR/Constants.cpp342
1 files changed, 106 insertions, 236 deletions
diff --git a/contrib/llvm/lib/IR/Constants.cpp b/contrib/llvm/lib/IR/Constants.cpp
index 0898bf6..d8d55b4 100644
--- a/contrib/llvm/lib/IR/Constants.cpp
+++ b/contrib/llvm/lib/IR/Constants.cpp
@@ -14,8 +14,6 @@
#include "llvm/IR/Constants.h"
#include "ConstantFold.h"
#include "LLVMContextImpl.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -26,7 +24,6 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
@@ -42,6 +39,8 @@ using namespace llvm;
void Constant::anchor() { }
+void ConstantData::anchor() {}
+
bool Constant::isNegativeZeroValue() const {
// Floating point values have an explicit -0.0 value.
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
@@ -192,7 +191,7 @@ bool Constant::isNotMinSignedValue() const {
return false;
}
-// Constructor to create a '0' constant of arbitrary type...
+/// Constructor to create a '0' constant of arbitrary type.
Constant *Constant::getNullValue(Type *Ty) {
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
@@ -263,19 +262,9 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
getAllOnesValue(VTy->getElementType()));
}
-/// getAggregateElement - For aggregates (struct/array/vector) return the
-/// constant that corresponds to the specified element if possible, or null if
-/// not. This can return null if the element index is a ConstantExpr, or if
-/// 'this' is a constant expr.
Constant *Constant::getAggregateElement(unsigned Elt) const {
- if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(this))
- return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : nullptr;
-
- if (const ConstantArray *CA = dyn_cast<ConstantArray>(this))
- return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : nullptr;
-
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
- return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr;
+ if (const ConstantAggregate *CC = dyn_cast<ConstantAggregate>(this))
+ return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
if (const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(this))
return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr;
@@ -369,8 +358,6 @@ static bool canTrapImpl(const Constant *C,
}
}
-/// 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<const ConstantExpr *, 4> NonTrappingOps;
return canTrapImpl(this, NonTrappingOps);
@@ -401,7 +388,6 @@ ConstHasGlobalValuePredicate(const Constant *C,
return false;
}
-/// Return true if the value can vary between threads.
bool Constant::isThreadDependent() const {
auto DLLImportPredicate = [](const GlobalValue *GV) {
return GV->isThreadLocal();
@@ -416,8 +402,6 @@ bool Constant::isDLLImportDependent() const {
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 User *U : users()) {
const Constant *UC = dyn_cast<Constant>(U);
@@ -461,9 +445,8 @@ bool Constant::needsRelocation() const {
return Result;
}
-/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
-/// it. This involves recursively eliminating any dead users of the
-/// constantexpr.
+/// If the specified constantexpr is dead, remove it. This involves recursively
+/// eliminating any dead users of the constantexpr.
static bool removeDeadUsersOfConstant(const Constant *C) {
if (isa<GlobalValue>(C)) return false; // Cannot remove this
@@ -479,10 +462,6 @@ static bool removeDeadUsersOfConstant(const Constant *C) {
}
-/// removeDeadConstantUsers - If there are any dead constant users dangling
-/// off of this constant, remove them. This method is useful for clients
-/// that want to check to see if a global is unused, but don't want to deal
-/// with potentially dead constants hanging off of the globals.
void Constant::removeDeadConstantUsers() const {
Value::const_user_iterator I = user_begin(), E = user_end();
Value::const_user_iterator LastNonDeadUser = E;
@@ -521,8 +500,8 @@ void Constant::removeDeadConstantUsers() const {
void ConstantInt::anchor() { }
-ConstantInt::ConstantInt(IntegerType *Ty, const APInt& V)
- : Constant(Ty, ConstantIntVal, nullptr, 0), Val(V) {
+ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
+ : ConstantData(Ty, ConstantIntVal), Val(V) {
assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
}
@@ -588,8 +567,7 @@ Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
return C;
}
-ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V,
- bool isSigned) {
+ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) {
return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned));
}
@@ -613,8 +591,7 @@ Constant *ConstantInt::get(Type *Ty, const APInt& V) {
return C;
}
-ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str,
- uint8_t radix) {
+ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) {
return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix));
}
@@ -645,9 +622,6 @@ static const fltSemantics *TypeToFloatSemantics(Type *Ty) {
void ConstantFP::anchor() { }
-/// get() - This returns a constant fp for the specified value in the
-/// specified type. This should only be used for simple constant values like
-/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
Constant *ConstantFP::get(Type *Ty, double V) {
LLVMContext &Context = Ty->getContext();
@@ -748,8 +722,8 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
return C;
}
-ConstantFP::ConstantFP(Type *Ty, const APFloat& V)
- : Constant(Ty, ConstantFPVal, nullptr, 0), Val(V) {
+ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
+ : ConstantData(Ty, ConstantFPVal), Val(V) {
assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
"FP type Mismatch");
}
@@ -767,28 +741,20 @@ void ConstantFP::destroyConstantImpl() {
// ConstantAggregateZero Implementation
//===----------------------------------------------------------------------===//
-/// getSequentialElement - If this CAZ has array or vector type, return a zero
-/// with the right element type.
Constant *ConstantAggregateZero::getSequentialElement() const {
return Constant::getNullValue(getType()->getSequentialElementType());
}
-/// getStructElement - If this CAZ has struct type, return a zero with the
-/// right element type for the specified element.
Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
return Constant::getNullValue(getType()->getStructElementType(Elt));
}
-/// getElementValue - Return a zero of the right value for the specified GEP
-/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
}
-/// getElementValue - Return a zero of the right value for the specified GEP
-/// index.
Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
@@ -808,28 +774,20 @@ unsigned ConstantAggregateZero::getNumElements() const {
// UndefValue Implementation
//===----------------------------------------------------------------------===//
-/// getSequentialElement - If this undef has array or vector type, return an
-/// undef with the right element type.
UndefValue *UndefValue::getSequentialElement() const {
return UndefValue::get(getType()->getSequentialElementType());
}
-/// getStructElement - If this undef has struct type, return a zero with the
-/// right element type for the specified element.
UndefValue *UndefValue::getStructElement(unsigned Elt) const {
return UndefValue::get(getType()->getStructElementType(Elt));
}
-/// getElementValue - Return an undef of the right value for the specified GEP
-/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
UndefValue *UndefValue::getElementValue(Constant *C) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
}
-/// getElementValue - Return an undef of the right value for the specified GEP
-/// index.
UndefValue *UndefValue::getElementValue(unsigned Idx) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
@@ -910,16 +868,25 @@ static Constant *getSequenceIfElementsMatch(Constant *C,
return nullptr;
}
+ConstantAggregate::ConstantAggregate(CompositeType *T, ValueTy VT,
+ ArrayRef<Constant *> V)
+ : Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
+ V.size()) {
+ std::copy(V.begin(), V.end(), op_begin());
+
+ // Check that types match, unless this is an opaque struct.
+ if (auto *ST = dyn_cast<StructType>(T))
+ if (ST->isOpaque())
+ return;
+ for (unsigned I = 0, E = V.size(); I != E; ++I)
+ assert(V[I]->getType() == T->getTypeAtIndex(I) &&
+ "Initializer for composite element doesn't match!");
+}
+
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
- : Constant(T, ConstantArrayVal,
- OperandTraits<ConstantArray>::op_end(this) - V.size(),
- V.size()) {
+ : ConstantAggregate(T, ConstantArrayVal, V) {
assert(V.size() == T->getNumElements() &&
- "Invalid initializer vector for constant array");
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- assert(V[i]->getType() == T->getElementType() &&
- "Initializer for array element doesn't match array element type!");
- std::copy(V.begin(), V.end(), op_begin());
+ "Invalid initializer for constant array");
}
Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {
@@ -957,8 +924,6 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
return nullptr;
}
-/// getTypeForElements - Return an anonymous struct type to use for a constant
-/// with the specified set of elements. The list must not be empty.
StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
ArrayRef<Constant*> V,
bool Packed) {
@@ -978,17 +943,10 @@ StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
return getTypeForElements(V[0]->getContext(), V, Packed);
}
-
ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V)
- : Constant(T, ConstantStructVal,
- OperandTraits<ConstantStruct>::op_end(this) - V.size(),
- V.size()) {
- assert(V.size() == T->getNumElements() &&
- "Invalid initializer vector for constant structure");
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- assert((T->isOpaque() || V[i]->getType() == T->getElementType(i)) &&
- "Initializer for struct element doesn't match struct element type!");
- std::copy(V.begin(), V.end(), op_begin());
+ : ConstantAggregate(T, ConstantStructVal, V) {
+ assert((T->isOpaque() || V.size() == T->getNumElements()) &&
+ "Invalid initializer for constant struct");
}
// ConstantStruct accessors.
@@ -1031,13 +989,9 @@ Constant *ConstantStruct::get(StructType *T, ...) {
}
ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
- : Constant(T, ConstantVectorVal,
- OperandTraits<ConstantVector>::op_end(this) - V.size(),
- V.size()) {
- for (size_t i = 0, e = V.size(); i != e; i++)
- assert(V[i]->getType() == T->getElementType() &&
- "Initializer for vector element doesn't match vector element type!");
- std::copy(V.begin(), V.end(), op_begin());
+ : ConstantAggregate(T, ConstantVectorVal, V) {
+ assert(V.size() == T->getNumElements() &&
+ "Invalid initializer for constant vector");
}
// ConstantVector accessors.
@@ -1157,8 +1111,6 @@ unsigned ConstantExpr::getPredicate() const {
return cast<CompareConstantExpr>(this)->predicate;
}
-/// getWithOperandReplaced - Return a constant expression identical to this
-/// one, but with the specified operand set to the specified value.
Constant *
ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
assert(Op->getType() == getOperand(OpNo)->getType() &&
@@ -1173,9 +1125,6 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
return getWithOperands(NewOps);
}
-/// 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,
bool OnlyIfReduced, Type *SrcTy) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
@@ -1320,14 +1269,12 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
return Entry;
}
-/// destroyConstant - Remove the constant from the constant table.
-///
+/// Remove the constant from the constant table.
void ConstantAggregateZero::destroyConstantImpl() {
getContext().pImpl->CAZConstants.erase(getType());
}
-/// destroyConstant - Remove the constant from the constant table...
-///
+/// Remove the constant from the constant table.
void ConstantArray::destroyConstantImpl() {
getType()->getContext().pImpl->ArrayConstants.remove(this);
}
@@ -1336,20 +1283,16 @@ void ConstantArray::destroyConstantImpl() {
//---- ConstantStruct::get() implementation...
//
-// destroyConstant - Remove the constant from the constant table...
-//
+/// Remove the constant from the constant table.
void ConstantStruct::destroyConstantImpl() {
getType()->getContext().pImpl->StructConstants.remove(this);
}
-// destroyConstant - Remove the constant from the constant table...
-//
+/// Remove the constant from the constant table.
void ConstantVector::destroyConstantImpl() {
getType()->getContext().pImpl->VectorConstants.remove(this);
}
-/// getSplatValue - If this is a splat vector constant, meaning that all of
-/// the elements have the same value, return that value. Otherwise return 0.
Constant *Constant::getSplatValue() const {
assert(this->getType()->isVectorTy() && "Only valid for vectors!");
if (isa<ConstantAggregateZero>(this))
@@ -1361,8 +1304,6 @@ Constant *Constant::getSplatValue() const {
return nullptr;
}
-/// getSplatValue - If this is a splat constant, where all of the
-/// elements have the same value, return that value. Otherwise return null.
Constant *ConstantVector::getSplatValue() const {
// Check out first element.
Constant *Elt = getOperand(0);
@@ -1373,8 +1314,6 @@ Constant *ConstantVector::getSplatValue() const {
return Elt;
}
-/// If C is a constant integer then return its value, otherwise C must be a
-/// vector of constant integers, all equal, and the common value is returned.
const APInt &Constant::getUniqueInteger() const {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
return CI->getValue();
@@ -1395,16 +1334,11 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
return Entry;
}
-// destroyConstant - Remove the constant from the constant table...
-//
+/// Remove the constant from the constant table.
void ConstantPointerNull::destroyConstantImpl() {
getContext().pImpl->CPNConstants.erase(getType());
}
-
-//---- UndefValue::get() implementation.
-//
-
UndefValue *UndefValue::get(Type *Ty) {
UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty];
if (!Entry)
@@ -1413,16 +1347,12 @@ UndefValue *UndefValue::get(Type *Ty) {
return Entry;
}
-// destroyConstant - Remove the constant from the constant table.
-//
+/// Remove the constant from the constant table.
void UndefValue::destroyConstantImpl() {
// Free the constant and any dangling references to it.
getContext().pImpl->UVConstants.erase(getType());
}
-//---- BlockAddress::get() implementation.
-//
-
BlockAddress *BlockAddress::get(BasicBlock *BB) {
assert(BB->getParent() && "Block must have a parent");
return get(BB->getParent(), BB);
@@ -1458,24 +1388,25 @@ BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
return BA;
}
-// destroyConstant - Remove the constant from the constant table.
-//
+/// Remove the constant from the constant table.
void BlockAddress::destroyConstantImpl() {
getFunction()->getType()->getContext().pImpl
->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
getBasicBlock()->AdjustBlockAddressRefCount(-1);
}
-Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
+Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {
// 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>())
+ if (From == NewF)
NewF = cast<Function>(To->stripPointerCasts());
- else
+ else {
+ assert(From == NewBB && "From does not match any operand");
NewBB = cast<BasicBlock>(To);
+ }
// See if the 'new' entry already exists, if not, just update this in place
// and return early.
@@ -1606,8 +1537,7 @@ Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S,
return getBitCast(S, Ty);
}
-Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty,
- bool isSigned) {
+Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty, bool isSigned) {
assert(C->getType()->isIntOrIntVectorTy() &&
Ty->isIntOrIntVectorTy() && "Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
@@ -1979,8 +1909,16 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
assert(DestTy && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace();
Type *ReqTy = DestTy->getPointerTo(AS);
- if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
- ReqTy = VectorType::get(ReqTy, VecTy->getNumElements());
+
+ unsigned NumVecElts = 0;
+ if (C->getType()->isVectorTy())
+ NumVecElts = C->getType()->getVectorNumElements();
+ else for (auto Idx : Idxs)
+ if (Idx->getType()->isVectorTy())
+ NumVecElts = Idx->getType()->getVectorNumElements();
+
+ if (NumVecElts)
+ ReqTy = VectorType::get(ReqTy, NumVecElts);
if (OnlyIfReducedTy == ReqTy)
return nullptr;
@@ -1990,13 +1928,14 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
ArgVec.reserve(1 + Idxs.size());
ArgVec.push_back(C);
for (unsigned i = 0, e = Idxs.size(); i != e; ++i) {
- assert(Idxs[i]->getType()->isVectorTy() == ReqTy->isVectorTy() &&
- "getelementptr index type missmatch");
assert((!Idxs[i]->getType()->isVectorTy() ||
- ReqTy->getVectorNumElements() ==
- Idxs[i]->getType()->getVectorNumElements()) &&
+ Idxs[i]->getType()->getVectorNumElements() == NumVecElts) &&
"getelementptr index type missmatch");
- ArgVec.push_back(cast<Constant>(Idxs[i]));
+
+ Constant *Idx = cast<Constant>(Idxs[i]);
+ if (NumVecElts && !Idxs[i]->getType()->isVectorTy())
+ Idx = ConstantVector::getSplat(NumVecElts, Idx);
+ ArgVec.push_back(Idx);
}
const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
InBounds ? GEPOperator::IsInBounds : 0, None,
@@ -2278,9 +2217,6 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
isExact ? PossiblyExactOperator::IsExact : 0);
}
-/// getBinOpIdentity - Return the identity for the given binary operation,
-/// i.e. a constant C such that X op C = X and C op X = X for every X. It
-/// returns null if the operator doesn't have an identity.
Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
switch (Opcode) {
default:
@@ -2300,10 +2236,6 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
}
}
-/// getBinOpAbsorber - Return the absorbing element for the given binary
-/// operation, i.e. a constant C such that X op C = C and C op X = C for
-/// every X. For example, this returns zero for integer multiplication.
-/// It returns null if the operator doesn't have an absorbing element.
Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
switch (Opcode) {
default:
@@ -2319,8 +2251,7 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
}
}
-// destroyConstant - Remove the constant from the constant table...
-//
+/// Remove the constant from the constant table.
void ConstantExpr::destroyConstantImpl() {
getType()->getContext().pImpl->ExprConstants.remove(this);
}
@@ -2335,7 +2266,8 @@ GetElementPtrConstantExpr::GetElementPtrConstantExpr(
OperandTraits<GetElementPtrConstantExpr>::op_end(this) -
(IdxList.size() + 1),
IdxList.size() + 1),
- SrcElementTy(SrcElementTy) {
+ SrcElementTy(SrcElementTy),
+ ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)) {
Op<0>() = C;
Use *OperandList = getOperandList();
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
@@ -2346,13 +2278,16 @@ Type *GetElementPtrConstantExpr::getSourceElementType() const {
return SrcElementTy;
}
+Type *GetElementPtrConstantExpr::getResultElementType() const {
+ return ResElementTy;
+}
+
//===----------------------------------------------------------------------===//
// ConstantData* implementations
void ConstantDataArray::anchor() {}
void ConstantDataVector::anchor() {}
-/// getElementType - Return the element type of the array/vector.
Type *ConstantDataSequential::getElementType() const {
return getType()->getElementType();
}
@@ -2361,10 +2296,6 @@ StringRef ConstantDataSequential::getRawDataValues() const {
return StringRef(DataElements, getNumElements()*getElementByteSize());
}
-/// isElementTypeCompatible - Return true if a ConstantDataSequential can be
-/// 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(Type *Ty) {
if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) return true;
if (auto *IT = dyn_cast<IntegerType>(Ty)) {
@@ -2380,7 +2311,6 @@ bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
return false;
}
-/// getNumElements - Return the number of elements in the array or vector.
unsigned ConstantDataSequential::getNumElements() const {
if (ArrayType *AT = dyn_cast<ArrayType>(getType()))
return AT->getNumElements();
@@ -2388,27 +2318,26 @@ unsigned ConstantDataSequential::getNumElements() const {
}
-/// getElementByteSize - Return the size in bytes of the elements in the data.
uint64_t ConstantDataSequential::getElementByteSize() const {
return getElementType()->getPrimitiveSizeInBits()/8;
}
-/// getElementPointer - Return the start of the specified element.
+/// Return the start of the specified element.
const char *ConstantDataSequential::getElementPointer(unsigned Elt) const {
assert(Elt < getNumElements() && "Invalid Elt");
return DataElements+Elt*getElementByteSize();
}
-/// isAllZeros - return true if the array is empty or all zeros.
+/// Return true if the array is empty or all zeros.
static bool isAllZeros(StringRef Arr) {
- for (StringRef::iterator I = Arr.begin(), E = Arr.end(); I != E; ++I)
- if (*I != 0)
+ for (char I : Arr)
+ if (I != 0)
return false;
return true;
}
-/// getImpl - This is the underlying implementation of all of the
+/// This is the underlying implementation of all of the
/// ConstantDataSequential::get methods. They all thunk down to here, providing
/// the correct element type. We take the bytes in as a StringRef because
/// we *want* an underlying "char*" to avoid TBAA type punning violations.
@@ -2539,11 +2468,6 @@ Constant *ConstantDataArray::getFP(LLVMContext &Context,
return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
}
-/// getString - This method constructs a CDS and initializes it with a text
-/// string. The default behavior (AddNull==true) causes a null terminator to
-/// be placed at the end of the array (increasing the length of the string by
-/// one more than the StringRef would normally indicate. Pass AddNull=false
-/// to disable this behavior.
Constant *ConstantDataArray::getString(LLVMContext &Context,
StringRef Str, bool AddNull) {
if (!AddNull) {
@@ -2658,8 +2582,6 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
}
-/// getElementAsInteger - If this is a sequential container of integers (of
-/// any size), return the specified element in the low bits of a uint64_t.
uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
assert(isa<IntegerType>(getElementType()) &&
"Accessor can only be used when element is an integer");
@@ -2680,8 +2602,6 @@ uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
}
}
-/// getElementAsAPFloat - If this is a sequential container of floating point
-/// type, return the specified element as an APFloat.
APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
const char *EltPtr = getElementPointer(Elt);
@@ -2703,8 +2623,6 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
}
}
-/// getElementAsFloat - If this is an sequential container of floats, return
-/// the specified element as a float.
float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
assert(getElementType()->isFloatTy() &&
"Accessor can only be used when element is a 'float'");
@@ -2712,8 +2630,6 @@ float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
return *const_cast<float *>(EltPtr);
}
-/// getElementAsDouble - If this is an sequential container of doubles, return
-/// the specified element as a float.
double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
assert(getElementType()->isDoubleTy() &&
"Accessor can only be used when element is a 'float'");
@@ -2722,9 +2638,6 @@ double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
return *const_cast<double *>(EltPtr);
}
-/// getElementAsConstant - Return a Constant for a specified index's element.
-/// Note that this has to compute a new constant to return, so it isn't as
-/// efficient as getElementAsInteger/Float/Double.
Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
if (getElementType()->isHalfTy() || getElementType()->isFloatTy() ||
getElementType()->isDoubleTy())
@@ -2733,13 +2646,10 @@ Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
}
-/// isString - This method returns true if this is an array of i8.
bool ConstantDataSequential::isString() const {
return isa<ArrayType>(getType()) && getElementType()->isIntegerTy(8);
}
-/// isCString - This method returns true if the array "isString", ends with a
-/// nul byte, and does not contains any other nul bytes.
bool ConstantDataSequential::isCString() const {
if (!isString())
return false;
@@ -2753,8 +2663,6 @@ bool ConstantDataSequential::isCString() const {
return Str.drop_back().find(0) == StringRef::npos;
}
-/// getSplatValue - If this is a splat constant, meaning that all of the
-/// elements have the same value, return that value. Otherwise return nullptr.
Constant *ConstantDataVector::getSplatValue() const {
const char *Base = getRawDataValues().data();
@@ -2782,14 +2690,14 @@ Constant *ConstantDataVector::getSplatValue() const {
/// work, but would be really slow because it would have to unique each updated
/// array instance.
///
-void Constant::handleOperandChange(Value *From, Value *To, Use *U) {
+void Constant::handleOperandChange(Value *From, Value *To) {
Value *Replacement = nullptr;
switch (getValueID()) {
default:
llvm_unreachable("Not a constant!");
#define HANDLE_CONSTANT(Name) \
case Value::Name##Val: \
- Replacement = cast<Name>(this)->handleOperandChangeImpl(From, To, U); \
+ Replacement = cast<Name>(this)->handleOperandChangeImpl(From, To); \
break;
#include "llvm/IR/Value.def"
}
@@ -2809,39 +2717,7 @@ void Constant::handleOperandChange(Value *From, Value *To, Use *U) {
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 *ConstantTokenNone::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) {
+Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
@@ -2855,9 +2731,11 @@ Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
// Keep track of whether all the values in the array are "ToC".
bool AllSame = true;
Use *OperandList = getOperandList();
+ unsigned OperandNo = 0;
for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
Constant *Val = cast<Constant>(O->get());
if (Val == From) {
+ OperandNo = (O - OperandList);
Val = ToC;
++NumUpdated;
}
@@ -2877,65 +2755,57 @@ Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
// Update to the new value.
return getContext().pImpl->ArrayConstants.replaceOperandsInPlace(
- Values, this, From, ToC, NumUpdated, U - OperandList);
+ Values, this, From, ToC, NumUpdated, OperandNo);
}
-Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
+Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
Use *OperandList = getOperandList();
- unsigned OperandToUpdate = U-OperandList;
- assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
SmallVector<Constant*, 8> Values;
Values.reserve(getNumOperands()); // Build replacement struct.
// Fill values with the modified operands of the constant struct. Also,
// compute whether this turns into an all-zeros struct.
- bool isAllZeros = false;
- bool isAllUndef = false;
- if (ToC->isNullValue()) {
- isAllZeros = true;
- for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
- Constant *Val = cast<Constant>(O->get());
- Values.push_back(Val);
- if (isAllZeros) isAllZeros = Val->isNullValue();
- }
- } else if (isa<UndefValue>(ToC)) {
- isAllUndef = true;
- for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
- Constant *Val = cast<Constant>(O->get());
- Values.push_back(Val);
- if (isAllUndef) isAllUndef = isa<UndefValue>(Val);
+ unsigned NumUpdated = 0;
+ bool AllSame = true;
+ unsigned OperandNo = 0;
+ for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) {
+ Constant *Val = cast<Constant>(O->get());
+ if (Val == From) {
+ OperandNo = (O - OperandList);
+ Val = ToC;
+ ++NumUpdated;
}
- } else {
- for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O)
- Values.push_back(cast<Constant>(O->get()));
+ Values.push_back(Val);
+ AllSame &= Val == ToC;
}
- Values[OperandToUpdate] = ToC;
- if (isAllZeros)
+ if (AllSame && ToC->isNullValue())
return ConstantAggregateZero::get(getType());
- if (isAllUndef)
+ if (AllSame && isa<UndefValue>(ToC))
return UndefValue::get(getType());
// Update to the new value.
return getContext().pImpl->StructConstants.replaceOperandsInPlace(
- Values, this, From, ToC);
+ Values, this, From, ToC, NumUpdated, OperandNo);
}
-Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
+Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To) {
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;
+ unsigned OperandNo = 0;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
Constant *Val = getOperand(i);
if (Val == From) {
+ OperandNo = i;
++NumUpdated;
Val = ToC;
}
@@ -2946,20 +2816,21 @@ Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To, Use *U) {
return C;
// Update to the new value.
- Use *OperandList = getOperandList();
return getContext().pImpl->VectorConstants.replaceOperandsInPlace(
- Values, this, From, ToC, NumUpdated, U - OperandList);
+ Values, this, From, ToC, NumUpdated, OperandNo);
}
-Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV, Use *U) {
+Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) {
assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");
Constant *To = cast<Constant>(ToV);
SmallVector<Constant*, 8> NewOps;
unsigned NumUpdated = 0;
+ unsigned OperandNo = 0;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
Constant *Op = getOperand(i);
if (Op == From) {
+ OperandNo = i;
++NumUpdated;
Op = To;
}
@@ -2971,9 +2842,8 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV, Use *U) {
return C;
// Update to the new value.
- Use *OperandList = getOperandList();
return getContext().pImpl->ExprConstants.replaceOperandsInPlace(
- NewOps, this, From, To, NumUpdated, U - OperandList);
+ NewOps, this, From, To, NumUpdated, OperandNo);
}
Instruction *ConstantExpr::getAsInstruction() {
OpenPOWER on IntegriCloud