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/// InnerLoopVectorizer vectorizes loops which contain only one basic
12/// LoopVectorizationPlanner - drives the vectorization process after having
13/// passed Legality checks.
14/// The planner builds and optimizes the Vectorization Plans which record the
15/// decisions how to vectorize the given loop. In particular, represent the
16/// control-flow of the vectorized version, the replication of instructions that
17/// are to be scalarized, and interleave access groups.
18///
19/// Also provides a VPlan-based builder utility analogous to IRBuilder.
20/// It provides an instruction-level API for generating VPInstructions while
21/// abstracting away the Recipe manipulation details.
22//===----------------------------------------------------------------------===//
23
24#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
25#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
26
27#include "VPlan.h"
28#include "llvm/ADT/SmallSet.h"
31#include <optional>
32
33namespace {
34class GeneratedRTChecks;
35}
36
37namespace llvm {
38
39class LoopInfo;
40class DominatorTree;
46class LoopVersioning;
49class VPRecipeBuilder;
50struct VPRegisterUsage;
51struct VFRange;
52
56
57/// \return An upper bound for vscale based on TTI or the vscale_range
58/// attribute.
59std::optional<unsigned> getMaxVScale(const Function &F);
60
61/// \return The upper bound for the runtime value of \p EC, or std::nullopt
62/// if the upper bound is unknown.
63std::optional<uint64_t>
65
66// Utility functions that are used by different vectorization classes
68
69/// Reports a vectorization failure: print \p DebugMsg for debugging
70/// purposes along with the corresponding optimization remark \p RemarkName.
71/// If \p I is passed, it is an instruction that prevents vectorization.
72/// Otherwise, the loop \p TheLoop is used for the location of the remark.
73void reportVectorizationFailure(const StringRef DebugMsg,
74 const StringRef OREMsg, const StringRef ORETag,
76 const Loop *TheLoop, Instruction *I = nullptr);
77
78/// Same as above, but the debug message and optimization remark are identical
79inline void reportVectorizationFailure(const StringRef DebugMsg,
80 const StringRef ORETag,
82 const Loop *TheLoop,
83 Instruction *I = nullptr) {
84 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
85}
86
87/// Reports an informative message: print \p Msg for debugging purposes as well
88/// as an optimization remark. Uses either \p I as location of the remark, or
89/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
90/// remark.
91void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
93 const Loop *TheLoop, Instruction *I = nullptr,
94 DebugLoc DL = {});
95
96/// Report successful vectorization of the loop. In case an outer loop is
97/// vectorized, prepend "outer" to the vectorization remark.
98void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
99 ElementCount VFWidth, unsigned IC);
100
101} // namespace LoopVectorizationUtils
102
103/// VPlan-based builder utility analogous to IRBuilder.
105private:
106 class VPInsertPoint {
107 VPBasicBlock *Block = nullptr;
109
110 public:
111 /// Creates a new insertion point which doesn't point to anything.
112 VPInsertPoint() = default;
113
114 /// Creates a new insertion point to insert at \p Point in \p Block.
115 VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Point)
116 : Block(Block), Point(Point) {}
117
118 /// Creates a new insertion point to insert before \p R.
119 VPInsertPoint(VPRecipeBase *R)
120 : Block(R->getParent()), Point(R->getIterator()) {}
121
122 /// Creates a new insertion point to insert at the end of \p Block.
123 VPInsertPoint(VPBasicBlock *Block) : Block(Block), Point(Block->end()) {}
124
125 /// Returns true if this insert point is set.
126 operator bool() const { return Block; }
127
128 VPBasicBlock *getBlock() const { return Block; }
129
130 operator VPRecipeBase *() const {
131 return Point == Block->end() ? nullptr : &*Point;
132 }
133
134 template <typename T> void insert(T &R) { return Block->insert(R, Point); }
135 };
136
137 VPInsertPoint InsertPt;
138
139 /// Insert \p VPI in BB at InsertPt if BB is set.
140 template <typename T> T *tryInsertInstruction(T *R) {
141 if (InsertPt)
142 InsertPt.insert(R);
143 return R;
144 }
145
146 VPInstruction *createInstruction(unsigned Opcode,
148 const VPIRMetadata &MD, DebugLoc DL,
149 const Twine &Name = "") {
150 return tryInsertInstruction(
151 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
152 }
153
154public:
155 VPlan &getPlan() const {
156 assert(InsertPt && "Insert block must be set");
157 return *InsertPt.getBlock()->getPlan();
158 }
159
160 VPBuilder() = default;
161 VPBuilder(const VPInsertPoint &IP) : InsertPt(IP) {}
163 : InsertPt(TheBB, IP) {}
164
165 /// Get the recipe at the current insert point or nullptr if the insert point
166 /// is the end of the block.
167 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
168
169 /// Create a VPBuilder to insert after \p R.
171 return {R->getParent(), std::next(R->getIterator())};
172 }
173
174 /// Sets the current insert point to a previously-saved location.
175 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
176
177 /// Set the current insert point.
178 void setInsertPoint(const VPInsertPoint &IP) {
179 assert(IP && "Attempting to set a null insert point");
180 InsertPt = IP;
181 }
183 assert(TheBB && "Attempting to set a null insert point");
184 InsertPt = VPInsertPoint(TheBB, 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 InsertPt.insert(R);
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 = "",
201 Type *ResultTy = nullptr) {
202 VPInstruction *NewVPInst = tryInsertInstruction(
203 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
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 = "") {
215 return tryInsertInstruction(
216 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
217 }
218
220 Type *ResultTy, const VPIRFlags &Flags = {},
222 const Twine &Name = "") {
223 return tryInsertInstruction(new VPInstructionWithType(
224 Opcode, Operands, ResultTy, Flags, {}, DL, Name));
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);
234 return tryInsertInstruction(new VPInstruction(
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);
245 return tryInsertInstruction(new VPInstruction(
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 = "") {
253 return tryInsertInstruction(
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
274 return tryInsertInstruction(new VPInstruction(
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) {
314 return tryInsertInstruction(
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");
328 return tryInsertInstruction(
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");
339 return tryInsertInstruction(
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
352 const Twine &Name = "") {
353 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
354 }
355
357 GEPNoWrapFlags GEPFlags,
359 const Twine &Name = "") {
360 return tryInsertInstruction(new VPInstruction(
361 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
362 }
363
366 const Twine &Name = "") {
367 return tryInsertInstruction(
369 GEPNoWrapFlags::none(), {}, DL, Name));
370 }
371
372 /// Create a phi with \p IncomingValues, using the default flags for the
373 /// result type, unless \p Flags is set.
376 const Twine &Name = "",
377 std::optional<VPIRFlags> Flags = std::nullopt,
378 Type *ResultTy = nullptr) {
379 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
380 return tryInsertInstruction(new VPPhi(
381 IncomingValues,
382 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
383 DL, Name, ResultTy));
384 }
385
388 const Twine &Name = "") {
389 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
390 }
391
393 VPlan &Plan = getPlan();
394 unsigned MinEC = EC.getKnownMinValue();
395 if (EC.isScalable()) {
396 VPValue *VScale = createVScale(Ty);
397 if (MinEC == 1)
398 return VScale;
399 // TODO: Move this optimization into createOverflowingOp directly.
400 if (isPowerOf2_32(MinEC)) {
401 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
402 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
403 {true, false});
404 }
405 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
406 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
407 {true, false});
408 }
409 return Plan.getConstantInt(Ty, MinEC);
410 }
411
412 /// Convert \p Current to \p Start + \p Current * \p Step.
414 FPMathOperator *FPBinOp, VPValue *Start,
415 VPValue *Current, VPValue *Step,
416 const VPIRFlags::WrapFlagsTy &Flags = {}) {
417 return tryInsertInstruction(
418 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
419 }
420
422 DebugLoc DL,
423 const VPIRMetadata &Metadata = {}) {
424 return tryInsertInstruction(new VPInstructionWithType(
425 Instruction::Load, Addr, ResultTy, {}, Metadata, DL));
426 }
427
429 Type *ResultTy, DebugLoc DL,
430 std::optional<VPIRFlags> Flags = std::nullopt,
431 const VPIRMetadata &Metadata = {}) {
432 return tryInsertInstruction(new VPInstructionWithType(
433 Opcode, Op, ResultTy,
434 Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)), Metadata, DL));
435 }
436
437 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
438 /// result type \p ResultTy
441 Type *ResultTy, DebugLoc DL) {
442 VPlan &Plan = getPlan();
444 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
445 return tryInsertInstruction(new VPInstructionWithType(
446 VPInstruction::Intrinsic, Ops, ResultTy, {}, {}, DL));
447 }
448
449 /// Create a scalar llvm.vscale call.
452 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
453 }
454
456 Type *SrcTy = Op->getScalarType();
457 if (ResultTy == SrcTy)
458 return Op;
459 Instruction::CastOps CastOp =
460 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
461 ? Instruction::Trunc
462 : Instruction::ZExt;
463 return createScalarCast(CastOp, Op, ResultTy, DL);
464 }
465
467 Type *SrcTy = Op->getScalarType();
468 if (ResultTy == SrcTy)
469 return Op;
470 Instruction::CastOps CastOp =
471 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
472 ? Instruction::Trunc
473 : Instruction::SExt;
474 return createScalarCast(CastOp, Op, ResultTy, DL);
475 }
476
478 return tryInsertInstruction(
479 new VPInstruction(Instruction::Freeze, Op, {}, {}, DL));
480 }
481
483 Type *ResultTy) {
484 return tryInsertInstruction(new VPWidenCastRecipe(
485 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
486 }
487
488 /// Create a single-scalar recipe with \p Opcode and \p Operands without
489 /// inserting it.
492 VPValue *Mask,
493 const VPIRFlags &Flags,
494 const VPIRMetadata &Metadata,
495 DebugLoc DL, Instruction *UV) {
496 if (Instruction::isCast(Opcode)) {
497 assert(!Mask && "Cast cannot be predicated");
498 return new VPInstructionWithType(Opcode, Operands, UV->getType(), Flags,
499 Metadata, DL, UV->getName(), UV);
500 }
501 return new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true, Mask,
502 Flags, Metadata, DL);
503 }
504
507 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
508 VPValue *VF, DebugLoc DL) {
509 return tryInsertInstruction(new VPScalarIVStepsRecipe(
510 IV, Step, VF, InductionOpcode,
511 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
512 }
513
515 return tryInsertInstruction(new VPExpandSCEVRecipe(Expr));
516 }
517
519 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
520 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
521 return tryInsertInstruction(
522 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
523 }
524
525 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
526 /// with element type \p SourceElementTy.
528 Type *SourceElementTy,
529 bool Reverse, DebugLoc DL);
530
532 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
533 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
534 return tryInsertInstruction(new VPWidenMemIntrinsicRecipe(
535 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
536 }
537
538 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
539 /// be null).
541 VPValue *Mask, bool Consecutive,
542 const VPIRMetadata &Metadata,
543 DebugLoc DL) {
544 return tryInsertInstruction(
545 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
546 }
547
548 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
549 /// \p Mask (may be null).
551 VPValue *StoredVal, VPValue *Mask,
552 bool Consecutive,
553 const VPIRMetadata &Metadata,
554 DebugLoc DL) {
555 return tryInsertInstruction(new VPWidenStoreRecipe(
556 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
557 }
558
559 //===--------------------------------------------------------------------===//
560 // RAII helpers.
561 //===--------------------------------------------------------------------===//
562
563 /// RAII object that stores the current insertion point and restores it when
564 /// the object is destroyed.
566 VPBuilder &Builder;
567 VPInsertPoint InsertPt;
568
569 public:
570 InsertPointGuard(VPBuilder &B) : Builder(B), InsertPt(B.InsertPt) {}
571
574
575 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
576 };
577};
578
579/// TODO: The following VectorizationFactor was pulled out of
580/// LoopVectorizationCostModel class. LV also deals with
581/// VectorizerParams::VectorizationFactor.
582/// We need to streamline them.
583
584/// Information about vectorization costs.
586 /// Vector width with best cost.
588
589 /// Cost of the loop with that width.
591
592 /// Cost of the scalar loop.
594
595 /// The minimum trip count required to make vectorization profitable, e.g. due
596 /// to runtime checks.
598
602
603 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
605 return {ElementCount::getFixed(1), 0, 0};
606 }
607
608 bool operator==(const VectorizationFactor &rhs) const {
609 return Width == rhs.Width && Cost == rhs.Cost;
610 }
611
612 bool operator!=(const VectorizationFactor &rhs) const {
613 return !(*this == rhs);
614 }
615};
616
617/// A class that represents two vectorization factors (initialized with 0 by
618/// default). One for fixed-width vectorization and one for scalable
619/// vectorization. This can be used by the vectorizer to choose from a range of
620/// fixed and/or scalable VFs in order to find the most cost-effective VF to
621/// vectorize with.
625
627 : FixedVF(ElementCount::getFixed(0)),
628 ScalableVF(ElementCount::getScalable(0)) {}
630 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
631 }
635 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
636 "Invalid scalable properties");
637 }
638
640
641 /// \return true if either fixed- or scalable VF is non-zero.
642 explicit operator bool() const { return FixedVF || ScalableVF; }
643
644 /// \return true if either fixed- or scalable VF is a valid vector VF.
645 bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); }
646};
647
648/// Holds state needed to make cost decisions before computing costs per-VF,
649/// including the maximum VFs.
651 /// \return True if maximizing vector bandwidth is enabled by the target or
652 /// user options, for the given register kind (scalable or fixed-width).
653 bool useMaxBandwidth(bool IsScalable) const;
654
655 /// \return the maximized element count based on the targets vector
656 /// registers and the loop trip-count, but limited to a maximum safe VF.
657 /// This is a helper function of computeFeasibleMaxVF.
658 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
659 unsigned SmallestType,
660 unsigned WidestType,
661 ElementCount MaxSafeVF, unsigned UserIC,
662 bool FoldTailByMasking,
663 bool RequiresScalarEpilogue);
664
665 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
666 /// that results in VF * UserIC <= MaxTripCount.
667 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
668 unsigned UserIC, bool FoldTailByMasking,
669 bool RequiresScalarEpilogue) const;
670
671 /// Checks if scalable vectorization is supported and enabled. Caches the
672 /// result to avoid repeated debug dumps for repeated queries.
673 bool isScalableVectorizationAllowed();
674
675 /// \return the maximum legal scalable VF, based on the safe max number
676 /// of elements.
677 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
678
679 /// Initializes the value of vscale used for tuning the cost model. If
680 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
681 /// return the value returned by the corresponding TTI method.
682 void initializeVScaleForTuning();
683
684 const TargetTransformInfo &TTI;
685 const LoopVectorizationLegality *Legal;
686 const Loop *TheLoop;
687 const Function &F;
689 DemandedBits *DB;
691 const LoopVectorizeHints *Hints;
692
693 /// Cached result of isScalableVectorizationAllowed.
694 std::optional<bool> IsScalableVectorizationAllowed;
695
696 /// Used to store the value of vscale used for tuning the cost model. It is
697 /// initialized during object construction.
698 std::optional<unsigned> VScaleForTuning;
699
700 /// The highest VF possible for this loop, without using MaxBandwidth.
701 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
702
703 /// All element types found in the loop.
704 SmallPtrSet<Type *, 16> ElementTypesInLoop;
705
706 /// PHINodes of the reductions that should be expanded in-loop. Set by
707 /// collectInLoopReductions.
708 SmallPtrSet<PHINode *, 4> InLoopReductions;
709
710 /// A Map of inloop reduction operations and their immediate chain operand.
711 /// FIXME: This can be removed once reductions can be costed correctly in
712 /// VPlan. This was added to allow quick lookup of the inloop operations.
713 /// Set by collectInLoopReductions.
714 DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
715
716 /// Maximum safe number of elements to be processed per vector iteration,
717 /// which do not prevent store-load forwarding and are safe with regard to the
718 /// memory dependencies. Required for EVL-based vectorization, where this
719 /// value is used as the upper bound of the safe AVL. Set by
720 /// computeFeasibleMaxVF.
721 std::optional<unsigned> MaxSafeElements;
722
723 /// Map of scalar integer values to the smallest bitwidth they can be legally
724 /// represented as. The vector equivalents of these values should be truncated
725 /// to this type.
727
728public:
729 /// The kind of cost that we are calculating.
731
732 /// Whether this loop should be optimized for size based on function attribute
733 /// or profile information.
734 const bool OptForSize;
735
737 const LoopVectorizationLegality *Legal,
738 const Loop *TheLoop, const Function &F,
741 const LoopVectorizeHints *Hints, bool OptForSize)
742 : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
743 ORE(ORE), Hints(Hints),
744 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
746 initializeVScaleForTuning();
747 }
748
749 /// \return The vscale value used for tuning the cost model.
750 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
751
752 const TargetTransformInfo &getTTI() const { return TTI; }
753
754 PredicatedScalarEvolution &getPSE() const { return PSE; }
755
756 /// \return The loop being analyzed.
757 const Loop *getLoop() const { return TheLoop; }
758
759 /// \return The vectorization hints for the loop being analyzed.
760 const LoopVectorizeHints &getHints() const { return *Hints; }
761
762 /// Returns true if epilogue vectorization is considered profitable for a
763 /// main loop with vectorization factor \p VF and interleave count \p IC.
764 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
765
766 /// \return True if register pressure should be considered for the given VF.
768
769 /// \return True if scalable vectors are supported by the target or forced.
770 bool supportsScalableVectors() const;
771
772 /// Collect element types in the loop that need widening.
774 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
775
776 /// \return The size (in bits) of the smallest and widest types in the code
777 /// that need to be vectorized. We ignore values that remain scalar such as
778 /// 64 bit loop indices.
779 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
780
781 /// \return An upper bound for the vectorization factors for both
782 /// fixed and scalable vectorization, where the minimum-known number of
783 /// elements is a power-of-2 larger than zero. If scalable vectorization is
784 /// disabled or unsupported, then the scalable part will be equal to
785 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
786 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
787 ElementCount UserVF, unsigned UserIC,
788 bool FoldTailByMasking,
789 bool RequiresScalarEpilogue);
790
791 /// Return maximum safe number of elements to be processed per vector
792 /// iteration, which do not prevent store-load forwarding and are safe with
793 /// regard to the memory dependencies. Required for EVL-based VPlans to
794 /// correctly calculate AVL (application vector length) as min(remaining AVL,
795 /// MaxSafeElements). Set by computeFeasibleMaxVF.
796 /// TODO: need to consider adjusting cost model to use this value as a
797 /// vectorization factor for EVL-based vectorization.
798 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
799
800 /// Returns true if we should use strict in-order reductions for the given
801 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
802 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
803 /// of FP operations.
804 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
805
806 /// Returns true if the target machine supports a masked load (if \p IsLoad)
807 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
808 /// space \p AddressSpace. The caller must ensure the access is consecutive or
809 /// part of an interleave group.
810 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
811 unsigned AddressSpace) const;
812
813 /// Returns true if the target machine supports a gather (if \p IsLoad)
814 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
815 /// factor \p VF.
816 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
817 ElementCount VF) const;
818
819 /// Split reductions into those that happen in the loop, and those that
820 /// happen outside. In-loop reductions are collected into InLoopReductions.
821 /// InLoopReductionImmediateChains is filled with each in-loop reduction
822 /// operation and its immediate chain operand for use during cost modelling.
824
825 /// Returns true if the Phi is part of an inloop reduction.
826 bool isInLoopReduction(PHINode *Phi) const {
827 return InLoopReductions.contains(Phi);
828 }
829
830 /// Returns the set of in-loop reduction PHIs.
832 return InLoopReductions;
833 }
834
835 /// Returns the immediate chain operand of in-loop reduction operation \p I,
836 /// or nullptr if \p I is not an in-loop reduction operation.
838 return InLoopReductionImmediateChains.lookup(I);
839 }
840
841 /// Check whether vectorization would require runtime checks. When optimizing
842 /// for size, returning true here aborts vectorization.
844
845 /// Returns a scalable VF to use for outer-loop vectorization if the target
846 /// supports it and a fixed VF otherwise.
848
849 /// Compute smallest bitwidth each instruction can be represented with.
850 /// The vector equivalents of these instructions should be truncated to this
851 /// type.
853
854 /// \returns The smallest bitwidth each instruction can be represented with.
856 return MinBWs;
857 }
858};
859
860/// Planner drives the vectorization process after having passed
861/// Legality checks.
863 /// The loop that we evaluate.
864 Loop *OrigLoop;
865
866 /// Loop Info analysis.
867 LoopInfo *LI;
868
869 /// The dominator tree.
870 DominatorTree *DT;
871
872 /// Target Library Info.
873 const TargetLibraryInfo *TLI;
874
875 /// Target Transform Info.
876 const TargetTransformInfo &TTI;
877
878 /// The legality analysis.
880
881 /// The profitability analysis. Cleared after making cost based decisions.
882 std::unique_ptr<LoopVectorizationCostModel> CM;
883
884 /// VF selection state independent of cost-modeling decisions.
885 VFSelectionContext &Config;
886
887 /// The interleaved access analysis.
889
891
893
895
896 /// Profitable vector factors.
898
899 /// A builder used to construct the current plan.
900 VPBuilder Builder;
901
902 /// Computes the cost of \p Plan for vectorization factor \p VF.
903 ///
904 /// The current implementation requires access to the
905 /// LoopVectorizationLegality to handle inductions and reductions, which is
906 /// why it is kept separate from the VPlan-only cost infrastructure.
907 ///
908 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
909 /// been retired.
910 InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;
911
912 /// Precompute costs for certain instructions using the legacy cost model. The
913 /// function is used to bring up the VPlan-based cost model to initially avoid
914 /// taking different decisions due to inaccuracies in the legacy cost model.
915 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
916 VPCostContext &CostCtx) const;
917
918public:
920 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
922 std::unique_ptr<LoopVectorizationCostModel> CM,
925
927
928 /// Return the cost model. Must not be called after clearCostModel().
930 assert(CM && "Cost model has already been cleared");
931 return *CM;
932 }
933
934 /// Destroy the cost model.
935 void clearCostModel();
936
937 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
938 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
939 /// interleaving should be avoided up-front, no plans are generated.
940 void plan(ElementCount UserVF, unsigned UserIC);
941
942 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
943 /// for each VF.
944 VPlan &getPlanFor(ElementCount VF) const;
945
946 /// Compute and return the most profitable vectorization factor and the
947 /// corresponding best VPlan. Also collect all profitable VFs in
948 /// ProfitableVFs.
949 std::pair<VectorizationFactor, VPlan *> computeBestVF();
950
951 /// \return The desired interleave count.
952 /// If interleave count has been specified by metadata it will be returned.
953 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
954 /// are the selected vectorization factor and the cost of the selected VF.
955 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
956 InstructionCost LoopCost);
957
958 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
959 /// according to the best selected \p VF and \p UF.
960 ///
961 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
962 /// fixed.
963 ///
964 /// Returns a mapping of SCEVs to their expanded IR values.
965 /// Note that this is a temporary workaround needed due to the current
966 /// epilogue handling.
968 None, ///< Not part of epilogue vectorization.
969 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
970 Epilogue ///< Vectorizing the epilogue loop.
971 };
973 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
975 EpilogueVectorizationKind EpilogueVecKind =
977
978#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
979 void printPlans(raw_ostream &O);
980#endif
981
982 /// Look through the existing plans and return true if we have one with
983 /// vectorization factor \p VF.
985 return any_of(VPlans,
986 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
987 }
988
989 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
990 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
991 /// returned value holds for the entire \p Range.
992 static bool
993 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
994 VFRange &Range);
995
996 /// \return A VPlan for the most profitable epilogue vectorization, with its
997 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
998 /// Returns nullptr if epilogue vectorization is not supported or not
999 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
1000 /// epilogue lowering policy permits creating a scalar epilogue at all.
1001 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
1002 ElementCount MainLoopVF,
1003 unsigned IC,
1004 bool ScalarEpilogueAllowed);
1005
1006 /// Emit remarks for recipes with invalid costs in the available VPlans.
1008
1009 /// Create a check to \p Plan to see if the vector loop should be executed
1010 /// based on its trip count.
1011 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1012 ElementCount MinProfitableTripCount) const;
1013
1014 /// Attach the runtime checks of \p RTChecks to \p Plan.
1015 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1016 bool HasBranchWeights) const;
1017
1018 /// Update loop metadata and profile info for both the scalar remainder loop
1019 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1020 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1021 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1022 /// the average trip count and invocation weight of the original loop (\p
1023 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1024 /// cannot be retrieved after the plan has been executed, as the original loop
1025 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1026 /// target wants the vector loop left eligible for runtime unrolling.
1028 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1029 bool VectorizingEpilogue, MDNode *OrigLoopID,
1030 std::optional<unsigned> OrigAverageTripCount,
1031 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1032 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1033
1034private:
1035 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1036 /// scalar transformations applied. Returns null if an initial VPlan cannot
1037 /// be built.
1038 VPlanPtr tryToBuildVPlan1();
1039
1040 /// Build a VPlan using VPRecipes according to the information gathered by
1041 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1042 /// conversion only. For inner loops, \p Range's largest included VF is
1043 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1044 /// can be built for the input range, set the largest included VF to the
1045 /// maximum VF for which no plan could be built. Each VPlan is built starting
1046 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1047 /// original scalar loop.
1048 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);
1049
1050 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1051 /// based on \p VPlan1 and according to the information gathered by Legal
1052 /// when it checked if it is legal to vectorize the loop.
1053 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);
1054
1055 /// Add ComputeReductionResult recipes to the middle block to compute the
1056 /// final reduction results. Add Select recipes to the latch block when
1057 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1058 /// iteration values according to the header mask.
1059 void addReductionResultComputation(VPlanPtr &Plan,
1060 VPRecipeBuilder &RecipeBuilder,
1061 ElementCount MinVF);
1062
1063 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1064 /// that of B.
1065 bool isMoreProfitable(const VectorizationFactor &A,
1066 const VectorizationFactor &B, bool HasTail,
1067 bool IsEpilogue = false) const;
1068
1069 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1070 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1071 bool isMoreProfitable(const VectorizationFactor &A,
1072 const VectorizationFactor &B,
1073 const unsigned MaxTripCount, bool HasTail,
1074 bool IsEpilogue = false) const;
1075
1076 /// Determines if we have the infrastructure to vectorize the loop and its
1077 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1078 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1079};
1080
1081/// A helper function that returns true if the given type is irregular. The
1082/// type is irregular if its allocated size doesn't equal the store size of an
1083/// element of the corresponding vector type.
1084inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1085 // Determine if an array of N elements of type Ty is "bitcast compatible"
1086 // with a <N x Ty> vector.
1087 // This is only true if there is no padding between the array elements.
1088 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1089}
1090
1091} // namespace llvm
1092
1093#endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
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")
dxil translate DXIL Translate Metadata
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))
const SmallVectorImpl< MachineOperand > & 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
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
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:305
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.
InnerLoopVectorizer vectorizes loops which contain only one basic block to a specified vectorization ...
bool isCast() const
Drive the analysis of interleaved memory accesses in the loop.
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...
DenseMap< const SCEV *, Value * > executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan, InnerLoopVectorizer &LB, DominatorTree *DT, EpilogueVectorizationKind EpilogueVecKind=EpilogueVectorizationKind::None)
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 clearCostModel()
Destroy the cost model.
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
Definition VPlan.cpp:1722
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:1773
LoopVectorizationCostModel & getCostModel()
Return the cost model. Must not be called after clearCostModel().
void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, bool HasBranchWeights) const
Attach the runtime checks of RTChecks to Plan.
unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF, InstructionCost LoopCost)
void emitInvalidCostRemarks(OptimizationRemarkEmitter *ORE)
Emit remarks for recipes with invalid costs in the available VPlans.
LoopVectorizationPlanner(Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, const TargetTransformInfo &TTI, LoopVectorizationLegality *Legal, std::unique_ptr< LoopVectorizationCostModel > CM, VFSelectionContext &Config, InterleavedAccessInfo &IAI, PredicatedScalarEvolution &PSE, OptimizationRemarkEmitter *ORE)
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1687
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1877
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...
void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount) const
Create a check to Plan to see if the vector loop should be executed based on its trip count.
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.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Root of the metadata hierarchy.
Definition Metadata.h:64
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:232
Holds state needed to make cost decisions before computing costs per-VF, including the maximum VFs.
PredicatedScalarEvolution & getPSE() 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.
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
VFSelectionContext(const TargetTransformInfo &TTI, const LoopVectorizationLegality *Legal, const Loop *TheLoop, const Function &F, PredicatedScalarEvolution &PSE, DemandedBits *DB, OptimizationRemarkEmitter *ORE, const LoopVectorizeHints *Hints, bool OptForSize)
Instruction * getInLoopReductionImmediateChain(Instruction *I) const
Returns the immediate chain operand of in-loop reduction operation I, or nullptr if I is not an in-lo...
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:4453
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4480
InsertPointGuard(const InsertPointGuard &)=delete
InsertPointGuard & operator=(const InsertPointGuard &)=delete
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createFirstActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenStoreRecipe * createWidenStore(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Store, storing StoredVal to Addr with Mask (may be null).
VPInstruction * createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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 * createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPValue * createElementCount(Type *Ty, ElementCount EC)
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createVScale(Type *ResultTy, DebugLoc DL=DebugLoc::getUnknown())
Create a scalar llvm.vscale call.
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...
Definition VPlan.cpp:1702
VPWidenLoadRecipe * createWidenLoad(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Load, loading from Addr with Mask (may be null).
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 * createNot(VPValue *Operand, 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 ...
Definition VPlan.cpp:1674
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, std::optional< VPIRFlags > Flags=std::nullopt, const VPIRMetadata &Metadata={})
VPValue * createScalarFreeze(VPValue *Op, DebugLoc DL)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags GEPFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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.
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenPHIRecipe * createWidenPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstructionWithType * createScalarLoad(Type *ResultTy, VPValue *Addr, DebugLoc DL, const VPIRMetadata &Metadata={})
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Convert Current to Start + Current * Step.
VPWidenMemIntrinsicRecipe * createWidenMemIntrinsic(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL)
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
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.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createScalarIntrinsic(Intrinsic::ID IntrinsicID, ArrayRef< VPValue * > Operands, Type *ResultTy, DebugLoc DL)
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="")
VPBuilder()=default
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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,...
VPExpandSCEVRecipe * createExpandSCEV(const SCEV *Expr)
VPBuilder(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
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)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPInstruction * createWidePtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilder(const VPInsertPoint &IP)
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4234
Recipe to expand a SCEV expression.
Definition VPlan.h:4066
Class to record and manage LLVM IR flags.
Definition VPlan.h:705
static 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:1182
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition VPlan.h:1581
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1266
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1396
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:412
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3436
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4295
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:620
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2394
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1925
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2100
A recipe for widened phis.
Definition VPlan.h:2786
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4865
const DataLayout & getDataLayout() const
Definition VPlan.h:5079
LLVMContext & getContext() const
Definition VPlan.h:5075
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:5181
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
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.
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).
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:1746
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
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
cl::opt< unsigned > ForceTargetInstructionCost
DWARFExpression::Operation Op
std::optional< unsigned > getMaxVScale(const Function &F)
cl::opt< bool > EnableVPlanNativePath
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:76
cl::opt< bool > PreferInLoopReductions
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.
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:3853
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3958
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.
bool operator==(const VectorizationFactor &rhs) const
ElementCount Width
Vector width with best cost.
InstructionCost ScalarCost
Cost of the scalar loop.
bool operator!=(const VectorizationFactor &rhs) const
static VectorizationFactor Disabled()
Width 1 means no vectorization, cost 0 means uncomputed cost.
VectorizationFactor(ElementCount Width, InstructionCost Cost, InstructionCost ScalarCost)