30#define DEBUG_TYPE "loop-vectorize"
38 dbgs() <<
"LV: " << Prefix << DebugMsg;
59 if (
I &&
I->getDebugLoc())
60 DL =
I->getDebugLoc();
72 <<
"loop not vectorized: " << OREMsg);
87 "Vectorizing: ", TheLoop->
isInnermost() ?
"innermost loop" :
"outer loop",
93 <<
"vectorized " << LoopType <<
"loop (vectorization width: "
94 <<
ore::NV(
"VectorizationFactor", VFWidth)
95 <<
", interleaved count: " <<
ore::NV(
"InterleaveCount", IC) <<
")";
102 return Opts.force_target_supports_masked_memory_ops ||
103 (IsLoad ? TTI.isLegalMaskedLoad(ScalarTy, Alignment,
AddressSpace)
104 : TTI.isLegalMaskedStore(ScalarTy, Alignment,
AddressSpace));
111 return Opts.force_target_supports_gather_scatter_ops ||
112 (IsLoad ? TTI.isLegalMaskedGather(VectorTy, Alignment)
113 : TTI.isLegalMaskedScatter(VectorTy, Alignment));
117 return TTI.supportsScalableVectors() ||
118 Opts.force_target_supports_scalable_vectors ||
122bool VFSelectionContext::useMaxBandwidth(VectorKind Kind,
123 Type *ElementTy)
const {
127 bool TargetHasMaxBW =
TTI.shouldMaximizeVectorBandwidth(Kind);
128 bool ShouldEnableMaxBW =
129 TargetHasMaxBW ?
TTI.shouldMaximizeVectorBandwidth(Kind, ElementTy)
130 : Opts.vectorizer_maximize_bandwidth_for_vector_calls &&
132 return valueOr(Opts.vectorizer_maximize_bandwidth, ShouldEnableMaxBW);
141 if (TTI.shouldConsiderVectorizationRegPressure())
148 VF, VF.
isScalable() ? MaxPermissibleVFWithoutMaxBW.ScalableVF
149 : MaxPermissibleVFWithoutMaxBW.FixedVF);
153 ElementCount VF,
unsigned MaxTripCount,
unsigned UserIC,
154 bool FoldTailByMasking,
bool RequiresScalarEpilogue)
const {
156 if (VF.
isScalable() &&
F.hasFnAttribute(Attribute::VScaleRange)) {
157 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
158 auto Min = Attr.getVScaleRangeMin();
165 if (MaxTripCount > 0 && RequiresScalarEpilogue)
170 unsigned IC = UserIC > 0 ? UserIC : 1;
171 unsigned EstimatedVFTimesIC = EstimatedVF * IC;
173 if (MaxTripCount && MaxTripCount <= EstimatedVFTimesIC &&
181 if (ClampedUpperTripCount == 0)
182 ClampedUpperTripCount = 1;
183 LLVM_DEBUG(
dbgs() <<
"LV: Clamping the MaxVF to maximum power of two not "
184 "exceeding the constant trip count"
185 << (UserIC > 0 ?
" divided by UserIC" :
"") <<
": "
186 << ClampedUpperTripCount <<
"\n");
193ElementCount VFSelectionContext::getMaximizedVFForTarget(
194 unsigned MaxTripCount,
const TypeWidths &TyWidths,
ElementCount MaxSafeVF,
195 unsigned UserIC,
bool FoldTailByMasking,
bool RequiresScalarEpilogue) {
196 bool ComputeScalableMaxVF = MaxSafeVF.
isScalable();
197 const TypeSize WidestRegister = TTI.getRegisterBitWidth(
202 auto MinVF = [](
const ElementCount &
LHS,
const ElementCount &
RHS) {
204 "Scalable flags must match");
212 ComputeScalableMaxVF);
213 MaxVectorElementCount = MinVF(MaxVectorElementCount, MaxSafeVF);
215 << (MaxVectorElementCount * TyWidths.WidestType)
218 if (!MaxVectorElementCount) {
220 << (ComputeScalableMaxVF ?
"scalable" :
"fixed")
221 <<
" vector registers.\n");
226 clampVFByMaxTripCount(MaxVectorElementCount, MaxTripCount, UserIC,
227 FoldTailByMasking, RequiresScalarEpilogue);
230 if (MaxVF != MaxVectorElementCount)
234 MaxPermissibleVFWithoutMaxBW.ScalableVF = MaxVF;
236 MaxPermissibleVFWithoutMaxBW.FixedVF = MaxVF;
238 if (useMaxBandwidth(ComputeScalableMaxVF)) {
239 auto MaxVectorElementCountMaxBW =
241 TyWidths.SmallestTypeForMaxBandwidth),
242 ComputeScalableMaxVF);
243 MaxVF = MinVF(MaxVectorElementCountMaxBW, MaxSafeVF);
245 if (ElementCount MinVF =
246 TTI.getMinimumVF(TyWidths.SmallestType, ComputeScalableMaxVF)) {
249 <<
") with target's minimum: " << MinVF <<
'\n');
254 MaxVF = clampVFByMaxTripCount(MaxVF, MaxTripCount, UserIC,
255 FoldTailByMasking, RequiresScalarEpilogue);
261 if (
F.hasFnAttribute(Attribute::VScaleRange))
262 return F.getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
267std::optional<uint64_t>
270 return EC.getFixedValue();
273 return uint64_t(EC.getKnownMinValue()) * *MaxVScale;
278bool VFSelectionContext::isScalableVectorizationAllowed() {
279 if (IsScalableVectorizationAllowed)
280 return *IsScalableVectorizationAllowed;
282 IsScalableVectorizationAllowed =
false;
288 "ScalableVectorizationDisabled", ORE, TheLoop);
292 LLVM_DEBUG(
dbgs() <<
"LV: Scalable vectorization is available\n");
295 std::numeric_limits<ElementCount::ScalarTy>::max());
304 if (!
all_of(Legal->getReductionVars(), [&](
const auto &
Reduction) ->
bool {
305 return TTI.isLegalToVectorizeReduction(Reduction.second, MaxScalableVF);
308 "Scalable vectorization not supported for the reduction "
309 "operations found in this loop.",
310 "ScalableVFUnfeasible", ORE, TheLoop);
316 if (
any_of(ElementTypesInLoop, [&](
Type *Ty) {
317 return !Ty->
isVoidTy() && !TTI.isElementTypeLegalForScalableVector(Ty);
320 "for all element types found in this loop.",
321 "ScalableVFUnfeasible", ORE, TheLoop);
325 if (!Legal->isSafeForAnyVectorWidth() && !
getMaxVScale(F)) {
327 "for safe distance analysis.",
328 "ScalableVFUnfeasible", ORE, TheLoop);
332 IsScalableVectorizationAllowed =
true;
337VFSelectionContext::getMaxLegalScalableVF(
unsigned MaxSafeElements) {
338 if (!isScalableVectorizationAllowed())
342 std::numeric_limits<ElementCount::ScalarTy>::max());
343 if (Legal->isSafeForAnyVectorWidth())
344 return MaxScalableVF;
352 "Max legal vector width too small, scalable vectorization "
354 "ScalableVFUnfeasible", ORE, TheLoop);
356 return MaxScalableVF;
360 unsigned MaxTripCount,
ElementCount UserVF,
unsigned UserIC,
361 bool FoldTailByMasking,
bool RequiresScalarEpilogue) {
362 TypeWidths TyWidths = getTypeWidthsForVFSelection();
369 Legal->getMaxSafeVectorWidthInBits() / TyWidths.WidestType);
370 if (!Legal->isSafeForAnyStoreLoadForwardDistances()) {
371 unsigned SLDist = Legal->getMaxStoreLoadForwardSafeDistanceInBits();
372 MaxSafeElementsPowerOf2 =
373 std::min(MaxSafeElementsPowerOf2, SLDist / TyWidths.WidestType);
377 auto MaxSafeScalableVF = getMaxLegalScalableVF(MaxSafeElementsPowerOf2);
379 if (!Legal->isSafeForAnyVectorWidth())
380 MaxSafeElements = MaxSafeElementsPowerOf2;
382 LLVM_DEBUG(
dbgs() <<
"LV: The max safe fixed VF is: " << MaxSafeFixedVF
384 LLVM_DEBUG(
dbgs() <<
"LV: The max safe scalable VF is: " << MaxSafeScalableVF
390 UserVF.
isScalable() ? MaxSafeScalableVF : MaxSafeFixedVF;
407 <<
" is unsafe, clamping to max safe VF="
408 << MaxSafeFixedVF <<
".\n");
411 TheLoop->getStartLoc(),
412 TheLoop->getHeader())
413 <<
"User-specified vectorization factor "
414 <<
ore::NV(
"UserVectorizationFactor", UserVF)
415 <<
" is unsafe, clamping to maximum safe vectorization factor "
416 <<
ore::NV(
"VectorizationFactor", MaxSafeFixedVF);
418 return MaxSafeFixedVF;
423 <<
" is ignored because scalable vectors are not "
427 TheLoop->getStartLoc(),
428 TheLoop->getHeader())
429 <<
"User-specified vectorization factor "
430 <<
ore::NV(
"UserVectorizationFactor", UserVF)
431 <<
" is ignored because the target does not support scalable "
432 "vectors. The compiler will pick a more suitable value.";
436 <<
" is unsafe. Ignoring scalable UserVF.\n");
439 TheLoop->getStartLoc(),
440 TheLoop->getHeader())
441 <<
"User-specified vectorization factor "
442 <<
ore::NV(
"UserVectorizationFactor", UserVF)
443 <<
" is unsafe. Ignoring the hint to let the compiler pick a "
444 "more suitable value.";
450 << TyWidths.SmallestType <<
" / " << TyWidths.WidestType
451 <<
" bits (smallest type for maximizing bandwidth: "
452 << TyWidths.SmallestTypeForMaxBandwidth <<
" bits)\n");
456 if (
auto MaxVF = getMaximizedVFForTarget(
457 MaxTripCount, TyWidths, MaxSafeFixedVF, UserIC, FoldTailByMasking,
458 RequiresScalarEpilogue))
459 Result.FixedVF = MaxVF;
461 if (
auto MaxVF = getMaximizedVFForTarget(
462 MaxTripCount, TyWidths, MaxSafeScalableVF, UserIC, FoldTailByMasking,
463 RequiresScalarEpilogue))
465 Result.ScalableVF = MaxVF;
473VFSelectionContext::TypeWidths
474VFSelectionContext::getTypeWidthsForVFSelection()
const {
475 unsigned MaxWidth = 8;
476 unsigned MinWidth = -1;
477 unsigned MinWidthForMaxBandwidth = -1U;
480 auto UpdateSmallestAndWidestSizes = [&](
Type *
T,
bool UpdateMaxWidth =
true) {
481 unsigned TySize =
DL.getTypeSizeInBits(
T->getScalarType()).getFixedValue();
483 MinWidth = std::min<unsigned>(MinWidth, TySize);
485 MaxWidth = std::max<unsigned>(MaxWidth, TySize);
487 if (!useMaxBandwidth(VectorKind::FixedOrScalable,
T))
490 MinWidthForMaxBandwidth =
491 std::min<unsigned>(MinWidthForMaxBandwidth, TySize);
497 if (ElementTypesInLoop.empty()) {
500 UpdateSmallestAndWidestSizes(RdxDesc.getRecurrenceType());
503 if (
Type *
T = RdxDesc.getMinWidthCastToRecurrenceType())
504 UpdateSmallestAndWidestSizes(
T,
false);
507 for (
Type *
T : ElementTypesInLoop)
508 UpdateSmallestAndWidestSizes(
T);
516 if (MinWidthForMaxBandwidth == -1U)
517 MinWidthForMaxBandwidth = MaxWidth;
521 return {MinWidthForMaxBandwidth, MinWidth, MaxWidth};
526 ElementTypesInLoop.clear();
534 if (ValuesToIgnore && ValuesToIgnore->
contains(&
I))
544 if (!Legal->isReductionVariable(PN))
547 Legal->getRecurrenceDescriptor(PN);
557 T = ST->getValueOperand()->getType();
560 "Expected the load/store/recurrence type to be sized");
562 ElementTypesInLoop.insert(
T);
567void VFSelectionContext::initializeVScaleForTuning() {
571 if (
F.hasFnAttribute(Attribute::VScaleRange)) {
572 auto Attr =
F.getFnAttribute(Attribute::VScaleRange);
573 auto Min = Attr.getVScaleRangeMin();
574 auto Max = Attr.getVScaleRangeMax();
575 if (Max && Min == Max) {
576 VScaleForTuning = Max;
581 VScaleForTuning = TTI.getVScaleForTuning();
586 return !Hints->allowReordering() && RdxDesc.
isOrdered();
592 Loop *L =
const_cast<Loop *
>(TheLoop);
593 if (Legal->getRuntimePointerChecking()->Need) {
595 "Runtime ptr check is required with -Os/-Oz",
596 "runtime pointer checks needed. Enable vectorization of this "
597 "loop with '#pragma clang loop vectorize(enable)' when "
598 "compiling with -Os/-Oz",
599 "CantVersionLoopWithOptForSize", ORE, L);
603 if (!PSE.getPredicate().isAlwaysTrue()) {
605 "Runtime SCEV check is required with -Os/-Oz",
606 "runtime SCEV checks needed. Enable vectorization of this "
607 "loop with '#pragma clang loop vectorize(enable)' when "
608 "compiling with -Os/-Oz",
609 "CantVersionLoopWithOptForSize", ORE, L);
614 if (!Legal->getLAI()->getSymbolicStrides().empty()) {
616 "Runtime stride check for small trip count",
617 "runtime stride == 1 checks needed. Enable vectorization of "
618 "this loop without such check by compiling with -Os/-Oz",
619 "CantVersionLoopWithOptForSize", ORE, L);
632 if (!InLoopReductions.empty())
635 for (
const auto &Reduction : Legal->getReductionVars()) {
636 PHINode *Phi = Reduction.first;
658 !TTI.preferInLoopReduction(Kind, Phi->getType()))
666 bool InLoop = !ReductionOperations.
empty();
669 InLoopReductions.insert(Phi);
670 LLVM_DEBUG(
dbgs() <<
"LV: Using " << (InLoop ?
"inloop" :
"out of loop")
671 <<
" reduction for phi: " << *Phi <<
"\n");
677 const unsigned MaxTripCount,
679 bool IsEpilogue)
const {
685 if (
A.Width.isScalable() && CostA.
isValid() && !
B.Width.isScalable() &&
694 if (IsEpilogue &&
A.Width.isScalable() !=
B.Width.isScalable() &&
695 A.Cost.isValid() &&
B.Cost.isValid()) {
696 auto [FixedCost, ScalableCost] = std::make_pair(CostA, CostB);
697 if (
B.Width.isFixed())
700 ScalableCost *= Opts.scalable_epilogue_vf_cost_scale_factor;
702 if (FixedCost <= ScalableCost)
703 return A.Width.isFixed();
707 unsigned EstimatedWidthA =
A.Width.getKnownMinValue();
708 unsigned EstimatedWidthB =
B.Width.getKnownMinValue();
710 if (
A.Width.isScalable())
711 EstimatedWidthA *= *VScale;
712 if (
B.Width.isScalable())
713 EstimatedWidthB *= *VScale;
720 return CostA < CostB ||
721 (CostA == CostB && EstimatedWidthA > EstimatedWidthB);
726 bool PreferScalable = !TTI.preferFixedOverScalableIfEqualCost() &&
727 A.Width.isScalable() && !
B.Width.isScalable();
737 bool LowerCostWithoutTC =
738 CmpFn(CostA * EstimatedWidthB, CostB * EstimatedWidthA);
740 return LowerCostWithoutTC;
742 auto GetCostForTC = [MaxTripCount, HasTail](
unsigned VF,
754 return VectorCost * (MaxTripCount / VF) +
755 ScalarCost * (MaxTripCount % VF);
756 return VectorCost *
divideCeil(MaxTripCount, VF);
759 auto RTCostA = GetCostForTC(EstimatedWidthA, CostA,
A.ScalarCost);
760 auto RTCostB = GetCostForTC(EstimatedWidthB, CostB,
B.ScalarCost);
761 bool LowerCostWithTC = CmpFn(RTCostA, RTCostB);
762 LLVM_DEBUG(
if (LowerCostWithTC != LowerCostWithoutTC) {
763 dbgs() <<
"LV: VF " << (LowerCostWithTC ?
A.Width :
B.Width)
764 <<
" has lower cost than VF "
765 << (LowerCostWithTC ?
B.Width :
A.Width)
766 <<
" when taking the cost of the remaining scalar loop iterations "
767 "into consideration for a maximum trip count of "
768 << MaxTripCount <<
".\n";
770 return LowerCostWithTC;
776 bool IsEpilogue)
const {
777 const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
778 return LoopVectorizationPlanner::isMoreProfitable(
A,
B, MaxTripCount, HasTail,
791 "Scalable vectorization requested but not supported by the target",
792 "the scalable user-specified vectorization width for outer-loop "
793 "vectorization cannot be used because the target does not support "
795 "ScalableVFUnfeasible", ORE, TheLoop);
801 unsigned WidestType = getTypeWidthsForVFSelection().WidestType;
803 auto RegKind = TTI.enableScalableVectorization()
810 unsigned N = std::max<uint64_t>(
816 if (Opts.vplan_build_outerloop_stress_test && VF.
isScalar()) {
818 <<
"overriding computed VF.\n");
826 <<
"VF " << VF <<
" to build VPlans.\n");
836 switch (R.getVPRecipeID()) {
837 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
840 case VPRecipeBase::VPWidenIntOrFpInductionSC:
841 return !cast<VPWidenIntOrFpInductionRecipe>(&R)->getPHINode();
842 case VPRecipeBase::VPReductionPHISC: {
843 auto *RedPhi = cast<VPReductionPHIRecipe>(&R);
846 RecurKind Kind = RedPhi->getRecurrenceKind();
847 if (RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(Kind) ||
848 RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) ||
849 !RedPhi->getUnderlyingValue())
856 if (RecurrenceDescriptor::isFindIVRecurrenceKind(Kind))
857 return RedPhi->isExpressionSunk();
866bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
867 VPlan &MainPlan)
const {
877 if (OrigLoop->getExitingBlock() != OrigLoop->getLoopLatch() ||
878 Legal->hasUncountableEarlyExit())
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 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 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...
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.
constexpr bool isPowerOf2() const
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...
const ReductionList & getReductionVars() const
Returns the reduction variables found in the loop.
bool isScalableVectorizationDisabled() const
bool isScalableVectorizationAlwaysPreferred() const
Represents a single loop in the control flow graph.
LLVM_ABI 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...
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.
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.
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)
constexpr bool valueOr(BoolOrDefault X, bool Default)
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.