29#define DEBUG_TYPE "loop-vectorize"
35 cl::desc(
"Maximize bandwidth when selecting vectorization factor which "
36 "will be determined by the smallest type in loop."));
39 "vectorizer-maximize-bandwidth-for-vector-calls",
cl::init(
true),
41 cl::desc(
"Try wider VFs if they enable the use of vector variants"));
45 cl::desc(
"Discard VFs if their register pressure is too high."));
50 "Pretend that scalable vectors are supported, even if the target does "
51 "not support them. This flag should only be used for testing."));
55 cl::desc(
"Prefer in-loop vector reductions, "
56 "overriding the targets preference."));
62 cl::desc(
"Assume the target supports masked memory operations (used for "
67 cl::desc(
"Assume the target supports gather/scatter operations (used for "
76 dbgs() <<
"LV: " << Prefix << DebugMsg;
97 if (
I &&
I->getDebugLoc())
98 DL =
I->getDebugLoc();
110 <<
"loop not vectorized: " << OREMsg);
125 "Vectorizing: ", TheLoop->
isInnermost() ?
"innermost loop" :
"outer loop",
131 <<
"vectorized " << LoopType <<
"loop (vectorization width: "
132 <<
ore::NV(
"VectorizationFactor", VFWidth)
133 <<
", interleaved count: " <<
ore::NV(
"InterleaveCount", IC) <<
")";
141 (IsLoad ? TTI.isLegalMaskedLoad(ScalarTy, Alignment,
AddressSpace)
142 : TTI.isLegalMaskedStore(ScalarTy, Alignment,
AddressSpace));
156 (LI && TTI.isLegalMaskedGather(Ty,
Align)) ||
157 (
SI && TTI.isLegalMaskedScatter(Ty,
Align));
165bool VFSelectionContext::useMaxBandwidth(
bool IsScalable)
const {
170 (
TTI.shouldMaximizeVectorBandwidth(RegKind) ||
172 Legal->hasVectorCallVariants())));
181 if (TTI.shouldConsiderVectorizationRegPressure())
188 VF, VF.
isScalable() ? MaxPermissibleVFWithoutMaxBW.ScalableVF
189 : MaxPermissibleVFWithoutMaxBW.FixedVF);
193 ElementCount VF,
unsigned MaxTripCount,
unsigned UserIC,
194 bool FoldTailByMasking,
bool RequiresScalarEpilogue)
const {
196 if (VF.
isScalable() &&
F.hasFnAttribute(Attribute::VScaleRange)) {
197 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
198 auto Min = Attr.getVScaleRangeMin();
205 if (MaxTripCount > 0 && RequiresScalarEpilogue)
210 unsigned IC = UserIC > 0 ? UserIC : 1;
211 unsigned EstimatedVFTimesIC = EstimatedVF * IC;
213 if (MaxTripCount && MaxTripCount <= EstimatedVFTimesIC &&
221 if (ClampedUpperTripCount == 0)
222 ClampedUpperTripCount = 1;
223 LLVM_DEBUG(
dbgs() <<
"LV: Clamping the MaxVF to maximum power of two not "
224 "exceeding the constant trip count"
225 << (UserIC > 0 ?
" divided by UserIC" :
"") <<
": "
226 << ClampedUpperTripCount <<
"\n");
233ElementCount VFSelectionContext::getMaximizedVFForTarget(
234 unsigned MaxTripCount,
unsigned SmallestType,
unsigned WidestType,
235 ElementCount MaxSafeVF,
unsigned UserIC,
bool FoldTailByMasking,
236 bool RequiresScalarEpilogue) {
237 bool ComputeScalableMaxVF = MaxSafeVF.
isScalable();
238 const TypeSize WidestRegister = TTI.getRegisterBitWidth(
243 auto MinVF = [](
const ElementCount &
LHS,
const ElementCount &
RHS) {
245 "Scalable flags must match");
253 ComputeScalableMaxVF);
254 MaxVectorElementCount = MinVF(MaxVectorElementCount, MaxSafeVF);
256 << (MaxVectorElementCount * WidestType) <<
" bits.\n");
258 if (!MaxVectorElementCount) {
260 << (ComputeScalableMaxVF ?
"scalable" :
"fixed")
261 <<
" vector registers.\n");
266 clampVFByMaxTripCount(MaxVectorElementCount, MaxTripCount, UserIC,
267 FoldTailByMasking, RequiresScalarEpilogue);
270 if (MaxVF != MaxVectorElementCount)
274 MaxPermissibleVFWithoutMaxBW.ScalableVF = MaxVF;
276 MaxPermissibleVFWithoutMaxBW.FixedVF = MaxVF;
278 if (useMaxBandwidth(ComputeScalableMaxVF)) {
281 ComputeScalableMaxVF);
282 MaxVF = MinVF(MaxVectorElementCountMaxBW, MaxSafeVF);
284 if (ElementCount MinVF =
285 TTI.getMinimumVF(SmallestType, ComputeScalableMaxVF)) {
288 <<
") with target's minimum: " << MinVF <<
'\n');
293 MaxVF = clampVFByMaxTripCount(MaxVF, MaxTripCount, UserIC,
294 FoldTailByMasking, RequiresScalarEpilogue);
301 if (std::optional<unsigned> MaxVScale =
TTI.getMaxVScale())
304 if (
F.hasFnAttribute(Attribute::VScaleRange))
305 return F.getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
310bool VFSelectionContext::isScalableVectorizationAllowed() {
311 if (IsScalableVectorizationAllowed)
312 return *IsScalableVectorizationAllowed;
314 IsScalableVectorizationAllowed =
false;
320 "ScalableVectorizationDisabled", ORE, TheLoop);
324 LLVM_DEBUG(
dbgs() <<
"LV: Scalable vectorization is available\n");
327 std::numeric_limits<ElementCount::ScalarTy>::max());
336 if (!
all_of(Legal->getReductionVars(), [&](
const auto &
Reduction) ->
bool {
337 return TTI.isLegalToVectorizeReduction(Reduction.second, MaxScalableVF);
340 "Scalable vectorization not supported for the reduction "
341 "operations found in this loop.",
342 "ScalableVFUnfeasible", ORE, TheLoop);
348 if (
any_of(ElementTypesInLoop, [&](
Type *Ty) {
349 return !Ty->
isVoidTy() && !TTI.isElementTypeLegalForScalableVector(Ty);
352 "for all element types found in this loop.",
353 "ScalableVFUnfeasible", ORE, TheLoop);
357 if (!Legal->isSafeForAnyVectorWidth() && !
getMaxVScale(F, TTI)) {
359 "for safe distance analysis.",
360 "ScalableVFUnfeasible", ORE, TheLoop);
364 IsScalableVectorizationAllowed =
true;
369VFSelectionContext::getMaxLegalScalableVF(
unsigned MaxSafeElements) {
370 if (!isScalableVectorizationAllowed())
374 std::numeric_limits<ElementCount::ScalarTy>::max());
375 if (Legal->isSafeForAnyVectorWidth())
376 return MaxScalableVF;
378 std::optional<unsigned> MaxVScale =
getMaxVScale(F, TTI);
384 "Max legal vector width too small, scalable vectorization "
386 "ScalableVFUnfeasible", ORE, TheLoop);
388 return MaxScalableVF;
392 unsigned MaxTripCount,
ElementCount UserVF,
unsigned UserIC,
393 bool FoldTailByMasking,
bool RequiresScalarEpilogue) {
400 unsigned MaxSafeElementsPowerOf2 =
402 if (!Legal->isSafeForAnyStoreLoadForwardDistances()) {
403 unsigned SLDist = Legal->getMaxStoreLoadForwardSafeDistanceInBits();
404 MaxSafeElementsPowerOf2 =
405 std::min(MaxSafeElementsPowerOf2, SLDist / WidestType);
409 auto MaxSafeScalableVF = getMaxLegalScalableVF(MaxSafeElementsPowerOf2);
411 if (!Legal->isSafeForAnyVectorWidth())
412 MaxSafeElements = MaxSafeElementsPowerOf2;
414 LLVM_DEBUG(
dbgs() <<
"LV: The max safe fixed VF is: " << MaxSafeFixedVF
416 LLVM_DEBUG(
dbgs() <<
"LV: The max safe scalable VF is: " << MaxSafeScalableVF
422 UserVF.
isScalable() ? MaxSafeScalableVF : MaxSafeFixedVF;
439 <<
" is unsafe, clamping to max safe VF="
440 << MaxSafeFixedVF <<
".\n");
443 TheLoop->getStartLoc(),
444 TheLoop->getHeader())
445 <<
"User-specified vectorization factor "
446 <<
ore::NV(
"UserVectorizationFactor", UserVF)
447 <<
" is unsafe, clamping to maximum safe vectorization factor "
448 <<
ore::NV(
"VectorizationFactor", MaxSafeFixedVF);
450 return MaxSafeFixedVF;
455 <<
" is ignored because scalable vectors are not "
459 TheLoop->getStartLoc(),
460 TheLoop->getHeader())
461 <<
"User-specified vectorization factor "
462 <<
ore::NV(
"UserVectorizationFactor", UserVF)
463 <<
" is ignored because the target does not support scalable "
464 "vectors. The compiler will pick a more suitable value.";
468 <<
" is unsafe. Ignoring scalable UserVF.\n");
471 TheLoop->getStartLoc(),
472 TheLoop->getHeader())
473 <<
"User-specified vectorization factor "
474 <<
ore::NV(
"UserVectorizationFactor", UserVF)
475 <<
" is unsafe. Ignoring the hint to let the compiler pick a "
476 "more suitable value.";
481 LLVM_DEBUG(
dbgs() <<
"LV: The Smallest and Widest types: " << SmallestType
482 <<
" / " << WidestType <<
" bits.\n");
486 if (
auto MaxVF = getMaximizedVFForTarget(
487 MaxTripCount, SmallestType, WidestType, MaxSafeFixedVF, UserIC,
488 FoldTailByMasking, RequiresScalarEpilogue))
489 Result.FixedVF = MaxVF;
491 if (
auto MaxVF = getMaximizedVFForTarget(
492 MaxTripCount, SmallestType, WidestType, MaxSafeScalableVF, UserIC,
493 FoldTailByMasking, RequiresScalarEpilogue))
495 Result.ScalableVF = MaxVF;
503std::pair<unsigned, unsigned>
505 unsigned MinWidth = -1U;
506 unsigned MaxWidth = 8;
511 if (ElementTypesInLoop.empty() && !Legal->getReductionVars().empty()) {
512 for (
const auto &[
_, RdxDesc] : Legal->getReductionVars()) {
517 std::min(RdxDesc.getMinWidthCastToRecurrenceTypeInBits(),
518 RdxDesc.getRecurrenceType()->getScalarSizeInBits()));
519 MaxWidth = std::max(MaxWidth,
520 RdxDesc.getRecurrenceType()->getScalarSizeInBits());
523 for (
Type *
T : ElementTypesInLoop) {
524 MinWidth = std::min<unsigned>(
525 MinWidth,
DL.getTypeSizeInBits(
T->getScalarType()).getFixedValue());
526 MaxWidth = std::max<unsigned>(
527 MaxWidth,
DL.getTypeSizeInBits(
T->getScalarType()).getFixedValue());
530 return {MinWidth, MaxWidth};
535 ElementTypesInLoop.clear();
543 if (ValuesToIgnore && ValuesToIgnore->
contains(&
I))
553 if (!Legal->isReductionVariable(PN))
556 Legal->getRecurrenceDescriptor(PN);
566 T = ST->getValueOperand()->getType();
569 "Expected the load/store/recurrence type to be sized");
571 ElementTypesInLoop.insert(
T);
576void VFSelectionContext::initializeVScaleForTuning() {
580 if (
F.hasFnAttribute(Attribute::VScaleRange)) {
581 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
582 auto Min = Attr.getVScaleRangeMin();
583 auto Max = Attr.getVScaleRangeMax();
584 if (Max && Min == Max) {
585 VScaleForTuning = Max;
590 VScaleForTuning = TTI.getVScaleForTuning();
595 return !Hints->allowReordering() && RdxDesc.
isOrdered();
601 Loop *L =
const_cast<Loop *
>(TheLoop);
602 if (Legal->getRuntimePointerChecking()->Need) {
604 "Runtime ptr check is required with -Os/-Oz",
605 "runtime pointer checks needed. Enable vectorization of this "
606 "loop with '#pragma clang loop vectorize(enable)' when "
607 "compiling with -Os/-Oz",
608 "CantVersionLoopWithOptForSize", ORE, L);
612 if (!PSE.getPredicate().isAlwaysTrue()) {
614 "Runtime SCEV check is required with -Os/-Oz",
615 "runtime SCEV checks needed. Enable vectorization of this "
616 "loop with '#pragma clang loop vectorize(enable)' when "
617 "compiling with -Os/-Oz",
618 "CantVersionLoopWithOptForSize", ORE, L);
623 if (!Legal->getLAI()->getSymbolicStrides().empty()) {
625 "Runtime stride check for small trip count",
626 "runtime stride == 1 checks needed. Enable vectorization of "
627 "this loop without such check by compiling with -Os/-Oz",
628 "CantVersionLoopWithOptForSize", ORE, L);
641 if (!InLoopReductions.empty())
644 for (
const auto &Reduction : Legal->getReductionVars()) {
645 PHINode *Phi = Reduction.first;
667 !TTI.preferInLoopReduction(Kind, Phi->getType()))
675 bool InLoop = !ReductionOperations.
empty();
678 InLoopReductions.insert(Phi);
681 for (
auto *
I : ReductionOperations) {
682 InLoopReductionImmediateChains[
I] = LastChain;
686 LLVM_DEBUG(
dbgs() <<
"LV: Using " << (InLoop ?
"inloop" :
"out of loop")
687 <<
" reduction for phi: " << *Phi <<
"\n");
693 const unsigned MaxTripCount,
695 bool IsEpilogue)
const {
701 if (
A.Width.isScalable() && CostA.
isValid() && !
B.Width.isScalable() &&
706 unsigned EstimatedWidthA =
A.Width.getKnownMinValue();
707 unsigned EstimatedWidthB =
B.Width.getKnownMinValue();
709 if (
A.Width.isScalable())
710 EstimatedWidthA *= *VScale;
711 if (
B.Width.isScalable())
712 EstimatedWidthB *= *VScale;
719 return CostA < CostB ||
720 (CostA == CostB && EstimatedWidthA > EstimatedWidthB);
725 bool PreferScalable = !
TTI.preferFixedOverScalableIfEqualCost(IsEpilogue) &&
726 A.Width.isScalable() && !
B.Width.isScalable();
736 bool LowerCostWithoutTC =
737 CmpFn(CostA * EstimatedWidthB, CostB * EstimatedWidthA);
739 return LowerCostWithoutTC;
741 auto GetCostForTC = [MaxTripCount, HasTail](
unsigned VF,
753 return VectorCost * (MaxTripCount / VF) +
754 ScalarCost * (MaxTripCount % VF);
755 return VectorCost *
divideCeil(MaxTripCount, VF);
758 auto RTCostA = GetCostForTC(EstimatedWidthA, CostA,
A.ScalarCost);
759 auto RTCostB = GetCostForTC(EstimatedWidthB, CostB,
B.ScalarCost);
760 bool LowerCostWithTC = CmpFn(RTCostA, RTCostB);
761 LLVM_DEBUG(
if (LowerCostWithTC != LowerCostWithoutTC) {
762 dbgs() <<
"LV: VF " << (LowerCostWithTC ?
A.Width :
B.Width)
763 <<
" has lower cost than VF "
764 << (LowerCostWithTC ?
B.Width :
A.Width)
765 <<
" when taking the cost of the remaining scalar loop iterations "
766 "into consideration for a maximum trip count of "
767 << MaxTripCount <<
".\n";
769 return LowerCostWithTC;
775 bool IsEpilogue)
const {
776 const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
777 return LoopVectorizationPlanner::isMoreProfitable(
A,
B, MaxTripCount, HasTail,
790 "Scalable vectorization requested but not supported by the target",
791 "the scalable user-specified vectorization width for outer-loop "
792 "vectorization cannot be used because the target does not support "
794 "ScalableVFUnfeasible", ORE, TheLoop);
802 auto RegKind = TTI.enableScalableVectorization()
809 unsigned N = std::max<uint64_t>(
817 <<
"overriding computed VF.\n");
822 "VF needs to be a power of two");
826 <<
"VF " << VF <<
" to build VPlans.\n");
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 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)."))
cl::opt< bool > VPlanBuildOuterloopStressTest
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 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.
constexpr bool isVector() const
One or more elements.
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 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
const TTI::TargetCostKind CostKind
The kind of cost that we are calculating.
bool supportsScalableVectors() const
bool runtimeChecksRequired()
Check whether vectorization would require runtime checks.
bool isLegalGatherOrScatter(Value *V, ElementCount VF) const
Returns true if the target machine can represent V as a masked gather or scatter operation.
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)
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.
LLVM Value Representation.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
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.
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.
std::optional< unsigned > getMaxVScale(const Function &F, const TargetTransformInfo &TTI)
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.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
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.
cl::opt< bool > PreferInLoopReductions
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.