diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/llvm/lib/IR/Constants.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/Constants.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/Constants.cpp | 129 |
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); |