30#define DEBUG_TYPE "loop-vectorize"
34 cl::desc(
"Maximize bandwidth when selecting vectorization factor which "
35 "will be determined by the smallest type in loop."));
38 "vectorizer-maximize-bandwidth-for-vector-calls",
cl::init(
true),
40 cl::desc(
"Try wider VFs if they enable the use of vector variants"));
44 cl::desc(
"Discard VFs if their register pressure is too high."));
49 "Pretend that scalable vectors are supported, even if the target does "
50 "not support them. This flag should only be used for testing."));
55 cl::desc(
"Prefer in-loop vector reductions, "
56 "overriding the targets preference."));
66 cl::desc(
"Assume the target supports masked memory operations (used for "
71 cl::desc(
"Assume the target supports gather/scatter operations (used for "
76 cl::desc(
"Scale the cost of scalable epilogue VFs by this factor."));
84 dbgs() <<
"LV: " << Prefix << DebugMsg;
105 if (
I &&
I->getDebugLoc())
106 DL =
I->getDebugLoc();
118 <<
"loop not vectorized: " << OREMsg);
133 "Vectorizing: ", TheLoop->
isInnermost() ?
"innermost loop" :
"outer loop",
139 <<
"vectorized " << LoopType <<
"loop (vectorization width: "
140 <<
ore::NV(
"VectorizationFactor", VFWidth)
141 <<
", interleaved count: " <<
ore::NV(
"InterleaveCount", IC) <<
")";
149 (IsLoad ? TTI.isLegalMaskedLoad(ScalarTy, Alignment,
AddressSpace)
150 : TTI.isLegalMaskedStore(ScalarTy, Alignment,
AddressSpace));
158 (IsLoad ? TTI.isLegalMaskedGather(VectorTy, Alignment)
159 : TTI.isLegalMaskedScatter(VectorTy, Alignment));
167bool VFSelectionContext::useMaxBandwidth(
bool IsScalable)
const {
172 (
TTI.shouldMaximizeVectorBandwidth(RegKind) ||
183 if (TTI.shouldConsiderVectorizationRegPressure())
190 VF, VF.
isScalable() ? MaxPermissibleVFWithoutMaxBW.ScalableVF
191 : MaxPermissibleVFWithoutMaxBW.FixedVF);
195 ElementCount VF,
unsigned MaxTripCount,
unsigned UserIC,
196 bool FoldTailByMasking,
bool RequiresScalarEpilogue)
const {
198 if (VF.
isScalable() &&
F.hasFnAttribute(Attribute::VScaleRange)) {
199 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
200 auto Min = Attr.getVScaleRangeMin();
207 if (MaxTripCount > 0 && RequiresScalarEpilogue)
212 unsigned IC = UserIC > 0 ? UserIC : 1;
213 unsigned EstimatedVFTimesIC = EstimatedVF * IC;
215 if (MaxTripCount && MaxTripCount <= EstimatedVFTimesIC &&
223 if (ClampedUpperTripCount == 0)
224 ClampedUpperTripCount = 1;
225 LLVM_DEBUG(
dbgs() <<
"LV: Clamping the MaxVF to maximum power of two not "
226 "exceeding the constant trip count"
227 << (UserIC > 0 ?
" divided by UserIC" :
"") <<
": "
228 << ClampedUpperTripCount <<
"\n");
235ElementCount VFSelectionContext::getMaximizedVFForTarget(
236 unsigned MaxTripCount,
unsigned SmallestType,
unsigned WidestType,
237 ElementCount MaxSafeVF,
unsigned UserIC,
bool FoldTailByMasking,
238 bool RequiresScalarEpilogue) {
239 bool ComputeScalableMaxVF = MaxSafeVF.
isScalable();
240 const TypeSize WidestRegister = TTI.getRegisterBitWidth(
245 auto MinVF = [](
const ElementCount &
LHS,
const ElementCount &
RHS) {
247 "Scalable flags must match");
255 ComputeScalableMaxVF);
256 MaxVectorElementCount = MinVF(MaxVectorElementCount, MaxSafeVF);
258 << (MaxVectorElementCount * WidestType) <<
" bits.\n");
260 if (!MaxVectorElementCount) {
262 << (ComputeScalableMaxVF ?
"scalable" :
"fixed")
263 <<
" vector registers.\n");
268 clampVFByMaxTripCount(MaxVectorElementCount, MaxTripCount, UserIC,
269 FoldTailByMasking, RequiresScalarEpilogue);
272 if (MaxVF != MaxVectorElementCount)
276 MaxPermissibleVFWithoutMaxBW.ScalableVF = MaxVF;
278 MaxPermissibleVFWithoutMaxBW.FixedVF = MaxVF;
280 if (useMaxBandwidth(ComputeScalableMaxVF)) {
283 ComputeScalableMaxVF);
284 MaxVF = MinVF(MaxVectorElementCountMaxBW, MaxSafeVF);
286 if (ElementCount MinVF =
287 TTI.getMinimumVF(SmallestType, ComputeScalableMaxVF)) {
290 <<
") with target's minimum: " << MinVF <<
'\n');
295 MaxVF = clampVFByMaxTripCount(MaxVF, MaxTripCount, UserIC,
296 FoldTailByMasking, RequiresScalarEpilogue);
302 if (
F.hasFnAttribute(Attribute::VScaleRange))
303 return F.getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
308std::optional<uint64_t>
311 return EC.getFixedValue();
314 return uint64_t(EC.getKnownMinValue()) * *MaxVScale;
319bool VFSelectionContext::isScalableVectorizationAllowed() {
320 if (IsScalableVectorizationAllowed)
321 return *IsScalableVectorizationAllowed;
323 IsScalableVectorizationAllowed =
false;
329 "ScalableVectorizationDisabled", ORE, TheLoop);
333 LLVM_DEBUG(
dbgs() <<
"LV: Scalable vectorization is available\n");
336 std::numeric_limits<ElementCount::ScalarTy>::max());
345 if (!
all_of(Legal->getReductionVars(), [&](
const auto &
Reduction) ->
bool {
346 return TTI.isLegalToVectorizeReduction(Reduction.second, MaxScalableVF);
349 "Scalable vectorization not supported for the reduction "
350 "operations found in this loop.",
351 "ScalableVFUnfeasible", ORE, TheLoop);
357 if (
any_of(ElementTypesInLoop, [&](
Type *Ty) {
358 return !Ty->
isVoidTy() && !TTI.isElementTypeLegalForScalableVector(Ty);
361 "for all element types found in this loop.",
362 "ScalableVFUnfeasible", ORE, TheLoop);
366 if (!Legal->isSafeForAnyVectorWidth() && !
getMaxVScale(F)) {
368 "for safe distance analysis.",
369 "ScalableVFUnfeasible", ORE, TheLoop);
373 IsScalableVectorizationAllowed =
true;
378VFSelectionContext::getMaxLegalScalableVF(
unsigned MaxSafeElements) {
379 if (!isScalableVectorizationAllowed())
383 std::numeric_limits<ElementCount::ScalarTy>::max());
384 if (Legal->isSafeForAnyVectorWidth())
385 return MaxScalableVF;
393 "Max legal vector width too small, scalable vectorization "
395 "ScalableVFUnfeasible", ORE, TheLoop);
397 return MaxScalableVF;
401 unsigned MaxTripCount,
ElementCount UserVF,
unsigned UserIC,
402 bool FoldTailByMasking,
bool RequiresScalarEpilogue) {
409 unsigned MaxSafeElementsPowerOf2 =
411 if (!Legal->isSafeForAnyStoreLoadForwardDistances()) {
412 unsigned SLDist = Legal->getMaxStoreLoadForwardSafeDistanceInBits();
413 MaxSafeElementsPowerOf2 =
414 std::min(MaxSafeElementsPowerOf2, SLDist / WidestType);
418 auto MaxSafeScalableVF = getMaxLegalScalableVF(MaxSafeElementsPowerOf2);
420 if (!Legal->isSafeForAnyVectorWidth())
421 MaxSafeElements = MaxSafeElementsPowerOf2;
423 LLVM_DEBUG(
dbgs() <<
"LV: The max safe fixed VF is: " << MaxSafeFixedVF
425 LLVM_DEBUG(
dbgs() <<
"LV: The max safe scalable VF is: " << MaxSafeScalableVF
431 UserVF.
isScalable() ? MaxSafeScalableVF : MaxSafeFixedVF;
448 <<
" is unsafe, clamping to max safe VF="
449 << MaxSafeFixedVF <<
".\n");
452 TheLoop->getStartLoc(),
453 TheLoop->getHeader())
454 <<
"User-specified vectorization factor "
455 <<
ore::NV(
"UserVectorizationFactor", UserVF)
456 <<
" is unsafe, clamping to maximum safe vectorization factor "
457 <<
ore::NV(
"VectorizationFactor", MaxSafeFixedVF);
459 return MaxSafeFixedVF;
464 <<
" is ignored because scalable vectors are not "
468 TheLoop->getStartLoc(),
469 TheLoop->getHeader())
470 <<
"User-specified vectorization factor "
471 <<
ore::NV(
"UserVectorizationFactor", UserVF)
472 <<
" is ignored because the target does not support scalable "
473 "vectors. The compiler will pick a more suitable value.";
477 <<
" is unsafe. Ignoring scalable UserVF.\n");
480 TheLoop->getStartLoc(),
481 TheLoop->getHeader())
482 <<
"User-specified vectorization factor "
483 <<
ore::NV(
"UserVectorizationFactor", UserVF)
484 <<
" is unsafe. Ignoring the hint to let the compiler pick a "
485 "more suitable value.";
490 LLVM_DEBUG(
dbgs() <<
"LV: The Smallest and Widest types: " << SmallestType
491 <<
" / " << WidestType <<
" bits.\n");
495 if (
auto MaxVF = getMaximizedVFForTarget(
496 MaxTripCount, SmallestType, WidestType, MaxSafeFixedVF, UserIC,
497 FoldTailByMasking, RequiresScalarEpilogue))
498 Result.FixedVF = MaxVF;
500 if (
auto MaxVF = getMaximizedVFForTarget(
501 MaxTripCount, SmallestType, WidestType, MaxSafeScalableVF, UserIC,
502 FoldTailByMasking, RequiresScalarEpilogue))
504 Result.ScalableVF = MaxVF;
512std::pair<unsigned, unsigned>
514 unsigned MinWidth = -1U;
515 unsigned MaxWidth = 8;
520 if (ElementTypesInLoop.empty() && !Legal->getReductionVars().empty()) {
521 for (
const auto &[
_, RdxDesc] : Legal->getReductionVars()) {
526 std::min(RdxDesc.getMinWidthCastToRecurrenceTypeInBits(),
527 RdxDesc.getRecurrenceType()->getScalarSizeInBits()));
528 MaxWidth = std::max(MaxWidth,
529 RdxDesc.getRecurrenceType()->getScalarSizeInBits());
532 for (
Type *
T : ElementTypesInLoop) {
533 MinWidth = std::min<unsigned>(
534 MinWidth,
DL.getTypeSizeInBits(
T->getScalarType()).getFixedValue());
535 MaxWidth = std::max<unsigned>(
536 MaxWidth,
DL.getTypeSizeInBits(
T->getScalarType()).getFixedValue());
548 return {MinWidth, MaxWidth};
553 ElementTypesInLoop.clear();
561 if (ValuesToIgnore && ValuesToIgnore->
contains(&
I))
571 if (!Legal->isReductionVariable(PN))
574 Legal->getRecurrenceDescriptor(PN);
584 T = ST->getValueOperand()->getType();
587 "Expected the load/store/recurrence type to be sized");
589 ElementTypesInLoop.insert(
T);
594void VFSelectionContext::initializeVScaleForTuning() {
598 if (
F.hasFnAttribute(Attribute::VScaleRange)) {
599 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
600 auto Min = Attr.getVScaleRangeMin();
601 auto Max = Attr.getVScaleRangeMax();
602 if (Max && Min == Max) {
603 VScaleForTuning = Max;
608 VScaleForTuning = TTI.getVScaleForTuning();
613 return !Hints->allowReordering() && RdxDesc.
isOrdered();
619 Loop *L =
const_cast<Loop *
>(TheLoop);
620 if (Legal->getRuntimePointerChecking()->Need) {
622 "Runtime ptr check is required with -Os/-Oz",
623 "runtime pointer checks needed. Enable vectorization of this "
624 "loop with '#pragma clang loop vectorize(enable)' when "
625 "compiling with -Os/-Oz",
626 "CantVersionLoopWithOptForSize", ORE, L);
630 if (!PSE.getPredicate().isAlwaysTrue()) {
632 "Runtime SCEV check is required with -Os/-Oz",
633 "runtime SCEV checks needed. Enable vectorization of this "
634 "loop with '#pragma clang loop vectorize(enable)' when "
635 "compiling with -Os/-Oz",
636 "CantVersionLoopWithOptForSize", ORE, L);
641 if (!Legal->getLAI()->getSymbolicStrides().empty()) {
643 "Runtime stride check for small trip count",
644 "runtime stride == 1 checks needed. Enable vectorization of "
645 "this loop without such check by compiling with -Os/-Oz",
646 "CantVersionLoopWithOptForSize", ORE, L);
659 if (!InLoopReductions.empty())
662 for (
const auto &Reduction : Legal->getReductionVars()) {
663 PHINode *Phi = Reduction.first;
685 !TTI.preferInLoopReduction(Kind, Phi->getType()))
693 bool InLoop = !ReductionOperations.
empty();
696 InLoopReductions.insert(Phi);
699 for (
auto *
I : ReductionOperations) {
700 InLoopReductionImmediateChains[
I] = LastChain;
704 LLVM_DEBUG(
dbgs() <<
"LV: Using " << (InLoop ?
"inloop" :
"out of loop")
705 <<
" reduction for phi: " << *Phi <<
"\n");
711 const unsigned MaxTripCount,
713 bool IsEpilogue)
const {
719 if (
A.Width.isScalable() && CostA.
isValid() && !
B.Width.isScalable() &&
728 if (IsEpilogue &&
A.Width.isScalable() !=
B.Width.isScalable() &&
729 A.Cost.isValid() &&
B.Cost.isValid()) {
730 auto [FixedCost, ScalableCost] = std::make_pair(CostA, CostB);
731 if (
B.Width.isFixed())
736 if (FixedCost <= ScalableCost)
737 return A.Width.isFixed();
741 unsigned EstimatedWidthA =
A.Width.getKnownMinValue();
742 unsigned EstimatedWidthB =
B.Width.getKnownMinValue();
744 if (
A.Width.isScalable())
745 EstimatedWidthA *= *VScale;
746 if (
B.Width.isScalable())
747 EstimatedWidthB *= *VScale;
754 return CostA < CostB ||
755 (CostA == CostB && EstimatedWidthA > EstimatedWidthB);
760 bool PreferScalable = !TTI.preferFixedOverScalableIfEqualCost() &&
761 A.Width.isScalable() && !
B.Width.isScalable();
771 bool LowerCostWithoutTC =
772 CmpFn(CostA * EstimatedWidthB, CostB * EstimatedWidthA);
774 return LowerCostWithoutTC;
776 auto GetCostForTC = [MaxTripCount, HasTail](
unsigned VF,
788 return VectorCost * (MaxTripCount / VF) +
789 ScalarCost * (MaxTripCount % VF);
790 return VectorCost *
divideCeil(MaxTripCount, VF);
793 auto RTCostA = GetCostForTC(EstimatedWidthA, CostA,
A.ScalarCost);
794 auto RTCostB = GetCostForTC(EstimatedWidthB, CostB,
B.ScalarCost);
795 bool LowerCostWithTC = CmpFn(RTCostA, RTCostB);
796 LLVM_DEBUG(
if (LowerCostWithTC != LowerCostWithoutTC) {
797 dbgs() <<
"LV: VF " << (LowerCostWithTC ?
A.Width :
B.Width)
798 <<
" has lower cost than VF "
799 << (LowerCostWithTC ?
B.Width :
A.Width)
800 <<
" when taking the cost of the remaining scalar loop iterations "
801 "into consideration for a maximum trip count of "
802 << MaxTripCount <<
".\n";
804 return LowerCostWithTC;
810 bool IsEpilogue)
const {
811 const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
812 return LoopVectorizationPlanner::isMoreProfitable(
A,
B, MaxTripCount, HasTail,
825 "Scalable vectorization requested but not supported by the target",
826 "the scalable user-specified vectorization width for outer-loop "
827 "vectorization cannot be used because the target does not support "
829 "ScalableVFUnfeasible", ORE, TheLoop);
837 auto RegKind = TTI.enableScalableVectorization()
844 unsigned N = std::max<uint64_t>(
852 <<
"overriding computed VF.\n");
857 "VF needs to be a power of two");
861 <<
"VF " << VF <<
" to build VPlans.\n");
871 switch (R.getVPRecipeID()) {
872 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
875 case VPRecipeBase::VPWidenIntOrFpInductionSC:
876 return !cast<VPWidenIntOrFpInductionRecipe>(&R)->getPHINode();
877 case VPRecipeBase::VPReductionPHISC: {
878 auto *RedPhi = cast<VPReductionPHIRecipe>(&R);
881 RecurKind Kind = RedPhi->getRecurrenceKind();
882 if (RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(Kind) ||
883 RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) ||
884 !RedPhi->getUnderlyingValue())
891 if (RecurrenceDescriptor::isFindIVRecurrenceKind(Kind)) {
892 auto *RdxResult = vputils::findComputeReductionResult(RedPhi);
894 "FindIV reduction must have ComputeReductionResult");
895 return any_of(RdxResult->users(),
896 std::not_fn(IsaPred<VPInstruction>));
906bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
907 VPlan &MainPlan)
const {
917 if (OrigLoop->getExitingBlock() != OrigLoop->getLoopLatch())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
loop Loop Strength Reduction
This file defines the LoopVectorizationLegality class.
static cl::opt< float > ScalableEpilogueVFCostScaleFactor("scalable-epilogue-vf-cost-scale-factor", cl::init(2.0), cl::Hidden, cl::desc("Scale the cost of scalable epilogue VFs by this factor."))
static bool hasUnsupportedHeaderPhiRecipe(VPlan &Plan)
static void debugVectorizationMessage(const StringRef Prefix, const StringRef DebugMsg, Instruction *I)
Write a DebugMsg about vectorization to the debug output stream.
static cl::opt< bool > ForceTargetSupportsGatherScatterOps("force-target-supports-gather-scatter-ops", cl::init(false), cl::Hidden, cl::desc("Assume the target supports gather/scatter operations (used for " "testing)."))
static cl::opt< bool > ForceTargetSupportsScalableVectors("force-target-supports-scalable-vectors", cl::init(false), cl::Hidden, cl::desc("Pretend that scalable vectors are supported, even if the target does " "not support them. This flag should only be used for testing."))
static cl::opt< bool > ConsiderRegPressure("vectorizer-consider-reg-pressure", cl::init(false), cl::Hidden, cl::desc("Discard VFs if their register pressure is too high."))
static cl::opt< bool > UseWiderVFIfCallVariantsPresent("vectorizer-maximize-bandwidth-for-vector-calls", cl::init(true), cl::Hidden, cl::desc("Try wider VFs if they enable the use of vector variants"))
static cl::opt< bool > PreferInLoopReductions("prefer-inloop-reductions", cl::init(false), cl::Hidden, cl::desc("Prefer in-loop vector reductions, " "overriding the targets preference."))
static OptimizationRemarkAnalysis createLVAnalysis(StringRef RemarkName, const Loop *TheLoop, Instruction *I, DebugLoc DL={})
Create an analysis remark that explains why vectorization failed RemarkName is the identifier for the...
static cl::opt< bool > ForceTargetSupportsMaskedMemoryOps("force-target-supports-masked-memory-ops", cl::init(false), cl::Hidden, cl::desc("Assume the target supports masked memory operations (used for " "testing)."))
Note: This currently only applies to llvm.masked.load and llvm.masked.store.
static cl::opt< bool > MaximizeBandwidth("vectorizer-maximize-bandwidth", cl::init(false), cl::Hidden, cl::desc("Maximize bandwidth when selecting vectorization factor which " "will be determined by the smallest type in loop."))
This file provides a LoopVectorizationPlanner class.
LLVM Basic Block Representation.
A parsed version of the target data layout string in and methods for querying it.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount getFixed(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
constexpr bool isScalar() const
Exactly one element.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
BlockT * getHeader() const
bool hasVectorCallVariants() const
Returns true if there is at least one function call in the loop which has a vectorized variant availa...
bool isScalableVectorizationDisabled() const
bool isScalableVectorizationAlwaysPreferred() const
Represents a single loop in the control flow graph.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
Type * getRecurrenceType() const
Returns the type of the recurrence.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
static bool isFindLastRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
LLVM_ABI SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const
Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static bool isFindIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool contains(ConstPtrType Ptr) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVoidTy() const
Return true if this is 'void'.
FixedScalableVFPair computeVPlanOuterloopVF(ElementCount UserVF)
Returns a scalable VF to use for outer-loop vectorization if the target supports it and a fixed VF ot...
std::pair< unsigned, unsigned > getSmallestAndWidestTypes() const
bool supportsScalableVectors() const
bool runtimeChecksRequired()
Check whether vectorization would require runtime checks.
bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment, ElementCount VF) const
Returns true if the target machine supports a gather (if IsLoad) or scatter of scalar type ScalarTy w...
bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment, unsigned AddressSpace) const
Returns true if the target machine supports a masked load (if IsLoad) or masked store of scalar type ...
void collectInLoopReductions()
Split reductions into those that happen in the loop, and those that happen outside.
FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC, bool FoldTailByMasking, bool RequiresScalarEpilogue)
const LoopVectorizeHints & getHints() const
bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const
Returns true if we should use strict in-order reductions for the given RdxDesc.
bool shouldConsiderRegPressureForVF(ElementCount VF) const
void collectElementTypesForWidening(const SmallPtrSetImpl< const Value * > *ValuesToIgnore=nullptr)
Collect element types in the loop that need widening.
std::optional< unsigned > getVScaleForTuning() const
void computeMinimalBitwidths()
Compute smallest bitwidth each instruction can be represented with.
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
const VPBasicBlock * getEntryBasicBlock() const
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr, DebugLoc DL={})
Reports an informative message: print Msg for debugging purposes as well as an optimization remark.
void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop, ElementCount VFWidth, unsigned IC)
Report successful vectorization of the loop.
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
cl::opt< bool > VPlanBuildOuterloopStressTest
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
std::optional< uint64_t > getMaxRuntimeElementCount(ElementCount EC, const Function &F)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
RecurKind
These are the kinds of recurrences that we support.
std::optional< unsigned > getMaxVScale(const Function &F)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Type * toVectorTy(Type *Scalar, ElementCount EC)
A helper function for converting Scalar types to vector types.
LLVM_ABI MapVector< Instruction *, uint64_t > computeMinimumValueSizes(ArrayRef< BasicBlock * > Blocks, DemandedBits &DB, const TargetTransformInfo *TTI=nullptr)
Compute a map of integer instructions to their minimum legal type size.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
A class that represents two vectorization factors (initialized with 0 by default).
static FixedScalableVFPair getNone()
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class.
static LLVM_ABI ElementCount VectorizationFactor
VF as overridden by the user.