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