https://github.com/madhur13490 updated https://github.com/llvm/llvm-project/pull/222614
>From 4c198247fdb0c3749f6a1b5dd51a442775c988aa Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar <[email protected]> Date: Thu, 10 Sep 2026 04:21:05 -0700 Subject: [PATCH] [SLP][modularisation][NFC] Move loop trip-count helpers to SLPUtils Move the BoUpSLP-independent helpers findInnermostNonInvariantLoop and getLoopTripCount out of SLPVectorizer.cpp into the self-contained SLPVectorizer/SLPUtils.{h,cpp} module. getLoopTripCount reads the file-local LoopAwareTripCount cl::opt, which stays static in SLPVectorizer.cpp and is passed to the moved helper as an explicit parameter. NFC. Part of the SLPVectorizer.cpp modularization effort: https://discourse.llvm.org/t/modularizing-slpvectorizer-cpp/90922 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 35 ++----------------- .../Vectorize/SLPVectorizer/SLPUtils.cpp | 32 +++++++++++++++++ .../Vectorize/SLPVectorizer/SLPUtils.h | 11 ++++++ 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 0ee63c3e27618..b5ba7cbb0823f 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -9368,20 +9368,6 @@ static bool isPoorThroughputOp(Instruction *I, const TargetTransformInfo &TTI, [&] { Cache.CheapOpcodes.insert(Key); }); } -/// Find the innermost loop starting from \p L, for which at least a single -/// value in \p VL is not invariant. -static const Loop *findInnermostNonInvariantLoop(const Loop *L, - ArrayRef<Value *> VL) { - assert(L && "Expected valid loop"); - auto IsLoopInvariant = [&](const Loop *L, ArrayRef<Value *> VL) { - return all_of(make_isa_range<Instruction>(VL), - [L](Instruction *I) { return L->isLoopInvariant(I); }); - }; - while (L && IsLoopInvariant(L, VL)) - L = L->getParentLoop(); - return L; -} - /// Get the loop nest for the given loop. ArrayRef<const Loop *> BoUpSLP::getLoopNest(const Loop *L) { assert(L && "Expected valid loop"); @@ -16209,24 +16195,6 @@ TTI::CastContextHint BoUpSLP::getCastContextHint(const TreeEntry &TE) const { return TTI::CastContextHint::None; } -/// Get the assumed loop trip count for the loop \p L. -static unsigned getLoopTripCount(const Loop *L, ScalarEvolution &SE) { - if (LoopAwareTripCount == 0) - return 1; - unsigned Scale = SE.getSmallConstantTripCount(L); - if (Scale == 0) - Scale = getLoopEstimatedTripCount(const_cast<Loop *>(L)).value_or(0); - if (Scale != 0) { - // Multiple exiting blocks - choose the minimum between trip count (scale) - // and LoopAwareTripCount, since the multiple exit loops can be terminated - // early. - if (!L->getExitingBlock()) - return std::min<unsigned>(LoopAwareTripCount, Scale); - return Scale; - } - return LoopAwareTripCount; -} - uint64_t BoUpSLP::getScaleToLoopIterations(const TreeEntry &TE, Value *Scalar, Instruction *U) { BasicBlock *Parent = nullptr; @@ -16328,7 +16296,8 @@ uint64_t BoUpSLP::getLoopNestScale(const Loop *L) { // Use SaturatingMultiply to clamp at uint64_t max on deep/large nests // rather than wrapping around. for (const Loop *Cur : reverse(Chain)) { - uint64_t TC = std::max<uint64_t>(1, getLoopTripCount(Cur, *SE)); + uint64_t TC = + std::max<uint64_t>(1, getLoopTripCount(Cur, *SE, LoopAwareTripCount)); Scale = SaturatingMultiply(Scale, TC); LoopNestScaleCache.try_emplace(Cur, std::max<uint64_t>(1, Scale)); } diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp index 7872d039176c6..e83ec4da9de6b 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp @@ -13,6 +13,8 @@ #include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/Constants.h" @@ -27,6 +29,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/LoopUtils.h" #include <algorithm> #include <numeric> @@ -1594,4 +1597,33 @@ std::optional<unsigned> getAggregateSize(Instruction *InsertInst) { } while (true); } +const Loop *findInnermostNonInvariantLoop(const Loop *L, ArrayRef<Value *> VL) { + assert(L && "Expected valid loop"); + auto IsLoopInvariant = [&](const Loop *L, ArrayRef<Value *> VL) { + return all_of(make_isa_range<Instruction>(VL), + [L](Instruction *I) { return L->isLoopInvariant(I); }); + }; + while (L && IsLoopInvariant(L, VL)) + L = L->getParentLoop(); + return L; +} + +unsigned getLoopTripCount(const Loop *L, ScalarEvolution &SE, + unsigned LoopAwareTripCount) { + if (LoopAwareTripCount == 0) + return 1; + unsigned Scale = SE.getSmallConstantTripCount(L); + if (Scale == 0) + Scale = getLoopEstimatedTripCount(const_cast<Loop *>(L)).value_or(0); + if (Scale != 0) { + // Multiple exiting blocks - choose the minimum between trip count (scale) + // and LoopAwareTripCount, since the multiple exit loops can be terminated + // early. + if (!L->getExitingBlock()) + return std::min<unsigned>(LoopAwareTripCount, Scale); + return Scale; + } + return LoopAwareTripCount; +} + } // namespace llvm::slpvectorizer diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h index 5be848c8fb585..62e8843737377 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h @@ -40,7 +40,9 @@ class DebugLoc; class Instruction; class InsertElementInst; class IRBuilderBase; +class Loop; class PHINode; +class ScalarEvolution; class TargetLibraryInfo; class Type; class Value; @@ -518,6 +520,15 @@ DebugLoc getDebugLocFromPHI(PHINode &PN); /// a homogeneous aggregate. std::optional<unsigned> getAggregateSize(Instruction *InsertInst); +/// \returns the innermost loop starting from \p L for which at least one value +/// in \p VL is not loop-invariant. +const Loop *findInnermostNonInvariantLoop(const Loop *L, ArrayRef<Value *> VL); + +/// \returns an estimated trip count for \p L, bounded by the loop-aware budget +/// \p LoopAwareTripCount. Returns 1 when the budget is 0. +unsigned getLoopTripCount(const Loop *L, ScalarEvolution &SE, + unsigned LoopAwareTripCount); + } // namespace llvm::slpvectorizer #endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPUTILS_H _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
