aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-03-20 11:40:34 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-05-14 11:43:05 +0000
commit349cc55c9796c4596a5b9904cd3281af295f878f (patch)
tree410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/llvm/lib/IR/Constants.cpp
parentcb2ae6163174b90e999326ecec3699ee093a5d43 (diff)
parentc0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/Constants.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Constants.cpp129
1 files changed, 71 insertions, 58 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/Constants.cpp b/contrib/llvm-project/llvm/lib/IR/Constants.cpp
index 1e72cb4d3a66..c66cfb6e9ac1 100644
--- a/contrib/llvm-project/llvm/lib/IR/Constants.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/Constants.cpp
@@ -95,7 +95,7 @@ bool Constant::isAllOnesValue() const {
// Check for FP which are bitcasted from -1 integers
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().bitcastToAPInt().isAllOnesValue();
+ return CFP->getValueAPF().bitcastToAPInt().isAllOnes();
// Check for constant splat vectors of 1 values.
if (getType()->isVectorTy())
@@ -112,7 +112,7 @@ bool Constant::isOneValue() const {
// Check for FP which are bitcasted from 1 integers
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return CFP->getValueAPF().bitcastToAPInt().isOneValue();
+ return CFP->getValueAPF().bitcastToAPInt().isOne();
// Check for constant splat vectors of 1 values.
if (getType()->isVectorTy())
@@ -129,7 +129,7 @@ bool Constant::isNotOneValue() const {
// Check for FP which are bitcasted from 1 integers
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
- return !CFP->getValueAPF().bitcastToAPInt().isOneValue();
+ return !CFP->getValueAPF().bitcastToAPInt().isOne();
// Check that vectors don't contain 1
if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
@@ -368,9 +368,8 @@ Constant *Constant::getNullValue(Type *Ty) {
return ConstantFP::get(Ty->getContext(),
APFloat::getZero(APFloat::IEEEquad()));
case Type::PPC_FP128TyID:
- return ConstantFP::get(Ty->getContext(),
- APFloat(APFloat::PPCDoubleDouble(),
- APInt::getNullValue(128)));
+ return ConstantFP::get(Ty->getContext(), APFloat(APFloat::PPCDoubleDouble(),
+ APInt::getZero(128)));
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
@@ -406,11 +405,10 @@ Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) {
Constant *Constant::getAllOnesValue(Type *Ty) {
if (IntegerType *ITy = dyn_cast<IntegerType>(Ty))
return ConstantInt::get(Ty->getContext(),
- APInt::getAllOnesValue(ITy->getBitWidth()));
+ APInt::getAllOnes(ITy->getBitWidth()));
if (Ty->isFloatingPointTy()) {
- APFloat FL = APFloat::getAllOnesValue(Ty->getFltSemantics(),
- Ty->getPrimitiveSizeInBits());
+ APFloat FL = APFloat::getAllOnesValue(Ty->getFltSemantics());
return ConstantFP::get(Ty->getContext(), FL);
}
@@ -716,29 +714,41 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
return Result;
}
-/// If the specified constantexpr is dead, remove it. This involves recursively
-/// eliminating any dead users of the constantexpr.
-static bool removeDeadUsersOfConstant(const Constant *C) {
+/// Return true if the specified constantexpr is dead. This involves
+/// recursively traversing users of the constantexpr.
+/// If RemoveDeadUsers is true, also remove dead users at the same time.
+static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) {
if (isa<GlobalValue>(C)) return false; // Cannot remove this
- while (!C->use_empty()) {
- const Constant *User = dyn_cast<Constant>(C->user_back());
+ Value::const_user_iterator I = C->user_begin(), E = C->user_end();
+ while (I != E) {
+ const Constant *User = dyn_cast<Constant>(*I);
if (!User) return false; // Non-constant usage;
- if (!removeDeadUsersOfConstant(User))
+ if (!constantIsDead(User, RemoveDeadUsers))
return false; // Constant wasn't dead
+
+ // Just removed User, so the iterator was invalidated.
+ // Since we return immediately upon finding a live user, we can always
+ // restart from user_begin().
+ if (RemoveDeadUsers)
+ I = C->user_begin();
+ else
+ ++I;
}
- // If C is only used by metadata, it should not be preserved but should have
- // its uses replaced.
- if (C->isUsedByMetadata()) {
- const_cast<Constant *>(C)->replaceAllUsesWith(
- UndefValue::get(C->getType()));
+ if (RemoveDeadUsers) {
+ // If C is only used by metadata, it should not be preserved but should
+ // have its uses replaced.
+ if (C->isUsedByMetadata()) {
+ const_cast<Constant *>(C)->replaceAllUsesWith(
+ UndefValue::get(C->getType()));
+ }
+ const_cast<Constant *>(C)->destroyConstant();
}
- const_cast<Constant*>(C)->destroyConstant();
+
return true;
}
-
void Constant::removeDeadConstantUsers() const {
Value::const_user_iterator I = user_begin(), E = user_end();
Value::const_user_iterator LastNonDeadUser = E;
@@ -750,7 +760,7 @@ void Constant::removeDeadConstantUsers() const {
continue;
}
- if (!removeDeadUsersOfConstant(User)) {
+ if (!constantIsDead(User, /* RemoveDeadUsers= */ true)) {
// If the constant wasn't dead, remember that this was the last live use
// and move on to the next constant.
LastNonDeadUser = I;
@@ -766,6 +776,20 @@ void Constant::removeDeadConstantUsers() const {
}
}
+bool Constant::hasOneLiveUse() const {
+ unsigned NumUses = 0;
+ for (const Use &use : uses()) {
+ const Constant *User = dyn_cast<Constant>(use.getUser());
+ if (!User || !constantIsDead(User, /* RemoveDeadUsers= */ false)) {
+ ++NumUses;
+
+ if (NumUses > 1)
+ return false;
+ }
+ }
+ return NumUses == 1;
+}
+
Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {
assert(C && Replacement && "Expected non-nullptr constant arguments");
Type *Ty = C->getType();
@@ -1432,12 +1456,12 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
Type *I32Ty = Type::getInt32Ty(VTy->getContext());
// Move scalar into vector.
- Constant *UndefV = UndefValue::get(VTy);
- V = ConstantExpr::getInsertElement(UndefV, V, ConstantInt::get(I32Ty, 0));
+ Constant *PoisonV = PoisonValue::get(VTy);
+ V = ConstantExpr::getInsertElement(PoisonV, V, ConstantInt::get(I32Ty, 0));
// Build shuffle mask to perform the splat.
SmallVector<int, 8> Zeros(EC.getKnownMinValue(), 0);
// Splat.
- return ConstantExpr::getShuffleVector(V, UndefV, Zeros);
+ return ConstantExpr::getShuffleVector(V, PoisonV, Zeros);
}
ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {
@@ -1510,20 +1534,6 @@ Constant *ConstantExpr::getShuffleMaskForBitcode() const {
return cast<ShuffleVectorConstantExpr>(this)->ShuffleMaskForBitcode;
}
-Constant *
-ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
- assert(Op->getType() == getOperand(OpNo)->getType() &&
- "Replacing operand with value of different type!");
- if (getOperand(OpNo) == Op)
- return const_cast<ConstantExpr*>(this);
-
- SmallVector<Constant*, 8> NewOps;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- NewOps.push_back(i == OpNo ? Op : getOperand(i));
-
- return getWithOperands(NewOps);
-}
-
Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
bool OnlyIfReduced, Type *SrcTy) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
@@ -3284,7 +3294,7 @@ bool ConstantDataSequential::isCString() const {
if (Str.back() != 0) return false;
// Other elements must be non-nul.
- return Str.drop_back().find(0) == StringRef::npos;
+ return !Str.drop_back().contains(0);
}
bool ConstantDataVector::isSplatData() const {
@@ -3482,7 +3492,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) {
NewOps, this, From, To, NumUpdated, OperandNo);
}
-Instruction *ConstantExpr::getAsInstruction() const {
+Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const {
SmallVector<Value *, 4> ValueOperands(operands());
ArrayRef<Value*> Ops(ValueOperands);
@@ -3500,40 +3510,43 @@ Instruction *ConstantExpr::getAsInstruction() const {
case Instruction::IntToPtr:
case Instruction::BitCast:
case Instruction::AddrSpaceCast:
- return CastInst::Create((Instruction::CastOps)getOpcode(),
- Ops[0], getType());
+ return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0],
+ getType(), "", InsertBefore);
case Instruction::Select:
- return SelectInst::Create(Ops[0], Ops[1], Ops[2]);
+ return SelectInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
case Instruction::InsertElement:
- return InsertElementInst::Create(Ops[0], Ops[1], Ops[2]);
+ return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
case Instruction::ExtractElement:
- return ExtractElementInst::Create(Ops[0], Ops[1]);
+ return ExtractElementInst::Create(Ops[0], Ops[1], "", InsertBefore);
case Instruction::InsertValue:
- return InsertValueInst::Create(Ops[0], Ops[1], getIndices());
+ return InsertValueInst::Create(Ops[0], Ops[1], getIndices(), "",
+ InsertBefore);
case Instruction::ExtractValue:
- return ExtractValueInst::Create(Ops[0], getIndices());
+ return ExtractValueInst::Create(Ops[0], getIndices(), "", InsertBefore);
case Instruction::ShuffleVector:
- return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask());
+ return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "",
+ InsertBefore);
case Instruction::GetElementPtr: {
const auto *GO = cast<GEPOperator>(this);
if (GO->isInBounds())
- return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(),
- Ops[0], Ops.slice(1));
+ return GetElementPtrInst::CreateInBounds(
+ GO->getSourceElementType(), Ops[0], Ops.slice(1), "", InsertBefore);
return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
- Ops.slice(1));
+ Ops.slice(1), "", InsertBefore);
}
case Instruction::ICmp:
case Instruction::FCmp:
return CmpInst::Create((Instruction::OtherOps)getOpcode(),
- (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1]);
+ (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1],
+ "", InsertBefore);
case Instruction::FNeg:
- return UnaryOperator::Create((Instruction::UnaryOps)getOpcode(), Ops[0]);
+ return UnaryOperator::Create((Instruction::UnaryOps)getOpcode(), Ops[0], "",
+ InsertBefore);
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
- BinaryOperator *BO =
- BinaryOperator::Create((Instruction::BinaryOps)getOpcode(),
- Ops[0], Ops[1]);
+ BinaryOperator *BO = BinaryOperator::Create(
+ (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], "", InsertBefore);
if (isa<OverflowingBinaryOperator>(BO)) {
BO->setHasNoUnsignedWrap(SubclassOptionalData &
OverflowingBinaryOperator::NoUnsignedWrap);