LLVM 24.0.0git
LoopVectorizationPlanner.h
Go to the documentation of this file.
1//===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file provides a LoopVectorizationPlanner class.
11/// LoopVectorizationPlanner - drives the vectorization process after having
12/// passed Legality checks.
13/// The planner builds and optimizes the Vectorization Plans which record the
14/// decisions how to vectorize the given loop. In particular, represent the
15/// control-flow of the vectorized version, the replication of instructions that
16/// are to be scalarized, and interleave access groups.
17///
18/// Also provides a VPlan-based builder utility analogous to IRBuilder.
19/// It provides an instruction-level API for generating VPInstructions while
20/// abstracting away the Recipe manipulation details.
21//===----------------------------------------------------------------------===//
22
23#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
24#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
25
26#include "VPlan.h"
27#include "VPlanUtils.h"
28#include "llvm/ADT/SmallSet.h"
31#include <optional>
32
33namespace {
34class GeneratedRTChecks;
35}
36
37namespace llvm {
38
40class LoopInfo;
41class DominatorTree;
49struct VPRegisterUsage;
50struct VFRange;
51struct VectorizeOptions;
52
53/// \return An upper bound for vscale based on TTI or the vscale_range
54/// attribute.
55std::optional<unsigned> getMaxVScale(const Function &F);
56
57/// \return The upper bound for the runtime value of \p EC, or std::nullopt
58/// if the upper bound is unknown.
59std::optional<uint64_t>
61
62// Utility functions that are used by different vectorization classes
64
65/// Reports a vectorization failure: print \p DebugMsg for debugging
66/// purposes along with the corresponding optimization remark \p RemarkName.
67/// If \p I is passed, it is an instruction that prevents vectorization.
68/// Otherwise, the loop \p TheLoop is used for the location of the remark.
69void reportVectorizationFailure(const StringRef DebugMsg,
70 const StringRef OREMsg, const StringRef ORETag,
72 const Loop *TheLoop, Instruction *I = nullptr);
73
74/// Same as above, but the debug message and optimization remark are identical
75inline void reportVectorizationFailure(const StringRef DebugMsg,
76 const StringRef ORETag,
78 const Loop *TheLoop,
79 Instruction *I = nullptr) {
80 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
81}
82
83/// Reports an informative message: print \p Msg for debugging purposes as well
84/// as an optimization remark. Uses either \p I as location of the remark, or
85/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
86/// remark.
87void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
89 const Loop *TheLoop, Instruction *I = nullptr,
90 DebugLoc DL = {});
91
92/// Report successful vectorization of the loop. In case an outer loop is
93/// vectorized, prepend "outer" to the vectorization remark.
94void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
95 ElementCount VFWidth, unsigned IC);
96
97} // namespace LoopVectorizationUtils
98
99/// Default inserter for VPBuilderBase, inserting \p R before \p It.
102 R->insertBefore(It);
103 }
104};
105
106/// VPlan-based builder utility similar to IRBuilder. Recipes are inserted via
107/// \p InserterTy.
108template <typename InserterTy> class VPBuilderBase : public InserterTy {
109private:
110 class VPInsertPoint {
111 VPBasicBlock::iterator Iterator;
112
113 public:
114 /// Creates a new insertion point which doesn't point to anything.
115 VPInsertPoint() = default;
116
117 /// Creates a new insertion point to insert before \p Iterator.
118 VPInsertPoint(VPBasicBlock::iterator Iterator) : Iterator(Iterator) {}
119
120 /// Creates a new insertion point to insert before \p R.
121 VPInsertPoint(VPRecipeBase *R) : Iterator(R->getIterator()) {}
122
123 /// Creates a new insertion point to insert at the end of \p Block.
124 VPInsertPoint(VPBasicBlock *Block) : Iterator(Block->end()) {}
125
126 /// Returns true if this insert point is set.
127 operator bool() const { return Iterator.isValid(); }
128
129 VPBasicBlock *getBlock() const {
130 return Iterator.isValid() ? Iterator.getNodeParent() : nullptr;
131 }
132 VPBasicBlock::iterator getIterator() const { return Iterator; }
133
134 operator VPRecipeBase *() const {
135 return Iterator == getBlock()->end() ? nullptr : &*Iterator;
136 }
137 };
138
139 VPInsertPoint InsertPt;
140
141protected:
142 /// Insert \p R at InsertPt if InsertPt is set.
143 template <typename T> T *tryInsertInstruction(T *R) {
144 if (InsertPt)
145 InserterTy::insertHelper(R, InsertPt.getIterator());
146 return R;
147 }
148
151 const VPIRMetadata &MD, DebugLoc DL,
152 const Twine &Name = "") {
154 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
155 }
156
157public:
158 VPlan &getPlan() const {
159 assert(InsertPt && "Insert block must be set");
160 return *InsertPt.getBlock()->getPlan();
161 }
162
163 VPBuilderBase() = default;
164 VPBuilderBase(const VPInsertPoint &IP) : InsertPt(IP) {}
165 VPBuilderBase(InserterTy Inserter) : InserterTy(Inserter) {}
166
167 /// Get the recipe at the current insert point or nullptr if the insert point
168 /// is the end of the block.
169 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
170
171 VPBasicBlock *getInsertBlock() const { return InsertPt.getBlock(); }
172
173 /// Create a builder to insert after \p R.
175 return VPBuilderBase(std::next(R->getIterator()));
176 }
177
178 /// Sets the current insert point to a previously-saved location.
179 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
180
181 /// Set the current insert point.
182 void setInsertPoint(const VPInsertPoint &IP) {
183 assert(IP && "Attempting to set a null insert point");
184 InsertPt = IP;
185 }
186
187 /// Insert \p R at the current insertion point. Returns \p R unchanged.
188 template <typename T> [[maybe_unused]] T *insert(T *R) {
189 InserterTy::insertHelper(R, InsertPt.getIterator());
190 return R;
191 }
192
193 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
194 /// its underlying Instruction.
196 Instruction *Inst = nullptr,
197 const VPIRFlags &Flags = {},
198 const VPIRMetadata &MD = {},
200 const Twine &Name = "", Type *ResultTy = nullptr,
201 const VPIRAttributes &Attrs = {}) {
202 VPInstruction *NewVPInst = tryInsertInstruction(new VPInstruction(
203 Opcode, Operands, Flags, MD, DL, Name, ResultTy, Attrs));
204 NewVPInst->setUnderlyingValue(Inst);
205 return NewVPInst;
206 }
208 DebugLoc DL, const Twine &Name = "") {
209 return createInstruction(Opcode, Operands, {}, DL, Name);
210 }
212 const VPIRFlags &Flags,
214 const Twine &Name = "") {
216 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
217 }
218
220 Type *ResultTy, const VPIRFlags &Flags = {},
222 const Twine &Name = "") {
224 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
225 }
226
229 const Twine &Name = "") {
230 // Assume that the maximum possible number of elements in a vector fits
231 // within the index type for the default address space.
232 VPlan &Plan = getPlan();
233 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
235 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
236 }
237
240 const Twine &Name = "") {
241 // Assume that the maximum possible number of elements in a vector fits
242 // within the index type for the default address space.
243 VPlan &Plan = getPlan();
244 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
246 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
247 }
248
250 unsigned Opcode, ArrayRef<VPValue *> Operands,
251 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
252 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
254 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
255 }
256
259 const Twine &Name = "") {
260 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
261 }
262
265 const Twine &Name = "") {
266 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
267 Name);
268 }
269
272 const Twine &Name = "") {
273
275 Instruction::BinaryOps::Or, {LHS, RHS},
276 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
277 }
278
281 const Twine &Name = "",
282 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
283 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
284 Name);
285 }
286
287 VPInstruction *
289 const Twine &Name = "",
290 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
291 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
292 Name);
293 }
294
300
306
307 /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
308 /// default flags for the result type, unless \p Flags is set.
310 VPValue *FalseVal,
312 const Twine &Name = "",
313 std::optional<VPIRFlags> Flags = std::nullopt) {
315 new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
316 Flags.value_or(VPIRFlags::getDefaultFlags(
317 Instruction::Select, TrueVal->getScalarType())),
318 {}, DL, Name));
319 }
320
321 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
322 /// and \p B.
325 const Twine &Name = "") {
327 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
329 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
330 }
331
332 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
333 /// and \p B.
336 const Twine &Name = "") {
338 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
340 new VPInstruction(Instruction::FCmp, {A, B},
341 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
342 }
343
344 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
345 /// result, then select between \p TrueVal and \p FalseVal.
347 VPValue *FalseVal,
349 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
350 "ChainOp must be i1 for AnyOf reduction");
351 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
352 FastMathFlags());
354 {ChainOp}, Flags, DL);
355 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
356 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
357 }
358
361 const Twine &Name = "") {
362 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
363 }
364
366 GEPNoWrapFlags GEPFlags,
368 const Twine &Name = "") {
370 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
371 }
372
380
381 /// Create a phi with \p IncomingValues, using the default flags for the
382 /// result type, unless \p Flags is set.
385 const Twine &Name = "",
386 std::optional<VPIRFlags> Flags = std::nullopt,
387 Type *ResultTy = nullptr) {
388 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
389 return tryInsertInstruction(new VPPhi(
390 IncomingValues,
391 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
392 DL, Name, ResultTy));
393 }
394
397 const Twine &Name = "") {
398 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
399 }
400
402 VPlan &Plan = getPlan();
403 unsigned MinEC = EC.getKnownMinValue();
404 if (EC.isScalable()) {
405 VPValue *VScale = createVScale(Ty);
406 if (MinEC == 1)
407 return VScale;
408 // TODO: Move this optimization into createOverflowingOp directly.
409 if (isPowerOf2_32(MinEC)) {
410 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
411 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
412 {true, false});
413 }
414 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
415 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
416 {true, false});
417 }
418 return Plan.getConstantInt(Ty, MinEC);
419 }
420
421 /// Convert \p Current to \p Start + \p Current * \p Step.
423 FPMathOperator *FPBinOp, VPValue *Start,
424 VPValue *Current, VPValue *Step,
425 const VPIRFlags::WrapFlagsTy &Flags = {}) {
427 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
428 }
429
431 Type *ResultTy, DebugLoc DL,
432 std::optional<VPIRFlags> Flags = std::nullopt,
433 const VPIRMetadata &Metadata = {}) {
435 Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
436 Metadata, DL, "", ResultTy));
437 }
438
439 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
440 /// result type \p ResultTy
443 Type *ResultTy, DebugLoc DL,
444 const Twine &Name = "") {
445 VPlan &Plan = getPlan();
447 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
449 {}, {}, DL, Name, ResultTy));
450 }
451
452 /// Create a scalar llvm.vscale call.
455 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
456 }
457
459 Type *SrcTy = Op->getScalarType();
460 if (ResultTy == SrcTy)
461 return Op;
462 Instruction::CastOps CastOp =
463 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
464 ? Instruction::Trunc
465 : Instruction::ZExt;
466 return createScalarCast(CastOp, Op, ResultTy, DL);
467 }
468
470 Type *SrcTy = Op->getScalarType();
471 if (ResultTy == SrcTy)
472 return Op;
473 Instruction::CastOps CastOp =
474 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
475 ? Instruction::Trunc
476 : Instruction::SExt;
477 return createScalarCast(CastOp, Op, ResultTy, DL);
478 }
479
481 const Twine &Name = "") {
482 return createNaryOp(Instruction::Freeze, Op, DL, Name);
483 }
484
486 Type *ResultTy) {
487 assert(Op->getScalarType() != ResultTy &&
488 "must not create a no-op cast recipe");
490 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
491 }
492
493 /// Create a single-scalar recipe with \p Opcode and \p Operands without
494 /// inserting it.
495 static VPSingleDefRecipe *
497 VPValue *Mask, const VPIRFlags &Flags,
499 Type *ResultTy, Instruction *UV) {
500 if (Instruction::isCast(Opcode)) {
501 assert(!Mask && "Cast cannot be predicated");
502 auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
503 UV->getName(), ResultTy);
504 VPI->setUnderlyingValue(UV);
505 return VPI;
506 }
507 auto *RepR = new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true,
508 Mask, Flags, Metadata, DL);
509 assert(RepR->getScalarType() == ResultTy && "unexpected result type");
510 return RepR;
511 }
512
515 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
516 VPValue *VF, DebugLoc DL) {
518 IV, Step, VF, InductionOpcode,
519 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
520 }
521
525
527 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
528 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
530 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
531 }
532
533 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
534 /// with element type \p SourceElementTy.
536 Type *SourceElementTy,
537 bool Reverse, DebugLoc DL) {
538 VPlan &Plan = getPlan();
540 if (Reverse) {
541 // When folding the tail, we may compute an address that we don't in the
542 // original scalar loop: drop the GEP no-wrap flags in this case.
543 // Otherwise preserve existing flags without no-unsigned-wrap, as we will
544 // emit negative indices.
545 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
547 : Flags.withoutNoUnsignedWrap();
549 new VPVectorEndPointerRecipe(Ptr, &Plan.getVF(), SourceElementTy,
550 /*Stride=*/-1, ReverseFlags, DL));
551 }
552 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
553 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
554 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
555 }
556
558 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
559 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
561 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
562 }
563
564 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
565 /// be null).
567 VPValue *Mask, bool Consecutive,
568 Align Alignment,
569 const VPIRMetadata &Metadata,
570 DebugLoc DL) {
572 Load, Addr, Mask, Consecutive, Alignment, Metadata, DL));
573 }
574
575 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
576 /// \p Mask (may be null).
578 VPValue *StoredVal, VPValue *Mask,
579 bool Consecutive, Align Alignment,
580 const VPIRMetadata &Metadata,
581 DebugLoc DL) {
583 Store, Addr, StoredVal, Mask, Consecutive, Alignment, Metadata, DL));
584 }
585
586 //===--------------------------------------------------------------------===//
587 // RAII helpers.
588 //===--------------------------------------------------------------------===//
589
590 /// RAII object that stores the current insertion point and restores it when
591 /// the object is destroyed.
593 VPBuilderBase &Builder;
594 VPInsertPoint InsertPt;
595
596 public:
597 InsertPointGuard(VPBuilderBase &B) : Builder(B), InsertPt(B.InsertPt) {}
598
601
602 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
603 };
604};
605
606/// TODO: The following VectorizationFactor was pulled out of
607/// LoopVectorizationCostModel class. LV also deals with
608/// VectorizerParams::VectorizationFactor.
609/// We need to streamline them.
610
611/// Information about vectorization costs.
613 /// Vector width with best cost.
615
616 /// Cost of the loop with that width.
618
619 /// Cost of the scalar loop.
621
622 /// The minimum trip count required to make vectorization profitable, e.g. due
623 /// to runtime checks.
625
629
630 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
632 return {ElementCount::getFixed(1), 0, 0};
633 }
634};
635
636/// A class that represents two vectorization factors (initialized with 0 by
637/// default). One for fixed-width vectorization and one for scalable
638/// vectorization. This can be used by the vectorizer to choose from a range of
639/// fixed and/or scalable VFs in order to find the most cost-effective VF to
640/// vectorize with.
644
646 : FixedVF(ElementCount::getFixed(0)),
647 ScalableVF(ElementCount::getScalable(0)) {}
649 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
650 }
654 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
655 "Invalid scalable properties");
656 }
657
659
660 /// \return true if either fixed- or scalable VF is non-zero.
661 explicit operator bool() const { return FixedVF || ScalableVF; }
662};
663
664/// Holds state needed to make cost decisions before computing costs per-VF,
665/// including the maximum VFs.
667 /// \return True if maximizing vector bandwidth is enabled by the target or
668 /// user options, for the given register kind (scalable or fixed-width).
669 bool useMaxBandwidth(bool IsScalable) const;
670
671 /// \return the maximized element count based on the targets vector
672 /// registers and the loop trip-count, but limited to a maximum safe VF.
673 /// This is a helper function of computeFeasibleMaxVF.
674 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
675 unsigned SmallestType,
676 unsigned WidestType,
677 ElementCount MaxSafeVF, unsigned UserIC,
678 bool FoldTailByMasking,
679 bool RequiresScalarEpilogue);
680
681 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
682 /// that results in VF * UserIC <= MaxTripCount.
683 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
684 unsigned UserIC, bool FoldTailByMasking,
685 bool RequiresScalarEpilogue) const;
686
687 /// Checks if scalable vectorization is supported and enabled. Caches the
688 /// result to avoid repeated debug dumps for repeated queries.
689 bool isScalableVectorizationAllowed();
690
691 /// \return the maximum legal scalable VF, based on the safe max number
692 /// of elements.
693 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
694
695 /// Initializes the value of vscale used for tuning the cost model. If
696 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
697 /// return the value returned by the corresponding TTI method.
698 void initializeVScaleForTuning();
699
700 const VectorizeOptions &Opts;
701 const TargetTransformInfo &TTI;
702 const LoopVectorizationLegality *Legal;
703 const Loop *TheLoop;
704 const Function &F;
706 DemandedBits *DB;
708 const LoopVectorizeHints *Hints;
709
710 /// Cached result of isScalableVectorizationAllowed.
711 std::optional<bool> IsScalableVectorizationAllowed;
712
713 /// Used to store the value of vscale used for tuning the cost model. It is
714 /// initialized during object construction.
715 std::optional<unsigned> VScaleForTuning;
716
717 /// The highest VF possible for this loop, without using MaxBandwidth.
718 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
719
720 /// All element types found in the loop.
721 SmallPtrSet<Type *, 16> ElementTypesInLoop;
722
723 /// PHINodes of the reductions that should be expanded in-loop. Set by
724 /// collectInLoopReductions.
725 SmallPtrSet<PHINode *, 4> InLoopReductions;
726
727 /// Maximum safe number of elements to be processed per vector iteration,
728 /// which do not prevent store-load forwarding and are safe with regard to the
729 /// memory dependencies. Required for EVL-based vectorization, where this
730 /// value is used as the upper bound of the safe AVL. Set by
731 /// computeFeasibleMaxVF.
732 std::optional<unsigned> MaxSafeElements;
733
734 /// Map of scalar integer values to the smallest bitwidth they can be legally
735 /// represented as. The vector equivalents of these values should be truncated
736 /// to this type.
738
739public:
740 /// The kind of cost that we are calculating.
742
743 /// Whether this loop should be optimized for size based on function attribute
744 /// or profile information.
745 const bool OptForSize;
746
747 VFSelectionContext(const VectorizeOptions &Opts,
748 const TargetTransformInfo &TTI,
749 const LoopVectorizationLegality *Legal,
750 const Loop *TheLoop, const Function &F,
753 const LoopVectorizeHints *Hints, bool OptForSize)
754 : Opts(Opts), TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE),
755 DB(DB), ORE(ORE), Hints(Hints),
756 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
758 initializeVScaleForTuning();
759 }
760
761 /// \return The vscale value used for tuning the cost model.
762 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
763
764 const VectorizeOptions &getOpts() const { return Opts; }
765
766 const TargetTransformInfo &getTTI() const { return TTI; }
767
768 PredicatedScalarEvolution &getPSE() const { return PSE; }
769
770 /// \return The loop being analyzed.
771 const Loop *getLoop() const { return TheLoop; }
772
773 /// \return The vectorization hints for the loop being analyzed.
774 const LoopVectorizeHints &getHints() const { return *Hints; }
775
776 /// Returns true if epilogue vectorization is considered profitable for a
777 /// main loop with vectorization factor \p VF and interleave count \p IC.
778 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
779
780 /// \return True if register pressure should be considered for the given VF.
782
783 /// \return True if scalable vectors are supported by the target or forced.
784 bool supportsScalableVectors() const;
785
786 /// Collect element types in the loop that need widening.
788 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
789
790 /// \return The size (in bits) of the smallest and widest types in the code
791 /// that need to be vectorized. We ignore values that remain scalar such as
792 /// 64 bit loop indices.
793 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
794
795 /// \return An upper bound for the vectorization factors for both
796 /// fixed and scalable vectorization, where the minimum-known number of
797 /// elements is a power-of-2 larger than zero. If scalable vectorization is
798 /// disabled or unsupported, then the scalable part will be equal to
799 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
800 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
801 ElementCount UserVF, unsigned UserIC,
802 bool FoldTailByMasking,
803 bool RequiresScalarEpilogue);
804
805 /// Return maximum safe number of elements to be processed per vector
806 /// iteration, which do not prevent store-load forwarding and are safe with
807 /// regard to the memory dependencies. Required for EVL-based VPlans to
808 /// correctly calculate AVL (application vector length) as min(remaining AVL,
809 /// MaxSafeElements). Set by computeFeasibleMaxVF.
810 /// TODO: need to consider adjusting cost model to use this value as a
811 /// vectorization factor for EVL-based vectorization.
812 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
813
814 /// Returns true if we should use strict in-order reductions for the given
815 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
816 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
817 /// of FP operations.
818 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
819
820 /// Returns true if the target machine supports a masked load (if \p IsLoad)
821 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
822 /// space \p AddressSpace. The caller must ensure the access is consecutive or
823 /// part of an interleave group.
824 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
825 unsigned AddressSpace) const;
826
827 /// Returns true if the target machine supports a gather (if \p IsLoad)
828 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
829 /// factor \p VF.
830 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
831 ElementCount VF) const;
832
833 /// Split reductions into those that happen in the loop, and those that
834 /// happen outside. In-loop reductions are collected into InLoopReductions.
836
837 /// Returns true if the Phi is part of an inloop reduction.
838 bool isInLoopReduction(PHINode *Phi) const {
839 return InLoopReductions.contains(Phi);
840 }
841
842 /// Returns the set of in-loop reduction PHIs.
844 return InLoopReductions;
845 }
846
847 /// Check whether vectorization would require runtime checks. When optimizing
848 /// for size, returning true here aborts vectorization.
850
851 /// Returns a scalable VF to use for outer-loop vectorization if the target
852 /// supports it and a fixed VF otherwise.
854
855 /// Compute smallest bitwidth each instruction can be represented with.
856 /// The vector equivalents of these instructions should be truncated to this
857 /// type.
859
860 /// \returns The smallest bitwidth each instruction can be represented with.
862 return MinBWs;
863 }
864};
865
866/// Planner drives the vectorization process after having passed
867/// Legality checks.
869 const VectorizeOptions &Opts;
870
871 /// The loop that we evaluate.
872 Loop *OrigLoop;
873
874 /// Loop Info analysis.
875 LoopInfo *LI;
876
877 /// The dominator tree.
878 DominatorTree *DT;
879
880 /// Target Library Info.
881 const TargetLibraryInfo *TLI;
882
883 /// Target Transform Info.
884 const TargetTransformInfo &TTI;
885
886 /// The legality analysis.
888
889 /// The profitability analysis. Cleared after making cost based decisions.
890 /// This instance should never be used in any function that takes an explicit
891 /// PlanCM reference, since that instance overrides this one.
892 std::unique_ptr<LoopVectorizationCostModel> CM;
893
894 /// VF selection state independent of cost-modeling decisions.
895 VFSelectionContext &Config;
896
898
900
901 /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
902 std::function<const BranchProbabilityInfo &()> GetBPI;
903
905
906 /// Profitable vector factors.
908
909 /// A builder used to construct the current plan.
910 VPBuilder Builder;
911
912 /// Computes the cost of \p Plan for vectorization factor \p VF, using
913 /// \p PlanCM as the cost model.
914 ///
915 /// The current implementation requires access to the
916 /// LoopVectorizationLegality to handle inductions and reductions, which is
917 /// why it is kept separate from the VPlan-only cost infrastructure.
918 ///
919 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
920 /// been retired.
922 LoopVectorizationCostModel &PlanCM) const;
923
924 /// Precompute costs for certain instructions using the legacy cost model. The
925 /// function is used to bring up the VPlan-based cost model to initially avoid
926 /// taking different decisions due to inaccuracies in the legacy cost model.
927 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
928 VPCostContext &CostCtx) const;
929
930public:
932 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
934 std::unique_ptr<LoopVectorizationCostModel> CM,
937 std::function<const BranchProbabilityInfo &()> GetBPI);
938
940
941 /// Return the cost model. Must not be called after clearCostModel().
943 assert(CM && "Cost model has already been cleared");
944 return *CM;
945 }
946
947 /// Destroy the cost model.
948 void clearCostModel();
949
950 /// Return true if there is at least one VPlan for a vector VF
951 bool hasVectorPlan() const {
952 return any_of(
953 VPlans, [&](const VPlanPtr &Plan) { return !Plan->hasScalarVFOnly(); });
954 }
955
956 /// Returns true if there is at least one VPlan.
957 bool hasAPlan() const { return !VPlans.empty(); }
958
959 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
960 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
961 /// interleaving should be avoided up-front, no plans are generated.
962 void plan(ElementCount UserVF, unsigned UserIC);
963
964 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
965 /// for each VF.
966 VPlan &getPlanFor(ElementCount VF) const;
967
968 /// Compute and return the most profitable vectorization factor and the
969 /// corresponding best VPlan. Also collect all profitable VFs in
970 /// ProfitableVFs.
971 std::pair<VectorizationFactor, VPlan *> computeBestVF();
972
973 /// \return The desired interleave count.
974 /// If interleave count has been specified by metadata it will be returned.
975 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
976 /// are the selected vectorization factor and the cost of the selected VF.
977 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
978 InstructionCost LoopCost);
979
980 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
981 /// according to the best selected \p VF and \p UF. \p HasRuntimeChecks is
982 /// used to decide whether runtime unrolling of the scalar loop is disabled.
983 ///
984 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
985 /// fixed.
986 ///
987 /// When vectorizing the main loop, \p TrackedBlocks are updated to the
988 /// VPIRBasicBlocks wrapping the blocks generated for them.
989 ///
990 /// Returns a mapping of SCEVs to their expanded IR values.
991 /// Note that this is a temporary workaround needed due to the current
992 /// epilogue handling.
994 None, ///< Not part of epilogue vectorization.
995 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
996 Epilogue ///< Vectorizing the epilogue loop.
997 };
999 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
1000 bool HasRuntimeChecks,
1001 EpilogueVectorizationKind EpilogueVecKind =
1003 MutableArrayRef<VPBasicBlock *> TrackedBlocks = {});
1004
1005#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1006 void printPlans(raw_ostream &O);
1007#endif
1008
1009 /// Look through the existing plans and return true if we have one with
1010 /// vectorization factor \p VF.
1012 return any_of(VPlans,
1013 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
1014 }
1015
1016 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
1017 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
1018 /// returned value holds for the entire \p Range.
1019 static bool
1020 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
1021 VFRange &Range);
1022
1023 /// \return A VPlan for the most profitable epilogue vectorization, with its
1024 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
1025 /// Returns nullptr if epilogue vectorization is not supported or not
1026 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
1027 /// epilogue lowering policy permits creating a scalar epilogue at all.
1028 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
1029 ElementCount MainLoopVF,
1030 unsigned IC,
1031 bool ScalarEpilogueAllowed);
1032
1033 /// Emit remarks for recipes with invalid costs in the available VPlans.
1035
1036 /// Create a check to \p Plan to see if the vector loop should be executed
1037 /// based on its trip count. When \p TailFoldedEpilogue is true, the
1038 /// tail-folded vector epilogue executes all iterations not executed by
1039 /// the main vector loop, so the check never needs to branch to the scalar
1040 /// loop.
1041 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1042 ElementCount MinProfitableTripCount,
1043 bool TailFoldedEpilogue) const;
1044
1045 /// Attach the runtime checks of \p RTChecks to \p Plan. \p VF and \p UF are
1046 /// used to compute the thresholds of difference checks.
1047 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1048 ElementCount VF, unsigned UF,
1049 bool HasBranchWeights) const;
1050
1051 /// Update loop metadata and profile info for both the scalar remainder loop
1052 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1053 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1054 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1055 /// the average trip count and invocation weight of the original loop (\p
1056 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1057 /// cannot be retrieved after the plan has been executed, as the original loop
1058 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1059 /// target wants the vector loop left eligible for runtime unrolling.
1061 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1062 bool VectorizingEpilogue, MDNode *OrigLoopID,
1063 std::optional<unsigned> OrigAverageTripCount,
1064 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1065 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1066
1067private:
1068 /// Build VPlan for the forced epilogue VF. If vectorization and tail-folding
1069 /// should be avoided up-front, no tail-folded plans are generated.
1070 bool planForEpilogueTF();
1071
1072 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1073 /// scalar transformations applied. Returns null if an initial VPlan cannot
1074 /// be built. \p PlanCM is the cost model to use for decisions made while
1075 /// building the plan.
1076 VPlanPtr tryToBuildVPlan1(LoopVectorizationCostModel &PlanCM);
1077
1078 /// Build a VPlan using VPRecipes according to the information gathered by
1079 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1080 /// conversion only. For inner loops, \p Range's largest included VF is
1081 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1082 /// can be built for the input range, set the largest included VF to the
1083 /// maximum VF for which no plan could be built. Each VPlan is built starting
1084 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1085 /// original scalar loop. \p PlanCM is the cost model used for legality
1086 /// and widening decisions while building the plan.
1087 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range,
1089
1090 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1091 /// based on \p VPlan1 and according to the information gathered by Legal
1092 /// when it checked if it is legal to vectorize the loop. \p PlanCM is
1093 /// the cost model to build these VPlans.
1094 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF,
1096
1097 /// Add ComputeReductionResult recipes to the middle block to compute the
1098 /// final reduction results. Add Select recipes to the latch block when
1099 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1100 /// iteration values according to the header mask. \p PlanCM is the cost
1101 /// model used to build \p Plan.
1102 void addReductionResultComputation(VPlanPtr &Plan, ElementCount MinVF,
1104
1105 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1106 /// that of B.
1107 bool isMoreProfitable(const VectorizationFactor &A,
1108 const VectorizationFactor &B, bool HasTail,
1109 bool IsEpilogue = false) const;
1110
1111 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1112 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1113 bool isMoreProfitable(const VectorizationFactor &A,
1114 const VectorizationFactor &B,
1115 const unsigned MaxTripCount, bool HasTail,
1116 bool IsEpilogue = false) const;
1117
1118 /// Determines if we have the infrastructure to vectorize the loop and its
1119 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1120 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1121};
1122
1123} // namespace llvm
1124
1125#endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
bool IsScalable
SDValue Pred
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")
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
SmallVector< MachineOperand, 4 > Cond
SI Fold Operands
const char * Msg
This file defines the SmallSet class.
This pass exposes codegen information to IR-level passes.
This file contains the declarations of the Vectorization Plan base classes:
Value * RHS
Value * LHS
static const uint32_t IV[8]
Definition blake3_impl.h:83
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Analysis providing branch probability information.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Definition Operator.h:291
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
InductionKind
This enum represents the kinds of inductions that we support.
bool isCast() const
An instruction for reading from memory.
LoopVectorizationCostModel - estimates the expected speedups due to vectorization.
LoopVectorizationLegality checks if it is legal to vectorize a loop, and to what vectorization factor...
EpilogueVectorizationKind
Generate the IR code for the vectorized loop captured in VPlan BestPlan according to the best selecte...
@ MainLoop
Vectorizing the main loop of epilogue vectorization.
void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount, bool TailFoldedEpilogue) const
Create a check to Plan to see if the vector loop should be executed based on its trip count.
void clearCostModel()
Destroy the cost model.
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
Definition VPlan.cpp:1661
void updateLoopMetadataAndProfileInfo(Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan, bool VectorizingEpilogue, MDNode *OrigLoopID, std::optional< unsigned > OrigAverageTripCount, unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF, bool DisableRuntimeUnroll, bool UnrollVectorizedLoop)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
Definition VPlan.cpp:1712
bool hasAPlan() const
Returns true if there is at least one VPlan.
LoopVectorizationCostModel & getCostModel()
Return the cost model. Must not be called after clearCostModel().
LoopVectorizationPlanner(Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, const TargetTransformInfo &TTI, LoopVectorizationLegality *Legal, std::unique_ptr< LoopVectorizationCostModel > CM, VFSelectionContext &Config, PredicatedScalarEvolution &PSE, OptimizationRemarkEmitter *ORE, std::function< const BranchProbabilityInfo &()> GetBPI)
unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF, InstructionCost LoopCost)
void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, ElementCount VF, unsigned UF, bool HasBranchWeights) const
Attach the runtime checks of RTChecks to Plan.
bool hasVectorPlan() const
Return true if there is at least one VPlan for a vector VF.
void emitInvalidCostRemarks(OptimizationRemarkEmitter *ORE)
Emit remarks for recipes with invalid costs in the available VPlans.
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1647
DenseMap< const SCEV *, Value * > executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan, bool HasRuntimeChecks, EpilogueVectorizationKind EpilogueVecKind=EpilogueVectorizationKind::None, MutableArrayRef< VPBasicBlock * > TrackedBlocks={})
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1816
std::unique_ptr< VPlan > selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC, bool ScalarEpilogueAllowed)
void plan(ElementCount UserVF, unsigned UserIC)
Build VPlans for the specified UserVF and UserIC if they are non-zero or all applicable candidate VFs...
bool hasPlanWithVF(ElementCount VF) const
Look through the existing plans and return true if we have one with vectorization factor VF.
std::pair< VectorizationFactor, VPlan * > computeBestVF()
Compute and return the most profitable vectorization factor and the corresponding best VPlan.
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:39
Root of the metadata hierarchy.
Definition Metadata.h:64
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
The optimization diagnostic interface.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an analyzed expression in the program.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
Holds state needed to make cost decisions before computing costs per-VF, including the maximum VFs.
PredicatedScalarEvolution & getPSE() const
const VectorizeOptions & getOpts() const
const bool OptForSize
Whether this loop should be optimized for size based on function attribute or profile information.
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 isInLoopReduction(PHINode *Phi) const
Returns true if the Phi is part of an inloop reduction.
std::pair< unsigned, unsigned > getSmallestAndWidestTypes() const
const TTI::TargetCostKind CostKind
The kind of cost that we are calculating.
VFSelectionContext(const VectorizeOptions &Opts, const TargetTransformInfo &TTI, const LoopVectorizationLegality *Legal, const Loop *TheLoop, const Function &F, PredicatedScalarEvolution &PSE, DemandedBits *DB, OptimizationRemarkEmitter *ORE, const LoopVectorizeHints *Hints, bool OptForSize)
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.
const TargetTransformInfo & getTTI() const
const SmallPtrSetImpl< PHINode * > & getInLoopReductions() const
Returns the set of in-loop reduction PHIs.
std::optional< unsigned > getMaxSafeElements() const
Return maximum safe number of elements to be processed per vector iteration, which do not prevent sto...
FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC, bool FoldTailByMasking, bool RequiresScalarEpilogue)
const MapVector< Instruction *, uint64_t > & getMinimalBitwidths() const
const LoopVectorizeHints & getHints() const
bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const
Returns true if epilogue vectorization is considered profitable for a main loop with vectorization fa...
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.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4522
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4553
iterator end()
Definition VPlan.h:4563
InsertPointGuard(const InsertPointGuard &)=delete
InsertPointGuard & operator=(const InsertPointGuard &)=delete
VPInstruction * createFreeze(VPValue *Op, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRMetadata &MD, DebugLoc DL, const Twine &Name="")
static VPBuilderBase getToInsertAfter(VPRecipeBase *R)
Create a builder to insert after R.
void restoreIP(VPInsertPoint IP)
Sets the current insert point to a previously-saved location.
VPVectorPointerRecipe * createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createWidePtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnyOfReduction(VPValue *ChainOp, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown())
Create an AnyOf reduction pattern: or-reduce ChainOp, freeze the result, then select between TrueVal ...
T * tryInsertInstruction(T *R)
Insert R at InsertPt if InsertPt is set.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags GEPFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
VPExpandSCEVRecipe * createExpandSCEV(const SCEV *Expr)
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Convert Current to Start + Current * Step.
VPBuilderBase(const VPInsertPoint &IP)
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Type *ResultTy, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPWidenLoadRecipe * createWidenLoad(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Load, loading from Addr with Mask (may be null).
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPBasicBlock * getInsertBlock() const
VPInstruction * createVScale(Type *ResultTy, DebugLoc DL=DebugLoc::getUnknown())
Create a scalar llvm.vscale call.
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, std::optional< VPIRFlags > Flags=std::nullopt, const VPIRMetadata &Metadata={})
VPInstruction * createScalarIntrinsic(Intrinsic::ID IntrinsicID, ArrayRef< VPValue * > Operands, Type *ResultTy, DebugLoc DL, const Twine &Name="")
Create a scalar call to the intrinsic IntrinsicID with Operands, and result type ResultTy.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPBuilderBase()=default
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr, const VPIRAttributes &Attrs={})
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
VPSingleDefRecipe * createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, bool Reverse, DebugLoc DL)
Create a vector pointer recipe for a consecutive memory access to Ptr with element type SourceElement...
VPInstruction * createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPWidenMemIntrinsicRecipe * createWidenMemIntrinsic(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL)
VPInstruction * createFirstActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilderBase(InserterTy Inserter)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPWidenPHIRecipe * createWidenPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createElementCount(Type *Ty, ElementCount EC)
VPWidenStoreRecipe * createWidenStore(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Store, storing StoredVal to Addr with Mask (may be null).
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4292
Recipe to expand a SCEV expression.
Definition VPlan.h:4116
Class to record and manage LLVM IR flags.
Definition VPlan.h:683
static LLVM_ABI_FOR_TEST VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
Helper to manage IR metadata for recipes.
Definition VPlan.h:1152
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1322
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1449
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1381
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:402
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3484
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4353
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:605
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2306
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2388
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1888
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2065
A recipe for widened phis.
Definition VPlan.h:2766
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4940
const DataLayout & getDataLayout() const
Definition VPlan.h:5141
LLVMContext & getContext() const
Definition VPlan.h:5137
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:5053
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5128
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
Definition VPlan.h:5247
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
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.
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
VPBuilderBase<> VPBuilder
Definition VPlan.h:66
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
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.
Definition MathExtras.h:280
@ Or
Bitwise or logical OR of integers.
DWARFExpression::Operation Op
std::optional< unsigned > getMaxVScale(const Function &F)
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:76
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A class that represents two vectorization factors (initialized with 0 by default).
FixedScalableVFPair(const ElementCount &FixedVF, const ElementCount &ScalableVF)
FixedScalableVFPair(const ElementCount &Max)
static FixedScalableVFPair getNone()
A range of powers-of-2 vectorization factors with fixed start and adjustable end.
Default inserter for VPBuilderBase, inserting R before It.
void insertHelper(VPRecipeBase *R, VPBasicBlock::iterator It)
Struct to hold various analysis needed for cost computations.
A struct that represents some properties of the register usage of a loop.
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3899
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:4007
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class.
InstructionCost Cost
Cost of the loop with that width.
ElementCount MinProfitableTripCount
The minimum trip count required to make vectorization profitable, e.g.
ElementCount Width
Vector width with best cost.
InstructionCost ScalarCost
Cost of the scalar loop.
static VectorizationFactor Disabled()
Width 1 means no vectorization, cost 0 means uncomputed cost.
VectorizationFactor(ElementCount Width, InstructionCost Cost, InstructionCost ScalarCost)