diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 6629208139c3e..2f9703cec0dda 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -4207,7 +4207,7 @@ VectorizationFactor LoopVectorizationPlanner::selectVectorizationFactor() { // divisors. case Instruction::Select: { VPValue *VPV = VPI->getVPSingleValue(); - if (VPV->getNumUsers() == 1) { + if (VPV->getNumUses() == 1) { if (auto *WR = dyn_cast(*VPV->user_begin())) { switch (WR->getOpcode()) { case Instruction::UDiv: diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 334dc9e20c58f..46f4d1bbe53af 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -1056,25 +1056,25 @@ const VPRegionBlock *VPlan::getVectorLoopRegion() const { void VPlan::printLiveIns(raw_ostream &O) const { VPSlotTracker SlotTracker(this); - if (VF.getNumUsers() > 0) { + if (VF.getNumUses() > 0) { O << "\nLive-in "; VF.printAsOperand(O, SlotTracker); O << " = VF"; } - if (VFxUF.getNumUsers() > 0) { + if (VFxUF.getNumUses() > 0) { O << "\nLive-in "; VFxUF.printAsOperand(O, SlotTracker); O << " = VF * UF"; } - if (VectorTripCount.getNumUsers() > 0) { + if (VectorTripCount.getNumUses() > 0) { O << "\nLive-in "; VectorTripCount.printAsOperand(O, SlotTracker); O << " = vector-trip-count"; } - if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) { + if (BackedgeTakenCount && BackedgeTakenCount->getNumUses()) { O << "\nLive-in "; BackedgeTakenCount->printAsOperand(O, SlotTracker); O << " = backedge-taken count"; @@ -1416,7 +1416,7 @@ void VPValue::replaceUsesWithIf( if (this == New) return; - for (unsigned J = 0; J < getNumUsers();) { + for (unsigned J = 0; J < getNumUses();) { VPUser *User = Users[J]; bool RemovedUser = false; for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) { @@ -1492,9 +1492,9 @@ void VPSlotTracker::assignName(const VPValue *V) { } void VPSlotTracker::assignNames(const VPlan &Plan) { - if (Plan.VF.getNumUsers() > 0) + if (Plan.VF.getNumUses() > 0) assignName(&Plan.VF); - if (Plan.VFxUF.getNumUsers() > 0) + if (Plan.VFxUF.getNumUses() > 0) assignName(&Plan.VFxUF); assignName(&Plan.VectorTripCount); if (Plan.BackedgeTakenCount) diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 255ec8a950315..53b3cdf6b7e95 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -4204,7 +4204,7 @@ class VPlan { /// Resets the trip count for the VPlan. The caller must make sure all uses of /// the original trip count have been replaced. void resetTripCount(VPValue *NewTripCount) { - assert(TripCount && NewTripCount && TripCount->getNumUsers() == 0 && + assert(TripCount && NewTripCount && TripCount->getNumUses() == 0 && "TripCount must be set when resetting"); TripCount = NewTripCount; } diff --git a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp index c1c525ee23122..225dd40bba017 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp @@ -885,7 +885,7 @@ bool VPlanTransforms::handleMaxMinNumReductions(VPlan &Plan) { if (VecV == RdxResult) continue; if (auto *DerivedIV = dyn_cast(VecV)) { - if (DerivedIV->getNumUsers() == 1 && + if (DerivedIV->getNumUses() == 1 && DerivedIV->getOperand(1) == &Plan.getVectorTripCount()) { auto *NewSel = Builder.createSelect(AnyNaN, Plan.getCanonicalIV(), &Plan.getVectorTripCount()); diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 5f3503d0ce57a..c46ed0768d3fc 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -2249,7 +2249,7 @@ InstructionCost VPWidenCastRecipe::computeCost(ElementCount VF, TTI::CastContextHint CCH = TTI::CastContextHint::None; // For Trunc/FPTrunc, get the context from the only user. if ((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) && - !hasMoreThanOneUniqueUser() && getNumUsers() > 0) { + !hasMoreThanOneUniqueUser() && getNumUses() > 0) { if (auto *StoreRecipe = dyn_cast(*user_begin())) CCH = ComputeCCH(StoreRecipe); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 6e2d85a5d06d8..a5f28f14a1f17 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -316,7 +316,7 @@ static bool mergeReplicateRegionsIntoSuccessors(VPlan &Plan) { }); // Remove phi recipes that are unused after merging the regions. - if (Phi1ToMove.getVPSingleValue()->getNumUsers() == 0) { + if (Phi1ToMove.getVPSingleValue()->getNumUses() == 0) { Phi1ToMove.eraseFromParent(); continue; } @@ -363,7 +363,7 @@ static VPRegionBlock *createReplicateRegion(VPReplicateRecipe *PredRecipe, Plan.createVPBasicBlock(Twine(RegionName) + ".if", RecipeWithoutMask); VPPredInstPHIRecipe *PHIRecipe = nullptr; - if (PredRecipe->getNumUsers() != 0) { + if (PredRecipe->getNumUses() != 0) { PHIRecipe = new VPPredInstPHIRecipe(RecipeWithoutMask, RecipeWithoutMask->getDebugLoc()); PredRecipe->replaceAllUsesWith(PHIRecipe); @@ -547,7 +547,7 @@ static bool isDeadRecipe(VPRecipeBase &R) { // Recipe is dead if no user keeps the recipe alive. return all_of(R.definedValues(), - [](VPValue *V) { return V->getNumUsers() == 0; }); + [](VPValue *V) { return V->getNumUses() == 0; }); } void VPlanTransforms::removeDeadRecipes(VPlan &Plan) { @@ -563,11 +563,11 @@ void VPlanTransforms::removeDeadRecipes(VPlan &Plan) { // Check if R is a dead VPPhi <-> update cycle and remove it. auto *PhiR = dyn_cast(&R); - if (!PhiR || PhiR->getNumOperands() != 2 || PhiR->getNumUsers() != 1) + if (!PhiR || PhiR->getNumOperands() != 2 || PhiR->getNumUses() != 1) continue; VPValue *Incoming = PhiR->getOperand(1); if (*PhiR->user_begin() != Incoming->getDefiningRecipe() || - Incoming->getNumUsers() != 1) + Incoming->getNumUses() != 1) continue; PhiR->replaceAllUsesWith(PhiR->getOperand(0)); PhiR->eraseFromParent(); @@ -658,7 +658,7 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) { auto *RepR = dyn_cast(U); // Skip recipes that shouldn't be narrowed. if (!Def || !isa(Def) || - Def->getNumUsers() == 0 || !Def->getUnderlyingValue() || + Def->getNumUses() == 0 || !Def->getUnderlyingValue() || (RepR && (RepR->isSingleScalar() || RepR->isPredicated()))) continue; @@ -1344,7 +1344,7 @@ static void simplifyBlends(VPlan &Plan) { // TODO: Find the most expensive mask that can be deadcoded, or a mask // that's used by multiple blends where it can be removed from them all. VPValue *Mask = Blend->getMask(I); - if (Mask->getNumUsers() == 1 && !match(Mask, m_False())) { + if (Mask->getNumUses() == 1 && !match(Mask, m_False())) { StartIndex = I; break; } @@ -1380,7 +1380,7 @@ static void simplifyBlends(VPlan &Plan) { NewBlend->setOperand(0, Inc1); NewBlend->setOperand(1, Inc0); NewBlend->setOperand(2, NewMask); - if (OldMask->getNumUsers() == 0) + if (OldMask->getNumUses() == 0) cast(OldMask)->eraseFromParent(); } } @@ -2467,7 +2467,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) { ToErase.push_back(CurRecipe); } // Remove dead EVL mask. - if (EVLMask->getNumUsers() == 0) + if (EVLMask->getNumUses() == 0) ToErase.push_back(EVLMask->getDefiningRecipe()); for (VPRecipeBase *R : reverse(ToErase)) { @@ -3445,7 +3445,7 @@ void VPlanTransforms::materializeBroadcasts(VPlan &Plan) { #endif SmallVector VPValues; - if (Plan.getOrCreateBackedgeTakenCount()->getNumUsers() > 0) + if (Plan.getOrCreateBackedgeTakenCount()->getNumUses() > 0) VPValues.push_back(Plan.getOrCreateBackedgeTakenCount()); append_range(VPValues, Plan.getLiveIns()); for (VPRecipeBase &R : *Plan.getEntry()) @@ -3514,7 +3514,7 @@ void VPlanTransforms::materializeConstantVectorTripCount( void VPlanTransforms::materializeBackedgeTakenCount(VPlan &Plan, VPBasicBlock *VectorPH) { VPValue *BTC = Plan.getOrCreateBackedgeTakenCount(); - if (BTC->getNumUsers() == 0) + if (BTC->getNumUses() == 0) return; VPBuilder Builder(VectorPH, VectorPH->begin()); @@ -3580,7 +3580,7 @@ void VPlanTransforms::materializeVectorTripCount(VPlan &Plan, assert(VectorTC.isLiveIn() && "vector-trip-count must be a live-in"); // There's nothing to do if there are no users of the vector trip count or its // IR value has already been set. - if (VectorTC.getNumUsers() == 0 || VectorTC.getLiveInIRValue()) + if (VectorTC.getNumUses() == 0 || VectorTC.getLiveInIRValue()) return; VPValue *TC = Plan.getTripCount(); @@ -3645,7 +3645,7 @@ void VPlanTransforms::materializeVFAndVFxUF(VPlan &Plan, VPBasicBlock *VectorPH, // If there are no users of the runtime VF, compute VFxUF by constant folding // the multiplication of VF and UF. - if (VF.getNumUsers() == 0) { + if (VF.getNumUses() == 0) { VPValue *RuntimeVFxUF = Builder.createElementCount(TCTy, VFEC * Plan.getUF()); VFxUF.replaceAllUsesWith(RuntimeVFxUF); diff --git a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp index 7a63d20825a31..ee05d5287d9e6 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp @@ -535,7 +535,7 @@ void VPlanTransforms::replicateByVF(VPlan &Plan, ElementCount VF) { continue; VPBuilder Builder(RepR); - if (RepR->getNumUsers() == 0) { + if (RepR->getNumUses() == 0) { if (isa(RepR->getUnderlyingInstr()) && vputils::isSingleScalar(RepR->getOperand(1))) { // Stores to invariant addresses need to store the last lane only. diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h index 85c6c2c8d7965..01dd2cbf7ba67 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanValue.h +++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h @@ -110,13 +110,18 @@ class LLVM_ABI_FOR_TEST VPValue { void dump() const; #endif - unsigned getNumUsers() const { return Users.size(); } + /// Returns the number of uses of this VPValue. The same user could appear + /// more than once in the list due to this value being used for multiple + /// operands in a recipe. + unsigned getNumUses() const { return Users.size(); } + + /// Adds a user of this value to the list. void addUser(VPUser &User) { Users.push_back(&User); } - /// Remove a single \p User from the list of users. - void removeUser(VPUser &User) { + /// Remove the first instance of \p User from the list of uses. + void removeFirstUse(VPUser &User) { // The same user can be added multiple times, e.g. because the same VPValue - // is used twice by the same VPUser. Remove a single one. + // is used twice by the same VPUser. Remove the first one. auto *I = find(Users, &User); if (I != Users.end()) Users.erase(I); @@ -138,7 +143,7 @@ class LLVM_ABI_FOR_TEST VPValue { /// Returns true if the value has more than one unique user. bool hasMoreThanOneUniqueUser() const { - if (getNumUsers() == 0) + if (getNumUses() == 0) return false; // Check if all users match the first user. @@ -203,7 +208,7 @@ class VPUser { /// Removes the operand at index \p Idx. This also removes the VPUser from the /// use-list of the operand. void removeOperand(unsigned Idx) { - getOperand(Idx)->removeUser(*this); + getOperand(Idx)->removeFirstUse(*this); Operands.erase(Operands.begin() + Idx); } @@ -224,7 +229,7 @@ class VPUser { VPUser &operator=(const VPUser &) = delete; virtual ~VPUser() { for (VPValue *Op : operands()) - Op->removeUser(*this); + Op->removeFirstUse(*this); } void addOperand(VPValue *Operand) { @@ -239,7 +244,7 @@ class VPUser { } void setOperand(unsigned I, VPValue *New) { - Operands[I]->removeUser(*this); + Operands[I]->removeFirstUse(*this); Operands[I] = New; New->addUser(*this); } @@ -383,7 +388,7 @@ class VPDef { for (VPValue *D : make_early_inc_range(DefinedValues)) { assert(D->Def == this && "all defined VPValues should point to the containing VPDef"); - assert(D->getNumUsers() == 0 && + assert(D->getNumUses() == 0 && "all defined VPValues should have no more users"); D->Def = nullptr; delete D; diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 99f3bc367a548..89580c37fe9d6 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -198,8 +198,8 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const { } // EVLIVIncrement is only used by EVLIV & BranchOnCount. // Having more than two users is unexpected. - if ((I->getNumUsers() != 1) && - (I->getNumUsers() != 2 || none_of(I->users(), [&I](VPUser *U) { + if ((I->getNumUses() != 1) && + (I->getNumUses() != 2 || none_of(I->users(), [&I](VPUser *U) { using namespace llvm::VPlanPatternMatch; return match(U, m_BranchOnCount(m_Specific(I), m_VPValue())); }))) { diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index db64c755d005f..acd33a555f942 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -137,38 +137,38 @@ TEST_F(VPInstructionTest, setOperand) { VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2}); - EXPECT_EQ(1u, VPV1->getNumUsers()); + EXPECT_EQ(1u, VPV1->getNumUses()); EXPECT_EQ(I1, *VPV1->user_begin()); - EXPECT_EQ(1u, VPV2->getNumUsers()); + EXPECT_EQ(1u, VPV2->getNumUses()); EXPECT_EQ(I1, *VPV2->user_begin()); // Replace operand 0 (VPV1) with VPV3. VPValue *VPV3 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3)); I1->setOperand(0, VPV3); - EXPECT_EQ(0u, VPV1->getNumUsers()); - EXPECT_EQ(1u, VPV2->getNumUsers()); + EXPECT_EQ(0u, VPV1->getNumUses()); + EXPECT_EQ(1u, VPV2->getNumUses()); EXPECT_EQ(I1, *VPV2->user_begin()); - EXPECT_EQ(1u, VPV3->getNumUsers()); + EXPECT_EQ(1u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV3->user_begin()); // Replace operand 1 (VPV2) with VPV3. I1->setOperand(1, VPV3); - EXPECT_EQ(0u, VPV1->getNumUsers()); - EXPECT_EQ(0u, VPV2->getNumUsers()); - EXPECT_EQ(2u, VPV3->getNumUsers()); + EXPECT_EQ(0u, VPV1->getNumUses()); + EXPECT_EQ(0u, VPV2->getNumUses()); + EXPECT_EQ(2u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV3->user_begin()); EXPECT_EQ(I1, *std::next(VPV3->user_begin())); // Replace operand 0 (VPV3) with VPV4. VPValue *VPV4 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 4)); I1->setOperand(0, VPV4); - EXPECT_EQ(1u, VPV3->getNumUsers()); + EXPECT_EQ(1u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV3->user_begin()); EXPECT_EQ(I1, *VPV4->user_begin()); // Replace operand 1 (VPV3) with VPV4. I1->setOperand(1, VPV4); - EXPECT_EQ(0u, VPV3->getNumUsers()); + EXPECT_EQ(0u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV4->user_begin()); EXPECT_EQ(I1, *std::next(VPV4->user_begin())); @@ -186,34 +186,34 @@ TEST_F(VPInstructionTest, replaceAllUsesWith) { VPV1->replaceAllUsesWith(VPV3); EXPECT_EQ(VPV3, I1->getOperand(0)); EXPECT_EQ(VPV2, I1->getOperand(1)); - EXPECT_EQ(0u, VPV1->getNumUsers()); - EXPECT_EQ(1u, VPV2->getNumUsers()); + EXPECT_EQ(0u, VPV1->getNumUses()); + EXPECT_EQ(1u, VPV2->getNumUses()); EXPECT_EQ(I1, *VPV2->user_begin()); - EXPECT_EQ(1u, VPV3->getNumUsers()); + EXPECT_EQ(1u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV3->user_begin()); // Replace all uses of VPV2 with VPV3. VPV2->replaceAllUsesWith(VPV3); EXPECT_EQ(VPV3, I1->getOperand(0)); EXPECT_EQ(VPV3, I1->getOperand(1)); - EXPECT_EQ(0u, VPV1->getNumUsers()); - EXPECT_EQ(0u, VPV2->getNumUsers()); - EXPECT_EQ(2u, VPV3->getNumUsers()); + EXPECT_EQ(0u, VPV1->getNumUses()); + EXPECT_EQ(0u, VPV2->getNumUses()); + EXPECT_EQ(2u, VPV3->getNumUses()); EXPECT_EQ(I1, *VPV3->user_begin()); // Replace all uses of VPV3 with VPV1. VPV3->replaceAllUsesWith(VPV1); EXPECT_EQ(VPV1, I1->getOperand(0)); EXPECT_EQ(VPV1, I1->getOperand(1)); - EXPECT_EQ(2u, VPV1->getNumUsers()); + EXPECT_EQ(2u, VPV1->getNumUses()); EXPECT_EQ(I1, *VPV1->user_begin()); - EXPECT_EQ(0u, VPV2->getNumUsers()); - EXPECT_EQ(0u, VPV3->getNumUsers()); + EXPECT_EQ(0u, VPV2->getNumUses()); + EXPECT_EQ(0u, VPV3->getNumUses()); VPInstruction *I2 = new VPInstruction(0, {VPV1, VPV2}); - EXPECT_EQ(3u, VPV1->getNumUsers()); + EXPECT_EQ(3u, VPV1->getNumUses()); VPV1->replaceAllUsesWith(VPV3); - EXPECT_EQ(3u, VPV3->getNumUsers()); + EXPECT_EQ(3u, VPV3->getNumUses()); delete I1; delete I2; @@ -225,15 +225,15 @@ TEST_F(VPInstructionTest, releaseOperandsAtDeletion) { VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2}); - EXPECT_EQ(1u, VPV1->getNumUsers()); + EXPECT_EQ(1u, VPV1->getNumUses()); EXPECT_EQ(I1, *VPV1->user_begin()); - EXPECT_EQ(1u, VPV2->getNumUsers()); + EXPECT_EQ(1u, VPV2->getNumUses()); EXPECT_EQ(I1, *VPV2->user_begin()); delete I1; - EXPECT_EQ(0u, VPV1->getNumUsers()); - EXPECT_EQ(0u, VPV2->getNumUsers()); + EXPECT_EQ(0u, VPV1->getNumUses()); + EXPECT_EQ(0u, VPV2->getNumUses()); } using VPBasicBlockTest = VPlanTestBase;