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
32namespace {
33class GeneratedRTChecks;
34}
35
36namespace llvm {
37
38class LoopInfo;
39class DominatorTree;
45class LoopVersioning;
48class VPRecipeBuilder;
49struct VPRegisterUsage;
50struct VFRange;
51
55
56/// \return An upper bound for vscale based on TTI or the vscale_range
57/// attribute.
58std::optional<unsigned> getMaxVScale(const Function &F,
60
61// Utility functions that are used by different vectorization classes
63
64/// Reports a vectorization failure: print \p DebugMsg for debugging
65/// purposes along with the corresponding optimization remark \p RemarkName.
66/// If \p I is passed, it is an instruction that prevents vectorization.
67/// Otherwise, the loop \p TheLoop is used for the location of the remark.
68void reportVectorizationFailure(const StringRef DebugMsg,
69 const StringRef OREMsg, const StringRef ORETag,
71 const Loop *TheLoop, Instruction *I = nullptr);
72
73/// Same as above, but the debug message and optimization remark are identical
74inline void reportVectorizationFailure(const StringRef DebugMsg,
75 const StringRef ORETag,
77 const Loop *TheLoop,
78 Instruction *I = nullptr) {
79 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
80}
81
82/// Reports an informative message: print \p Msg for debugging purposes as well
83/// as an optimization remark. Uses either \p I as location of the remark, or
84/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
85/// remark.
86void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
88 const Loop *TheLoop, Instruction *I = nullptr,
89 DebugLoc DL = {});
90
91/// Report successful vectorization of the loop. In case an outer loop is
92/// vectorized, prepend "outer" to the vectorization remark.
93void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
94 ElementCount VFWidth, unsigned IC);
95
96} // namespace LoopVectorizationUtils
97
98/// VPlan-based builder utility analogous to IRBuilder.
99class VPBuilder {
100private:
101 class VPInsertPoint {
102 VPBasicBlock *Block = nullptr;
104
105 public:
106 /// Creates a new insertion point which doesn't point to anything.
107 VPInsertPoint() = default;
108
109 /// Creates a new insertion point to insert at \p Point in \p Block.
110 VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Point)
111 : Block(Block), Point(Point) {}
112
113 /// Creates a new insertion point to insert before \p R.
114 VPInsertPoint(VPRecipeBase *R)
115 : Block(R->getParent()), Point(R->getIterator()) {}
116
117 /// Creates a new insertion point to insert at the end of \p Block.
118 VPInsertPoint(VPBasicBlock *Block) : Block(Block), Point(Block->end()) {}
119
120 /// Returns true if this insert point is set.
121 operator bool() const { return Block; }
122
123 VPBasicBlock *getBlock() const { return Block; }
124
125 operator VPRecipeBase *() const {
126 return Point == Block->end() ? nullptr : &*Point;
127 }
128
129 template <typename T> void insert(T &R) { return Block->insert(R, Point); }
130 };
131
132 VPInsertPoint InsertPt;
133
134 /// Insert \p VPI in BB at InsertPt if BB is set.
135 template <typename T> T *tryInsertInstruction(T *R) {
136 if (InsertPt)
137 InsertPt.insert(R);
138 return R;
139 }
140
141 VPInstruction *createInstruction(unsigned Opcode,
142 ArrayRef<VPValue *> Operands,
143 const VPIRMetadata &MD, DebugLoc DL,
144 const Twine &Name = "") {
145 return tryInsertInstruction(
146 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
147 }
148
149public:
150 VPlan &getPlan() const {
151 assert(InsertPt && "Insert block must be set");
152 return *InsertPt.getBlock()->getPlan();
153 }
154
155 VPBuilder() = default;
156 VPBuilder(const VPInsertPoint &IP) : InsertPt(IP) {}
158 : InsertPt(TheBB, IP) {}
159
160 /// Get the recipe at the current insert point or nullptr if the insert point
161 /// is the end of the block.
162 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
163
164 /// Create a VPBuilder to insert after \p R.
166 return {R->getParent(), std::next(R->getIterator())};
167 }
168
169 /// Sets the current insert point to a previously-saved location.
170 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
171
172 /// Set the current insert point.
173 void setInsertPoint(const VPInsertPoint &IP) {
174 assert(IP && "Attempting to set a null insert point");
175 InsertPt = IP;
176 }
178 assert(TheBB && "Attempting to set a null insert point");
179 InsertPt = VPInsertPoint(TheBB, IP);
180 }
181
182 /// Insert \p R at the current insertion point. Returns \p R unchanged.
183 template <typename T> [[maybe_unused]] T *insert(T *R) {
184 InsertPt.insert(R);
185 return R;
186 }
187
188 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
189 /// its underlying Instruction.
191 Instruction *Inst = nullptr,
192 const VPIRFlags &Flags = {},
193 const VPIRMetadata &MD = {},
195 const Twine &Name = "",
196 Type *ResultTy = nullptr) {
197 VPInstruction *NewVPInst = tryInsertInstruction(
198 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
199 NewVPInst->setUnderlyingValue(Inst);
200 return NewVPInst;
201 }
203 DebugLoc DL, const Twine &Name = "") {
204 return createInstruction(Opcode, Operands, {}, DL, Name);
205 }
207 const VPIRFlags &Flags,
209 const Twine &Name = "") {
210 return tryInsertInstruction(
211 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
212 }
213
215 Type *ResultTy, const VPIRFlags &Flags = {},
217 const Twine &Name = "") {
218 return tryInsertInstruction(new VPInstructionWithType(
219 Opcode, Operands, ResultTy, Flags, {}, DL, Name));
220 }
221
224 const Twine &Name = "") {
225 // Assume that the maximum possible number of elements in a vector fits
226 // within the index type for the default address space.
227 VPlan &Plan = getPlan();
228 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
229 return tryInsertInstruction(new VPInstruction(
230 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
231 }
232
235 const Twine &Name = "") {
236 // Assume that the maximum possible number of elements in a vector fits
237 // within the index type for the default address space.
238 VPlan &Plan = getPlan();
239 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
240 return tryInsertInstruction(new VPInstruction(
241 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
242 }
243
245 unsigned Opcode, ArrayRef<VPValue *> Operands,
246 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
247 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
248 return tryInsertInstruction(
249 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
250 }
251
254 const Twine &Name = "") {
255 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
256 }
257
260 const Twine &Name = "") {
261 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
262 Name);
263 }
264
267 const Twine &Name = "") {
268
269 return tryInsertInstruction(new VPInstruction(
270 Instruction::BinaryOps::Or, {LHS, RHS},
271 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
272 }
273
276 const Twine &Name = "",
277 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
278 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
279 Name);
280 }
281
282 VPInstruction *
284 const Twine &Name = "",
285 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
286 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
287 Name);
288 }
289
295
301
303 VPValue *FalseVal,
305 const Twine &Name = "",
306 const VPIRFlags &Flags = {}) {
307 return tryInsertInstruction(new VPInstruction(
308 Instruction::Select, {Cond, TrueVal, FalseVal}, Flags, {}, DL, Name));
309 }
310
311 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
312 /// and \p B.
315 const Twine &Name = "") {
317 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
318 return tryInsertInstruction(
319 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
320 }
321
322 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
323 /// and \p B.
326 const Twine &Name = "") {
328 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
329 return tryInsertInstruction(
330 new VPInstruction(Instruction::FCmp, {A, B},
331 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
332 }
333
334 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
335 /// result, then select between \p TrueVal and \p FalseVal.
337 VPValue *FalseVal,
339
342 const Twine &Name = "") {
343 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
344 }
345
347 GEPNoWrapFlags GEPFlags,
349 const Twine &Name = "") {
350 return tryInsertInstruction(new VPInstruction(
351 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
352 }
353
356 const Twine &Name = "") {
357 return tryInsertInstruction(
359 GEPNoWrapFlags::none(), {}, DL, Name));
360 }
361
364 const Twine &Name = "", const VPIRFlags &Flags = {},
365 Type *ResultTy = nullptr) {
366 return tryInsertInstruction(
367 new VPPhi(IncomingValues, Flags, DL, Name, ResultTy));
368 }
369
372 const Twine &Name = "") {
373 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
374 }
375
377 VPlan &Plan = getPlan();
378 VPValue *RuntimeEC = Plan.getConstantInt(Ty, EC.getKnownMinValue());
379 if (EC.isScalable()) {
380 VPValue *VScale = createVScale(Ty);
381 RuntimeEC = EC.getKnownMinValue() == 1
382 ? VScale
383 : createOverflowingOp(Instruction::Mul,
384 {VScale, RuntimeEC}, {true, false});
385 }
386 return RuntimeEC;
387 }
388
389 /// Convert \p Current to \p Start + \p Current * \p Step.
391 FPMathOperator *FPBinOp, VPValue *Start,
392 VPValue *Current, VPValue *Step,
393 const VPIRFlags::WrapFlagsTy &Flags = {}) {
394 return tryInsertInstruction(
395 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
396 }
397
399 DebugLoc DL,
400 const VPIRMetadata &Metadata = {}) {
401 return tryInsertInstruction(new VPInstructionWithType(
402 Instruction::Load, Addr, ResultTy, {}, Metadata, DL));
403 }
404
406 Type *ResultTy, DebugLoc DL,
407 const VPIRMetadata &Metadata = {}) {
408 return tryInsertInstruction(new VPInstructionWithType(
409 Opcode, Op, ResultTy, VPIRFlags::getDefaultFlags(Opcode), Metadata,
410 DL));
411 }
412
414 Type *ResultTy, DebugLoc DL,
415 const VPIRFlags &Flags,
416 const VPIRMetadata &Metadata = {}) {
417 return tryInsertInstruction(
418 new VPInstructionWithType(Opcode, Op, ResultTy, Flags, Metadata, DL));
419 }
420
421 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
422 /// result type \p ResultTy
424 ArrayRef<VPValue *> Operands,
425 Type *ResultTy, DebugLoc DL) {
426 VPlan &Plan = getPlan();
428 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
429 return tryInsertInstruction(new VPInstructionWithType(
430 VPInstruction::Intrinsic, Ops, ResultTy, {}, {}, DL));
431 }
432
433 /// Create a scalar llvm.vscale call.
436 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
437 }
438
440 Type *SrcTy = Op->getScalarType();
441 if (ResultTy == SrcTy)
442 return Op;
443 Instruction::CastOps CastOp =
444 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
445 ? Instruction::Trunc
446 : Instruction::ZExt;
447 return createScalarCast(CastOp, Op, ResultTy, DL);
448 }
449
451 Type *SrcTy = Op->getScalarType();
452 if (ResultTy == SrcTy)
453 return Op;
454 Instruction::CastOps CastOp =
455 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
456 ? Instruction::Trunc
457 : Instruction::SExt;
458 return createScalarCast(CastOp, Op, ResultTy, DL);
459 }
460
462 return tryInsertInstruction(
463 new VPInstruction(Instruction::Freeze, Op, {}, {}, DL));
464 }
465
467 Type *ResultTy) {
468 return tryInsertInstruction(new VPWidenCastRecipe(
469 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
470 }
471
472 /// Create a single-scalar recipe with \p Opcode and \p Operands without
473 /// inserting it.
475 ArrayRef<VPValue *> Operands,
476 VPValue *Mask,
477 const VPIRFlags &Flags,
478 const VPIRMetadata &Metadata,
479 DebugLoc DL, Instruction *UV) {
480 if (Instruction::isCast(Opcode)) {
481 assert(!Mask && "Cast cannot be predicated");
482 return new VPInstructionWithType(Opcode, Operands, UV->getType(), Flags,
483 Metadata, DL, UV->getName(), UV);
484 }
485 return new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true, Mask,
486 Flags, Metadata, DL);
487 }
488
491 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
492 VPValue *VF, DebugLoc DL) {
493 return tryInsertInstruction(new VPScalarIVStepsRecipe(
494 IV, Step, VF, InductionOpcode,
495 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
496 }
497
499 return tryInsertInstruction(new VPExpandSCEVRecipe(Expr));
500 }
501
503 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
504 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
505 return tryInsertInstruction(
506 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
507 }
508
509 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
510 /// with element type \p SourceElementTy.
512 Type *SourceElementTy,
513 bool Reverse, DebugLoc DL);
514
516 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
517 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
518 return tryInsertInstruction(new VPWidenMemIntrinsicRecipe(
519 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
520 }
521
522 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
523 /// be null).
525 VPValue *Mask, bool Consecutive,
526 const VPIRMetadata &Metadata,
527 DebugLoc DL) {
528 return tryInsertInstruction(
529 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
530 }
531
532 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
533 /// \p Mask (may be null).
535 VPValue *StoredVal, VPValue *Mask,
536 bool Consecutive,
537 const VPIRMetadata &Metadata,
538 DebugLoc DL) {
539 return tryInsertInstruction(new VPWidenStoreRecipe(
540 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
541 }
542
543 //===--------------------------------------------------------------------===//
544 // RAII helpers.
545 //===--------------------------------------------------------------------===//
546
547 /// RAII object that stores the current insertion point and restores it when
548 /// the object is destroyed.
550 VPBuilder &Builder;
551 VPInsertPoint InsertPt;
552
553 public:
554 InsertPointGuard(VPBuilder &B) : Builder(B), InsertPt(B.InsertPt) {}
555
558
559 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
560 };
561};
562
563/// TODO: The following VectorizationFactor was pulled out of
564/// LoopVectorizationCostModel class. LV also deals with
565/// VectorizerParams::VectorizationFactor.
566/// We need to streamline them.
567
568/// Information about vectorization costs.
570 /// Vector width with best cost.
572
573 /// Cost of the loop with that width.
575
576 /// Cost of the scalar loop.
578
579 /// The minimum trip count required to make vectorization profitable, e.g. due
580 /// to runtime checks.
582
586
587 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
589 return {ElementCount::getFixed(1), 0, 0};
590 }
591
592 bool operator==(const VectorizationFactor &rhs) const {
593 return Width == rhs.Width && Cost == rhs.Cost;
594 }
595
596 bool operator!=(const VectorizationFactor &rhs) const {
597 return !(*this == rhs);
598 }
599};
600
601/// A class that represents two vectorization factors (initialized with 0 by
602/// default). One for fixed-width vectorization and one for scalable
603/// vectorization. This can be used by the vectorizer to choose from a range of
604/// fixed and/or scalable VFs in order to find the most cost-effective VF to
605/// vectorize with.
609
611 : FixedVF(ElementCount::getFixed(0)),
612 ScalableVF(ElementCount::getScalable(0)) {}
614 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
615 }
619 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
620 "Invalid scalable properties");
621 }
622
624
625 /// \return true if either fixed- or scalable VF is non-zero.
626 explicit operator bool() const { return FixedVF || ScalableVF; }
627
628 /// \return true if either fixed- or scalable VF is a valid vector VF.
629 bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); }
630};
631
632/// Holds state needed to make cost decisions before computing costs per-VF,
633/// including the maximum VFs.
635 /// \return True if maximizing vector bandwidth is enabled by the target or
636 /// user options, for the given register kind (scalable or fixed-width).
637 bool useMaxBandwidth(bool IsScalable) const;
638
639 /// \return the maximized element count based on the targets vector
640 /// registers and the loop trip-count, but limited to a maximum safe VF.
641 /// This is a helper function of computeFeasibleMaxVF.
642 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
643 unsigned SmallestType,
644 unsigned WidestType,
645 ElementCount MaxSafeVF, unsigned UserIC,
646 bool FoldTailByMasking,
647 bool RequiresScalarEpilogue);
648
649 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
650 /// that results in VF * UserIC <= MaxTripCount.
651 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
652 unsigned UserIC, bool FoldTailByMasking,
653 bool RequiresScalarEpilogue) const;
654
655 /// Checks if scalable vectorization is supported and enabled. Caches the
656 /// result to avoid repeated debug dumps for repeated queries.
657 bool isScalableVectorizationAllowed();
658
659 /// \return the maximum legal scalable VF, based on the safe max number
660 /// of elements.
661 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
662
663 /// Initializes the value of vscale used for tuning the cost model. If
664 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
665 /// return the value returned by the corresponding TTI method.
666 void initializeVScaleForTuning();
667
668 const TargetTransformInfo &TTI;
669 const LoopVectorizationLegality *Legal;
670 const Loop *TheLoop;
671 const Function &F;
673 DemandedBits *DB;
675 const LoopVectorizeHints *Hints;
676
677 /// Cached result of isScalableVectorizationAllowed.
678 std::optional<bool> IsScalableVectorizationAllowed;
679
680 /// Used to store the value of vscale used for tuning the cost model. It is
681 /// initialized during object construction.
682 std::optional<unsigned> VScaleForTuning;
683
684 /// The highest VF possible for this loop, without using MaxBandwidth.
685 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
686
687 /// All element types found in the loop.
688 SmallPtrSet<Type *, 16> ElementTypesInLoop;
689
690 /// PHINodes of the reductions that should be expanded in-loop. Set by
691 /// collectInLoopReductions.
692 SmallPtrSet<PHINode *, 4> InLoopReductions;
693
694 /// A Map of inloop reduction operations and their immediate chain operand.
695 /// FIXME: This can be removed once reductions can be costed correctly in
696 /// VPlan. This was added to allow quick lookup of the inloop operations.
697 /// Set by collectInLoopReductions.
698 DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
699
700 /// Maximum safe number of elements to be processed per vector iteration,
701 /// which do not prevent store-load forwarding and are safe with regard to the
702 /// memory dependencies. Required for EVL-based vectorization, where this
703 /// value is used as the upper bound of the safe AVL. Set by
704 /// computeFeasibleMaxVF.
705 std::optional<unsigned> MaxSafeElements;
706
707 /// Map of scalar integer values to the smallest bitwidth they can be legally
708 /// represented as. The vector equivalents of these values should be truncated
709 /// to this type.
711
712public:
713 /// The kind of cost that we are calculating.
715
716 /// Whether this loop should be optimized for size based on function attribute
717 /// or profile information.
718 const bool OptForSize;
719
721 const LoopVectorizationLegality *Legal,
722 const Loop *TheLoop, const Function &F,
725 const LoopVectorizeHints *Hints, bool OptForSize)
726 : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
727 ORE(ORE), Hints(Hints),
728 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
730 initializeVScaleForTuning();
731 }
732
733 /// \return The vscale value used for tuning the cost model.
734 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
735
736 const TargetTransformInfo &getTTI() const { return TTI; }
737
738 PredicatedScalarEvolution &getPSE() const { return PSE; }
739
740 /// \return The loop being analyzed.
741 const Loop *getLoop() const { return TheLoop; }
742
743 /// \return True if register pressure should be considered for the given VF.
745
746 /// \return True if scalable vectors are supported by the target or forced.
747 bool supportsScalableVectors() const;
748
749 /// Collect element types in the loop that need widening.
751 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
752
753 /// \return The size (in bits) of the smallest and widest types in the code
754 /// that need to be vectorized. We ignore values that remain scalar such as
755 /// 64 bit loop indices.
756 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
757
758 /// \return An upper bound for the vectorization factors for both
759 /// fixed and scalable vectorization, where the minimum-known number of
760 /// elements is a power-of-2 larger than zero. If scalable vectorization is
761 /// disabled or unsupported, then the scalable part will be equal to
762 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
763 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
764 ElementCount UserVF, unsigned UserIC,
765 bool FoldTailByMasking,
766 bool RequiresScalarEpilogue);
767
768 /// Return maximum safe number of elements to be processed per vector
769 /// iteration, which do not prevent store-load forwarding and are safe with
770 /// regard to the memory dependencies. Required for EVL-based VPlans to
771 /// correctly calculate AVL (application vector length) as min(remaining AVL,
772 /// MaxSafeElements). Set by computeFeasibleMaxVF.
773 /// TODO: need to consider adjusting cost model to use this value as a
774 /// vectorization factor for EVL-based vectorization.
775 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
776
777 /// Returns true if we should use strict in-order reductions for the given
778 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
779 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
780 /// of FP operations.
781 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
782
783 /// Returns true if the target machine supports a masked load (if \p IsLoad)
784 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
785 /// space \p AddressSpace. The caller must ensure the access is consecutive or
786 /// part of an interleave group.
787 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
788 unsigned AddressSpace) const;
789
790 /// Returns true if the target machine can represent \p V as a masked gather
791 /// or scatter operation.
792 bool isLegalGatherOrScatter(Value *V, ElementCount VF) const;
793
794 /// Split reductions into those that happen in the loop, and those that
795 /// happen outside. In-loop reductions are collected into InLoopReductions.
796 /// InLoopReductionImmediateChains is filled with each in-loop reduction
797 /// operation and its immediate chain operand for use during cost modelling.
799
800 /// Returns true if the Phi is part of an inloop reduction.
801 bool isInLoopReduction(PHINode *Phi) const {
802 return InLoopReductions.contains(Phi);
803 }
804
805 /// Returns the set of in-loop reduction PHIs.
807 return InLoopReductions;
808 }
809
810 /// Returns the immediate chain operand of in-loop reduction operation \p I,
811 /// or nullptr if \p I is not an in-loop reduction operation.
813 return InLoopReductionImmediateChains.lookup(I);
814 }
815
816 /// Check whether vectorization would require runtime checks. When optimizing
817 /// for size, returning true here aborts vectorization.
819
820 /// Returns a scalable VF to use for outer-loop vectorization if the target
821 /// supports it and a fixed VF otherwise.
823
824 /// Compute smallest bitwidth each instruction can be represented with.
825 /// The vector equivalents of these instructions should be truncated to this
826 /// type.
828
829 /// \returns The smallest bitwidth each instruction can be represented with.
831 return MinBWs;
832 }
833};
834
835/// Planner drives the vectorization process after having passed
836/// Legality checks.
838 /// The loop that we evaluate.
839 Loop *OrigLoop;
840
841 /// Loop Info analysis.
842 LoopInfo *LI;
843
844 /// The dominator tree.
845 DominatorTree *DT;
846
847 /// Target Library Info.
848 const TargetLibraryInfo *TLI;
849
850 /// Target Transform Info.
851 const TargetTransformInfo &TTI;
852
853 /// The legality analysis.
855
856 /// The profitability analysis.
858
859 /// VF selection state independent of cost-modeling decisions.
860 VFSelectionContext &Config;
861
862 /// The interleaved access analysis.
864
866
867 const LoopVectorizeHints &Hints;
868
870
872
873 /// Profitable vector factors.
875
876 /// A builder used to construct the current plan.
877 VPBuilder Builder;
878
879 /// Computes the cost of \p Plan for vectorization factor \p VF.
880 ///
881 /// The current implementation requires access to the
882 /// LoopVectorizationLegality to handle inductions and reductions, which is
883 /// why it is kept separate from the VPlan-only cost infrastructure.
884 ///
885 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
886 /// been retired.
887 InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;
888
889 /// Precompute costs for certain instructions using the legacy cost model. The
890 /// function is used to bring up the VPlan-based cost model to initially avoid
891 /// taking different decisions due to inaccuracies in the legacy cost model.
892 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
893 VPCostContext &CostCtx) const;
894
895public:
897 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
902 : OrigLoop(L), LI(LI), DT(DT), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM),
903 Config(Config), IAI(IAI), PSE(PSE), Hints(Hints), ORE(ORE) {}
904
905 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
906 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
907 /// interleaving should be avoided up-front, no plans are generated.
908 void plan(ElementCount UserVF, unsigned UserIC);
909
910 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
911 /// for each VF.
912 VPlan &getPlanFor(ElementCount VF) const;
913
914 /// Compute and return the most profitable vectorization factor and the
915 /// corresponding best VPlan. Also collect all profitable VFs in
916 /// ProfitableVFs.
917 std::pair<VectorizationFactor, VPlan *> computeBestVF();
918
919 /// \return The desired interleave count.
920 /// If interleave count has been specified by metadata it will be returned.
921 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
922 /// are the selected vectorization factor and the cost of the selected VF.
923 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
924 InstructionCost LoopCost);
925
926 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
927 /// according to the best selected \p VF and \p UF.
928 ///
929 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
930 /// fixed.
931 ///
932 /// Returns a mapping of SCEVs to their expanded IR values.
933 /// Note that this is a temporary workaround needed due to the current
934 /// epilogue handling.
936 None, ///< Not part of epilogue vectorization.
937 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
938 Epilogue ///< Vectorizing the epilogue loop.
939 };
941 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
943 EpilogueVectorizationKind EpilogueVecKind =
945
946#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
947 void printPlans(raw_ostream &O);
948#endif
949
950 /// Look through the existing plans and return true if we have one with
951 /// vectorization factor \p VF.
953 return any_of(VPlans,
954 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
955 }
956
957 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
958 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
959 /// returned value holds for the entire \p Range.
960 static bool
961 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
962 VFRange &Range);
963
964 /// \return A VPlan for the most profitable epilogue vectorization, with its
965 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
966 /// Returns nullptr if epilogue vectorization is not supported or not
967 /// profitable for the loop.
968 std::unique_ptr<VPlan>
969 selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC);
970
971 /// Emit remarks for recipes with invalid costs in the available VPlans.
973
974 /// Create a check to \p Plan to see if the vector loop should be executed
975 /// based on its trip count.
976 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
977 ElementCount MinProfitableTripCount) const;
978
979 /// Returns true if \p Plan requires a scalar epilogue after the vector
980 /// loop. Asserts that the VPlan decision matches the legacy cost model.
981 bool requiresScalarEpilogue(VPlan &Plan, ElementCount VF) const;
982
983 /// Attach the runtime checks of \p RTChecks to \p Plan.
984 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
985 bool HasBranchWeights) const;
986
987 /// Update loop metadata and profile info for both the scalar remainder loop
988 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
989 /// loop on the vector loop and replaces vectorizer-specific metadata. The
990 /// loop ID of the original loop \p OrigLoopID must be passed, together with
991 /// the average trip count and invocation weight of the original loop (\p
992 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
993 /// cannot be retrieved after the plan has been executed, as the original loop
994 /// may have been removed.
996 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
997 bool VectorizingEpilogue, MDNode *OrigLoopID,
998 std::optional<unsigned> OrigAverageTripCount,
999 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1000 bool DisableRuntimeUnroll);
1001
1002private:
1003 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1004 /// scalar transformations applied. Returns null if an initial VPlan cannot
1005 /// be built.
1006 VPlanPtr tryToBuildVPlan1();
1007
1008 /// Build a VPlan using VPRecipes according to the information gathered by
1009 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1010 /// conversion only. For inner loops, \p Range's largest included VF is
1011 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1012 /// can be built for the input range, set the largest included VF to the
1013 /// maximum VF for which no plan could be built. Each VPlan is built starting
1014 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1015 /// original scalar loop.
1016 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);
1017
1018 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1019 /// based on \p VPlan1 and according to the information gathered by Legal
1020 /// when it checked if it is legal to vectorize the loop.
1021 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);
1022
1023 /// Add ComputeReductionResult recipes to the middle block to compute the
1024 /// final reduction results. Add Select recipes to the latch block when
1025 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1026 /// iteration values according to the header mask.
1027 void addReductionResultComputation(VPlanPtr &Plan,
1028 VPRecipeBuilder &RecipeBuilder,
1029 ElementCount MinVF);
1030
1031 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1032 /// that of B.
1033 bool isMoreProfitable(const VectorizationFactor &A,
1034 const VectorizationFactor &B, bool HasTail,
1035 bool IsEpilogue = false) const;
1036
1037 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1038 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1039 bool isMoreProfitable(const VectorizationFactor &A,
1040 const VectorizationFactor &B,
1041 const unsigned MaxTripCount, bool HasTail,
1042 bool IsEpilogue = false) const;
1043
1044 /// Determines if we have the infrastructure to vectorize the loop and its
1045 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1046 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1047};
1048
1049/// A helper function that returns true if the given type is irregular. The
1050/// type is irregular if its allocated size doesn't equal the store size of an
1051/// element of the corresponding vector type.
1052inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1053 // Determine if an array of N elements of type Ty is "bitcast compatible"
1054 // with a <N x Ty> vector.
1055 // This is only true if there is no padding between the array elements.
1056 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1057}
1058
1059} // namespace llvm
1060
1061#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
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:309
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.
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
Definition VPlan.cpp:1709
void updateLoopMetadataAndProfileInfo(Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan, bool VectorizingEpilogue, MDNode *OrigLoopID, std::optional< unsigned > OrigAverageTripCount, unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF, bool DisableRuntimeUnroll)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
Definition VPlan.cpp:1760
void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, bool HasBranchWeights) const
Attach the runtime checks of RTChecks to Plan.
LoopVectorizationPlanner(Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, const TargetTransformInfo &TTI, LoopVectorizationLegality *Legal, LoopVectorizationCostModel &CM, VFSelectionContext &Config, InterleavedAccessInfo &IAI, PredicatedScalarEvolution &PSE, const LoopVectorizeHints &Hints, OptimizationRemarkEmitter *ORE)
unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF, InstructionCost LoopCost)
bool requiresScalarEpilogue(VPlan &Plan, ElementCount VF) const
Returns true if Plan requires a scalar epilogue after the vector loop.
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:1674
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1866
void plan(ElementCount UserVF, unsigned UserIC)
Build VPlans for the specified UserVF and UserIC if they are non-zero or all applicable candidate VFs...
std::unique_ptr< VPlan > selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC)
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(Value *V, ElementCount VF) const
Returns true if the target machine can represent V as a masked gather or scatter operation.
bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment, unsigned AddressSpace) const
Returns true if the target machine supports a masked load (if IsLoad) or masked store of scalar type ...
void collectInLoopReductions()
Split reductions into those that happen in the loop, and those that happen outside.
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
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 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:4380
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4407
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="")
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:1689
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:1661
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, const VPIRMetadata &Metadata={})
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="")
VPValue * createScalarFreeze(VPValue *Op, Type *ResultTy, DebugLoc DL)
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 * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, const VPIRFlags &Flags, const VPIRMetadata &Metadata={})
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="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={}, Type *ResultTy=nullptr)
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
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:4174
Recipe to expand a SCEV expression.
Definition VPlan.h:4006
Class to record and manage LLVM IR flags.
Definition VPlan.h:704
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:1179
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition VPlan.h:1541
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1234
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1356
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:411
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3388
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4235
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
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:2349
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1880
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2055
A recipe for widened phis.
Definition VPlan.h:2743
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4792
const DataLayout & getDataLayout() const
Definition VPlan.h:4999
LLVMContext & getContext() const
Definition VPlan.h:4995
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:5101
LLVM Value Representation.
Definition Value.h:75
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:578
@ 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
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
std::optional< unsigned > getMaxVScale(const Function &F, const TargetTransformInfo &TTI)
cl::opt< unsigned > ForceTargetInstructionCost
TargetTransformInfo TTI
DWARFExpression::Operation Op
cl::opt< bool > EnableVPlanNativePath
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:74
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:3799
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3898
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)