[VPlan] Add VPValue::replaceUsesWithIf (NFCI).

Add replaceUsesWithIf helper and use it in a few places.
This commit is contained in:
Florian Hahn
2023-11-06 16:08:21 +00:00
parent 742d8eb96d
commit a002271972
3 changed files with 39 additions and 31 deletions

View File

@@ -1120,6 +1120,26 @@ void VPValue::replaceAllUsesWith(VPValue *New) {
}
}
void VPValue::replaceUsesWithIf(
VPValue *New,
llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace) {
for (unsigned J = 0; J < getNumUsers();) {
VPUser *User = Users[J];
unsigned NumUsers = getNumUsers();
for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
if (User->getOperand(I) != this || !ShouldReplace(*User, I))
continue;
User->setOperand(I, New);
}
// If a user got removed after updating the current user, the next user to
// update will be moved to the current position, so we only need to
// increment the index if the number of users did not change.
if (NumUsers == getNumUsers())
J++;
}
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void VPValue::printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const {
if (const Value *UV = getUnderlyingValue()) {

View File

@@ -162,17 +162,10 @@ static bool sinkScalarOperands(VPlan &Plan) {
// TODO: add ".cloned" suffix to name of Clone's VPValue.
Clone->insertBefore(SinkCandidate);
for (auto *U : to_vector(SinkCandidate->getVPSingleValue()->users())) {
auto *UI = cast<VPRecipeBase>(U);
if (UI->getParent() == SinkTo)
continue;
for (unsigned Idx = 0; Idx != UI->getNumOperands(); Idx++) {
if (UI->getOperand(Idx) != SinkCandidate->getVPSingleValue())
continue;
UI->setOperand(Idx, Clone);
}
}
SinkCandidate->getVPSingleValue()->replaceUsesWithIf(
Clone, [SinkTo](VPUser &U, unsigned) {
return cast<VPRecipeBase>(&U)->getParent() != SinkTo;
});
}
SinkCandidate->moveBefore(*SinkTo, SinkTo->getFirstNonPhi());
for (VPValue *Op : SinkCandidate->operands())
@@ -277,16 +270,10 @@ static bool mergeReplicateRegionsIntoSuccessors(VPlan &Plan) {
VPValue *PredInst1 =
cast<VPPredInstPHIRecipe>(&Phi1ToMove)->getOperand(0);
VPValue *Phi1ToMoveV = Phi1ToMove.getVPSingleValue();
for (VPUser *U : to_vector(Phi1ToMoveV->users())) {
auto *UI = dyn_cast<VPRecipeBase>(U);
if (!UI || UI->getParent() != Then2)
continue;
for (unsigned I = 0, E = U->getNumOperands(); I != E; ++I) {
if (Phi1ToMoveV != U->getOperand(I))
continue;
U->setOperand(I, PredInst1);
}
}
Phi1ToMoveV->replaceUsesWithIf(PredInst1, [Then2](VPUser &U, unsigned) {
auto *UI = dyn_cast<VPRecipeBase>(&U);
return UI && UI->getParent() == Then2;
});
Phi1ToMove.moveBefore(*Merge2, Merge2->begin());
}
@@ -542,16 +529,10 @@ void VPlanTransforms::optimizeInductions(VPlan &Plan, ScalarEvolution &SE) {
// Update scalar users of IV to use Step instead. Use SetVector to ensure
// the list of users doesn't contain duplicates.
SetVector<VPUser *> Users(WideIV->user_begin(), WideIV->user_end());
for (VPUser *U : Users) {
if (HasOnlyVectorVFs && !U->usesScalars(WideIV))
continue;
for (unsigned I = 0, E = U->getNumOperands(); I != E; I++) {
if (U->getOperand(I) != WideIV)
continue;
U->setOperand(I, Steps);
}
}
WideIV->replaceUsesWithIf(
Steps, [HasOnlyVectorVFs, WideIV](VPUser &U, unsigned) {
return !HasOnlyVectorVFs || U.usesScalars(WideIV);
});
}
}

View File

@@ -163,6 +163,13 @@ public:
void replaceAllUsesWith(VPValue *New);
/// Go through the uses list for this VPValue and make each use point to \p
/// New if the callback ShouldReplace returns true for the given use specified
/// by a pair of (VPUser, the use index).
void replaceUsesWithIf(
VPValue *New,
llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace);
/// Returns the recipe defining this VPValue or nullptr if it is not defined
/// by a recipe, i.e. is a live-in.
VPRecipeBase *getDefiningRecipe();