[llvm] [VPlan] Try to hoist Previous (and operands), if sinking fails for FORs. (PR #108945)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 08:13:15 PDT 2024
================
@@ -772,6 +772,97 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
return true;
}
+/// Try to hoist \p Previous and its operands before all users of \p FOR.
+static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
+ VPRecipeBase *Previous,
+ VPDominatorTree &VPDT) {
+ using namespace llvm::VPlanPatternMatch;
+ if (Previous->mayHaveSideEffects() || Previous->mayReadFromMemory())
+ return false;
+
+ // Collect recipes that need hoisting.
+ SmallVector<VPRecipeBase *> HoistCandidates;
+ SmallPtrSet<VPRecipeBase *, 8> Seen;
+ VPRecipeBase *HoistPoint = nullptr;
+ // Find the closest hoist point by looking at all users of FOR and selecting
+ // the recipe dominating all other users.
+ for (VPUser *U : FOR->users()) {
+ auto *R = dyn_cast<VPRecipeBase>(U);
+ if (!R)
+ continue;
+ if (!HoistPoint || VPDT.properlyDominates(R, HoistPoint))
+ HoistPoint = R;
+ }
+
+ auto NeedsHoisting = [HoistPoint, &VPDT,
+ &Seen](VPValue *HoistCandidateV) -> VPRecipeBase * {
+ VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
+ if (!HoistCandidate)
+ return nullptr;
+ assert((!HoistCandidate->getParent()->getParent() ||
+ HoistCandidate->getParent()->getParent() ==
+ HoistCandidate->getParent()->getEnclosingLoopRegion()) &&
+ "CFG in VPlan should still be flattened, without replicate regions");
+ // Hoist candidate has already beend visited, no need to hoist.
+ if (!Seen.insert(HoistCandidate).second)
+ return nullptr;
+
+ // Candidate is outside loop region or a header phi, dominates FOR users w/o
+ // hoisting.
+ if (!HoistCandidate->getParent()->getEnclosingLoopRegion() ||
+ isa<VPHeaderPHIRecipe>(HoistCandidate))
+ return nullptr;
+
+ // If we reached a recipe that dominates HoistPoint, we don't need to
+ // hoist the recipe.
+ if (VPDT.properlyDominates(HoistCandidate, HoistPoint))
+ return nullptr;
+ return HoistCandidate;
+ };
+ auto CanHoist = [&](VPRecipeBase *HoistCandidate) {
+ // Avoid hoisting candidates with side-effects, as we do not yet analyze
+ // associated dependencies.
+ return !HoistCandidate->mayHaveSideEffects();
+ };
+
+ // Recursively try to hoist Previous and its operands before all users of FOR.
+ if (NeedsHoisting(Previous->getVPSingleValue()))
----------------
ayalz wrote:
nit: can early-exit if Previous need not be hoisted.
https://github.com/llvm/llvm-project/pull/108945
More information about the llvm-commits
mailing list