[llvm] [LV] Factor out VF-independent code from cost model (NFC). (PR #192426)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 20 06:15:50 PDT 2026
================
@@ -490,6 +515,125 @@ struct FixedScalableVFPair {
bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); }
};
+/// Holds state needed to make cost decisions before computing costs per-VF,
+/// including the maximum VFs.
+class VFSelectionContext {
+ /// \return True if maximizing vector bandwidth is enabled by the target or
+ /// user options, for the given register kind.
+ bool useMaxBandwidth(TargetTransformInfo::RegisterKind RegKind) const;
+
+ /// \return the maximized element count based on the targets vector
+ /// registers and the loop trip-count, but limited to a maximum safe VF.
+ ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
+ unsigned SmallestType,
+ unsigned WidestType,
+ ElementCount MaxSafeVF, unsigned UserIC,
+ bool FoldTailByMasking,
+ bool RequiresScalarEpilogue);
+
+ /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
+ /// that results in VF * UserIC <= MaxTripCount.
+ ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
+ unsigned UserIC, bool FoldTailByMasking,
+ bool RequiresScalarEpilogue) const;
+
+ /// \return True if scalable vectorization is supported and enabled.
+ bool isScalableVectorizationAllowed();
+
+ /// \return The maximum legal scalable VF, based on the safe dependence
+ /// distance.
+ ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
+
+ /// Initialize the vscale value used for cost tuning.
+ void initializeVScaleForTuning();
+
+ const TargetTransformInfo &TTI;
+ const LoopVectorizationLegality *Legal;
+ const Loop *TheLoop;
+ const Function &F;
+ OptimizationRemarkEmitter *ORE;
+ const LoopVectorizeHints *Hints;
+
+ /// Cached result of isScalableVectorizationAllowed.
+ std::optional<bool> IsScalableVectorizationAllowed;
+
+ /// The vscale value to tune the cost model for.
+ std::optional<unsigned> VScaleForTuning;
+
+ /// The highest VF possible for this loop, without using MaxBandwidth.
+ FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
+
+ /// All element types found in the loop.
+ SmallPtrSet<Type *, 16> ElementTypesInLoop;
+
+ /// Ephemeral values collected before cost modeling, reused by the cost
+ /// model's collectValuesToIgnore to avoid recomputation.
+ SmallPtrSet<const Value *, 16> EphemeralValues;
+
+ /// Maximum safe number of elements to be processed per vector iteration,
+ /// which do not prevent store-load forwarding and are safe with regard to the
+ /// memory dependencies. Set by computeFeasibleMaxVF.
+ std::optional<unsigned> MaxSafeElements;
+
+public:
+ const TTI::TargetCostKind CostKind;
+ const bool OptForSize;
+
+ VFSelectionContext(const TargetTransformInfo &TTI,
+ const LoopVectorizationLegality *Legal,
+ const Loop *TheLoop, const Function &F,
+ OptimizationRemarkEmitter *ORE,
+ const LoopVectorizeHints *Hints, bool OptForSize)
+ : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), ORE(ORE), Hints(Hints),
+ CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
+ OptForSize(OptForSize) {
+ initializeVScaleForTuning();
+ }
+
+ /// \return The vscale value to tune the cost model for.
+ std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
+
+ /// \return True if register pressure should be considered for the given VF.
+ bool shouldConsiderRegPressureForVF(ElementCount VF) const;
+
+ /// \return True if scalable vectors are supported by the target or forced.
+ bool supportsScalableVectors() const;
+
+ /// Collect ephemeral values in the loop.
+ void collectEphemeralValues(AssumptionCache *AC);
+
+ /// Collect element types in the loop that need widening.
+ void collectElementTypesForWidening(
+ const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
+
+ /// \return The size (in bits) of the smallest and widest types in the code
+ /// that needs to be vectorized. We ignore values that remain scalar such as
+ /// 64 bit loop indices.
+ std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
+
+ /// Compute the maximum feasible VF for both fixed and scalable
----------------
david-arm wrote:
A number of comments from the original version seem to have been dropped. Is there a reason for that?
https://github.com/llvm/llvm-project/pull/192426
More information about the llvm-commits
mailing list