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 {
100 VPBasicBlock *BB = nullptr;
102
103 /// Insert \p VPI in BB at InsertPt if BB is set.
104 template <typename T> T *tryInsertInstruction(T *R) {
105 if (BB)
106 BB->insert(R, InsertPt);
107 return R;
108 }
109
110 VPInstruction *createInstruction(unsigned Opcode,
111 ArrayRef<VPValue *> Operands,
112 const VPIRMetadata &MD, DebugLoc DL,
113 const Twine &Name = "") {
114 return tryInsertInstruction(
115 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
116 }
117
118public:
119 VPlan &getPlan() const {
120 assert(getInsertBlock() && "Insert block must be set");
121 return *getInsertBlock()->getPlan();
122 }
123
124 VPBuilder() = default;
125 VPBuilder(VPBasicBlock *InsertBB) { setInsertPoint(InsertBB); }
126 VPBuilder(VPRecipeBase *InsertPt) { setInsertPoint(InsertPt); }
128 setInsertPoint(TheBB, IP);
129 }
130
131 /// Clear the insertion point: created instructions will not be inserted into
132 /// a block.
134 BB = nullptr;
135 InsertPt = VPBasicBlock::iterator();
136 }
137
138 VPBasicBlock *getInsertBlock() const { return BB; }
139 VPBasicBlock::iterator getInsertPoint() const { return InsertPt; }
140
141 /// Create a VPBuilder to insert after \p R.
143 VPBuilder B;
144 B.setInsertPoint(R->getParent(), std::next(R->getIterator()));
145 return B;
146 }
147
148 /// InsertPoint - A saved insertion point.
150 VPBasicBlock *Block = nullptr;
152
153 public:
154 /// Creates a new insertion point which doesn't point to anything.
155 VPInsertPoint() = default;
156
157 /// Creates a new insertion point at the given location.
159 : Block(InsertBlock), Point(InsertPoint) {}
160
161 /// Returns true if this insert point is set.
162 bool isSet() const { return Block != nullptr; }
163
164 VPBasicBlock *getBlock() const { return Block; }
165 VPBasicBlock::iterator getPoint() const { return Point; }
166 };
167
168 /// Sets the current insert point to a previously-saved location.
170 if (IP.isSet())
171 setInsertPoint(IP.getBlock(), IP.getPoint());
172 else
174 }
175
176 /// This specifies that created VPInstructions should be appended to the end
177 /// of the specified block.
179 assert(TheBB && "Attempting to set a null insert point");
180 BB = TheBB;
181 InsertPt = BB->end();
182 }
183
184 /// This specifies that created instructions should be inserted at the
185 /// specified point.
187 BB = TheBB;
188 InsertPt = IP;
189 }
190
191 /// This specifies that created instructions should be inserted at the
192 /// specified point.
194 BB = IP->getParent();
195 InsertPt = IP->getIterator();
196 }
197
198 /// Insert \p R at the current insertion point. Returns \p R unchanged.
199 template <typename T> [[maybe_unused]] T *insert(T *R) {
200 BB->insert(R, InsertPt);
201 return R;
202 }
203
204 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
205 /// its underlying Instruction.
207 Instruction *Inst = nullptr,
208 const VPIRFlags &Flags = {},
209 const VPIRMetadata &MD = {},
211 const Twine &Name = "",
212 Type *ResultTy = nullptr) {
213 VPInstruction *NewVPInst = tryInsertInstruction(
214 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
215 NewVPInst->setUnderlyingValue(Inst);
216 return NewVPInst;
217 }
219 DebugLoc DL, const Twine &Name = "") {
220 return createInstruction(Opcode, Operands, {}, DL, Name);
221 }
223 const VPIRFlags &Flags,
225 const Twine &Name = "") {
226 return tryInsertInstruction(
227 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
228 }
229
231 Type *ResultTy, const VPIRFlags &Flags = {},
233 const Twine &Name = "") {
234 return tryInsertInstruction(new VPInstructionWithType(
235 Opcode, Operands, ResultTy, Flags, {}, DL, Name));
236 }
237
240 const Twine &Name = "") {
241 // Assume that the maximum possible number of elements in a vector fits
242 // within the index type for the default address space.
243 VPlan &Plan = getPlan();
244 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
245 return tryInsertInstruction(new VPInstruction(
246 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
247 }
248
251 const Twine &Name = "") {
252 // Assume that the maximum possible number of elements in a vector fits
253 // within the index type for the default address space.
254 VPlan &Plan = getPlan();
255 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
256 return tryInsertInstruction(new VPInstruction(
257 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
258 }
259
261 unsigned Opcode, ArrayRef<VPValue *> Operands,
262 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
263 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
264 return tryInsertInstruction(
265 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
266 }
267
270 const Twine &Name = "") {
271 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
272 }
273
276 const Twine &Name = "") {
277 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
278 Name);
279 }
280
283 const Twine &Name = "") {
284
285 return tryInsertInstruction(new VPInstruction(
286 Instruction::BinaryOps::Or, {LHS, RHS},
287 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
288 }
289
292 const Twine &Name = "",
293 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
294 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
295 Name);
296 }
297
298 VPInstruction *
300 const Twine &Name = "",
301 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
302 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
303 Name);
304 }
305
311
317
319 VPValue *FalseVal,
321 const Twine &Name = "",
322 const VPIRFlags &Flags = {}) {
323 return tryInsertInstruction(new VPInstruction(
324 Instruction::Select, {Cond, TrueVal, FalseVal}, Flags, {}, DL, Name));
325 }
326
327 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
328 /// and \p B.
331 const Twine &Name = "") {
333 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
334 return tryInsertInstruction(
335 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
336 }
337
338 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
339 /// and \p B.
342 const Twine &Name = "") {
344 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
345 return tryInsertInstruction(
346 new VPInstruction(Instruction::FCmp, {A, B},
347 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
348 }
349
350 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
351 /// result, then select between \p TrueVal and \p FalseVal.
353 VPValue *FalseVal,
355
358 const Twine &Name = "") {
359 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
360 }
361
363 GEPNoWrapFlags GEPFlags,
365 const Twine &Name = "") {
366 return tryInsertInstruction(new VPInstruction(
367 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
368 }
369
372 const Twine &Name = "") {
373 return tryInsertInstruction(
375 GEPNoWrapFlags::none(), {}, DL, Name));
376 }
377
380 const Twine &Name = "", const VPIRFlags &Flags = {},
381 Type *ResultTy = nullptr) {
382 return tryInsertInstruction(
383 new VPPhi(IncomingValues, Flags, DL, Name, ResultTy));
384 }
385
388 const Twine &Name = "") {
389 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
390 }
391
393 VPlan &Plan = *getInsertBlock()->getPlan();
394 VPValue *RuntimeEC = Plan.getConstantInt(Ty, EC.getKnownMinValue());
395 if (EC.isScalable()) {
396 VPValue *VScale = createVScale(Ty);
397 RuntimeEC = EC.getKnownMinValue() == 1
398 ? VScale
399 : createOverflowingOp(Instruction::Mul,
400 {VScale, RuntimeEC}, {true, false});
401 }
402 return RuntimeEC;
403 }
404
405 /// Convert \p Current to \p Start + \p Current * \p Step.
407 FPMathOperator *FPBinOp, VPValue *Start,
408 VPValue *Current, VPValue *Step,
409 const VPIRFlags::WrapFlagsTy &Flags = {}) {
410 return tryInsertInstruction(
411 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
412 }
413
415 DebugLoc DL,
416 const VPIRMetadata &Metadata = {}) {
417 return tryInsertInstruction(new VPInstructionWithType(
418 Instruction::Load, Addr, ResultTy, {}, Metadata, DL));
419 }
420
422 Type *ResultTy, DebugLoc DL,
423 const VPIRMetadata &Metadata = {}) {
424 return tryInsertInstruction(new VPInstructionWithType(
425 Opcode, Op, ResultTy, VPIRFlags::getDefaultFlags(Opcode), Metadata,
426 DL));
427 }
428
430 Type *ResultTy, DebugLoc DL,
431 const VPIRFlags &Flags,
432 const VPIRMetadata &Metadata = {}) {
433 return tryInsertInstruction(
434 new VPInstructionWithType(Opcode, Op, ResultTy, Flags, Metadata, DL));
435 }
436
437 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
438 /// result type \p ResultTy
440 ArrayRef<VPValue *> Operands,
441 Type *ResultTy, DebugLoc DL) {
442 VPlan &Plan = getPlan();
444 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
445 return tryInsertInstruction(new VPInstructionWithType(
446 VPInstruction::Intrinsic, Ops, ResultTy, {}, {}, DL));
447 }
448
449 /// Create a scalar llvm.vscale call.
452 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
453 }
454
456 Type *SrcTy = Op->getScalarType();
457 if (ResultTy == SrcTy)
458 return Op;
459 Instruction::CastOps CastOp =
460 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
461 ? Instruction::Trunc
462 : Instruction::ZExt;
463 return createScalarCast(CastOp, Op, ResultTy, DL);
464 }
465
467 Type *SrcTy = Op->getScalarType();
468 if (ResultTy == SrcTy)
469 return Op;
470 Instruction::CastOps CastOp =
471 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
472 ? Instruction::Trunc
473 : Instruction::SExt;
474 return createScalarCast(CastOp, Op, ResultTy, DL);
475 }
476
478 return tryInsertInstruction(
479 new VPInstruction(Instruction::Freeze, Op, {}, {}, DL));
480 }
481
483 Type *ResultTy) {
484 return tryInsertInstruction(new VPWidenCastRecipe(
485 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
486 }
487
488 /// Create a single-scalar recipe with \p Opcode and \p Operands without
489 /// inserting it.
491 ArrayRef<VPValue *> Operands,
492 VPValue *Mask,
493 const VPIRFlags &Flags,
494 const VPIRMetadata &Metadata,
495 DebugLoc DL, Instruction *UV) {
496 if (Instruction::isCast(Opcode)) {
497 assert(!Mask && "Cast cannot be predicated");
498 return new VPInstructionWithType(Opcode, Operands, UV->getType(), Flags,
499 Metadata, DL, UV->getName(), UV);
500 }
501 return new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true, Mask,
502 Flags, Metadata, DL);
503 }
504
507 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
508 VPValue *VF, DebugLoc DL) {
509 return tryInsertInstruction(new VPScalarIVStepsRecipe(
510 IV, Step, VF, InductionOpcode,
511 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
512 }
513
515 return tryInsertInstruction(new VPExpandSCEVRecipe(Expr));
516 }
517
519 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
520 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
521 return tryInsertInstruction(
522 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
523 }
524
525 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
526 /// with element type \p SourceElementTy.
528 Type *SourceElementTy,
529 bool Reverse, DebugLoc DL);
530
532 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
533 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
534 return tryInsertInstruction(new VPWidenMemIntrinsicRecipe(
535 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
536 }
537
538 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
539 /// be null).
541 VPValue *Mask, bool Consecutive,
542 const VPIRMetadata &Metadata,
543 DebugLoc DL) {
544 return tryInsertInstruction(
545 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
546 }
547
548 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
549 /// \p Mask (may be null).
551 VPValue *StoredVal, VPValue *Mask,
552 bool Consecutive,
553 const VPIRMetadata &Metadata,
554 DebugLoc DL) {
555 return tryInsertInstruction(new VPWidenStoreRecipe(
556 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
557 }
558
559 //===--------------------------------------------------------------------===//
560 // RAII helpers.
561 //===--------------------------------------------------------------------===//
562
563 /// RAII object that stores the current insertion point and restores it when
564 /// the object is destroyed.
566 VPBuilder &Builder;
567 VPBasicBlock *Block;
569
570 public:
572 : Builder(B), Block(B.getInsertBlock()), Point(B.getInsertPoint()) {}
573
576
577 ~InsertPointGuard() { Builder.restoreIP(VPInsertPoint(Block, Point)); }
578 };
579};
580
581/// TODO: The following VectorizationFactor was pulled out of
582/// LoopVectorizationCostModel class. LV also deals with
583/// VectorizerParams::VectorizationFactor.
584/// We need to streamline them.
585
586/// Information about vectorization costs.
588 /// Vector width with best cost.
590
591 /// Cost of the loop with that width.
593
594 /// Cost of the scalar loop.
596
597 /// The minimum trip count required to make vectorization profitable, e.g. due
598 /// to runtime checks.
600
604
605 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
607 return {ElementCount::getFixed(1), 0, 0};
608 }
609
610 bool operator==(const VectorizationFactor &rhs) const {
611 return Width == rhs.Width && Cost == rhs.Cost;
612 }
613
614 bool operator!=(const VectorizationFactor &rhs) const {
615 return !(*this == rhs);
616 }
617};
618
619/// A class that represents two vectorization factors (initialized with 0 by
620/// default). One for fixed-width vectorization and one for scalable
621/// vectorization. This can be used by the vectorizer to choose from a range of
622/// fixed and/or scalable VFs in order to find the most cost-effective VF to
623/// vectorize with.
627
629 : FixedVF(ElementCount::getFixed(0)),
630 ScalableVF(ElementCount::getScalable(0)) {}
632 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
633 }
637 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
638 "Invalid scalable properties");
639 }
640
642
643 /// \return true if either fixed- or scalable VF is non-zero.
644 explicit operator bool() const { return FixedVF || ScalableVF; }
645
646 /// \return true if either fixed- or scalable VF is a valid vector VF.
647 bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); }
648};
649
650/// Holds state needed to make cost decisions before computing costs per-VF,
651/// including the maximum VFs.
653 /// \return True if maximizing vector bandwidth is enabled by the target or
654 /// user options, for the given register kind (scalable or fixed-width).
655 bool useMaxBandwidth(bool IsScalable) const;
656
657 /// \return the maximized element count based on the targets vector
658 /// registers and the loop trip-count, but limited to a maximum safe VF.
659 /// This is a helper function of computeFeasibleMaxVF.
660 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
661 unsigned SmallestType,
662 unsigned WidestType,
663 ElementCount MaxSafeVF, unsigned UserIC,
664 bool FoldTailByMasking,
665 bool RequiresScalarEpilogue);
666
667 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
668 /// that results in VF * UserIC <= MaxTripCount.
669 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
670 unsigned UserIC, bool FoldTailByMasking,
671 bool RequiresScalarEpilogue) const;
672
673 /// Checks if scalable vectorization is supported and enabled. Caches the
674 /// result to avoid repeated debug dumps for repeated queries.
675 bool isScalableVectorizationAllowed();
676
677 /// \return the maximum legal scalable VF, based on the safe max number
678 /// of elements.
679 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
680
681 /// Initializes the value of vscale used for tuning the cost model. If
682 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
683 /// return the value returned by the corresponding TTI method.
684 void initializeVScaleForTuning();
685
686 const TargetTransformInfo &TTI;
687 const LoopVectorizationLegality *Legal;
688 const Loop *TheLoop;
689 const Function &F;
691 DemandedBits *DB;
693 const LoopVectorizeHints *Hints;
694
695 /// Cached result of isScalableVectorizationAllowed.
696 std::optional<bool> IsScalableVectorizationAllowed;
697
698 /// Used to store the value of vscale used for tuning the cost model. It is
699 /// initialized during object construction.
700 std::optional<unsigned> VScaleForTuning;
701
702 /// The highest VF possible for this loop, without using MaxBandwidth.
703 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
704
705 /// All element types found in the loop.
706 SmallPtrSet<Type *, 16> ElementTypesInLoop;
707
708 /// PHINodes of the reductions that should be expanded in-loop. Set by
709 /// collectInLoopReductions.
710 SmallPtrSet<PHINode *, 4> InLoopReductions;
711
712 /// A Map of inloop reduction operations and their immediate chain operand.
713 /// FIXME: This can be removed once reductions can be costed correctly in
714 /// VPlan. This was added to allow quick lookup of the inloop operations.
715 /// Set by collectInLoopReductions.
716 DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
717
718 /// Maximum safe number of elements to be processed per vector iteration,
719 /// which do not prevent store-load forwarding and are safe with regard to the
720 /// memory dependencies. Required for EVL-based vectorization, where this
721 /// value is used as the upper bound of the safe AVL. Set by
722 /// computeFeasibleMaxVF.
723 std::optional<unsigned> MaxSafeElements;
724
725 /// Map of scalar integer values to the smallest bitwidth they can be legally
726 /// represented as. The vector equivalents of these values should be truncated
727 /// to this type.
729
730public:
731 /// The kind of cost that we are calculating.
733
734 /// Whether this loop should be optimized for size based on function attribute
735 /// or profile information.
736 const bool OptForSize;
737
739 const LoopVectorizationLegality *Legal,
740 const Loop *TheLoop, const Function &F,
743 const LoopVectorizeHints *Hints, bool OptForSize)
744 : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
745 ORE(ORE), Hints(Hints),
746 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
748 initializeVScaleForTuning();
749 }
750
751 /// \return The vscale value used for tuning the cost model.
752 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
753
754 const TargetTransformInfo &getTTI() const { return TTI; }
755
756 PredicatedScalarEvolution &getPSE() const { return PSE; }
757
758 /// \return The loop being analyzed.
759 const Loop *getLoop() const { return TheLoop; }
760
761 /// \return True if register pressure should be considered for the given VF.
763
764 /// \return True if scalable vectors are supported by the target or forced.
765 bool supportsScalableVectors() const;
766
767 /// Collect element types in the loop that need widening.
769 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
770
771 /// \return The size (in bits) of the smallest and widest types in the code
772 /// that need to be vectorized. We ignore values that remain scalar such as
773 /// 64 bit loop indices.
774 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
775
776 /// \return An upper bound for the vectorization factors for both
777 /// fixed and scalable vectorization, where the minimum-known number of
778 /// elements is a power-of-2 larger than zero. If scalable vectorization is
779 /// disabled or unsupported, then the scalable part will be equal to
780 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
781 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
782 ElementCount UserVF, unsigned UserIC,
783 bool FoldTailByMasking,
784 bool RequiresScalarEpilogue);
785
786 /// Return maximum safe number of elements to be processed per vector
787 /// iteration, which do not prevent store-load forwarding and are safe with
788 /// regard to the memory dependencies. Required for EVL-based VPlans to
789 /// correctly calculate AVL (application vector length) as min(remaining AVL,
790 /// MaxSafeElements). Set by computeFeasibleMaxVF.
791 /// TODO: need to consider adjusting cost model to use this value as a
792 /// vectorization factor for EVL-based vectorization.
793 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
794
795 /// Returns true if we should use strict in-order reductions for the given
796 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
797 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
798 /// of FP operations.
799 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
800
801 /// Returns true if the target machine supports a masked load (if \p IsLoad)
802 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
803 /// space \p AddressSpace. The caller must ensure the access is consecutive or
804 /// part of an interleave group.
805 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
806 unsigned AddressSpace) const;
807
808 /// Returns true if the target machine can represent \p V as a masked gather
809 /// or scatter operation.
810 bool isLegalGatherOrScatter(Value *V, ElementCount VF) const;
811
812 /// Split reductions into those that happen in the loop, and those that
813 /// happen outside. In-loop reductions are collected into InLoopReductions.
814 /// InLoopReductionImmediateChains is filled with each in-loop reduction
815 /// operation and its immediate chain operand for use during cost modelling.
817
818 /// Returns true if the Phi is part of an inloop reduction.
819 bool isInLoopReduction(PHINode *Phi) const {
820 return InLoopReductions.contains(Phi);
821 }
822
823 /// Returns the set of in-loop reduction PHIs.
825 return InLoopReductions;
826 }
827
828 /// Returns the immediate chain operand of in-loop reduction operation \p I,
829 /// or nullptr if \p I is not an in-loop reduction operation.
831 return InLoopReductionImmediateChains.lookup(I);
832 }
833
834 /// Check whether vectorization would require runtime checks. When optimizing
835 /// for size, returning true here aborts vectorization.
837
838 /// Returns a scalable VF to use for outer-loop vectorization if the target
839 /// supports it and a fixed VF otherwise.
841
842 /// Compute smallest bitwidth each instruction can be represented with.
843 /// The vector equivalents of these instructions should be truncated to this
844 /// type.
846
847 /// \returns The smallest bitwidth each instruction can be represented with.
849 return MinBWs;
850 }
851};
852
853/// Planner drives the vectorization process after having passed
854/// Legality checks.
856 /// The loop that we evaluate.
857 Loop *OrigLoop;
858
859 /// Loop Info analysis.
860 LoopInfo *LI;
861
862 /// The dominator tree.
863 DominatorTree *DT;
864
865 /// Target Library Info.
866 const TargetLibraryInfo *TLI;
867
868 /// Target Transform Info.
869 const TargetTransformInfo &TTI;
870
871 /// The legality analysis.
873
874 /// The profitability analysis.
876
877 /// VF selection state independent of cost-modeling decisions.
878 VFSelectionContext &Config;
879
880 /// The interleaved access analysis.
882
884
885 const LoopVectorizeHints &Hints;
886
888
890
891 /// Profitable vector factors.
893
894 /// A builder used to construct the current plan.
895 VPBuilder Builder;
896
897 /// Computes the cost of \p Plan for vectorization factor \p VF.
898 ///
899 /// The current implementation requires access to the
900 /// LoopVectorizationLegality to handle inductions and reductions, which is
901 /// why it is kept separate from the VPlan-only cost infrastructure.
902 ///
903 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
904 /// been retired.
905 InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;
906
907 /// Precompute costs for certain instructions using the legacy cost model. The
908 /// function is used to bring up the VPlan-based cost model to initially avoid
909 /// taking different decisions due to inaccuracies in the legacy cost model.
910 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
911 VPCostContext &CostCtx) const;
912
913public:
915 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
920 : OrigLoop(L), LI(LI), DT(DT), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM),
921 Config(Config), IAI(IAI), PSE(PSE), Hints(Hints), ORE(ORE) {}
922
923 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
924 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
925 /// interleaving should be avoided up-front, no plans are generated.
926 void plan(ElementCount UserVF, unsigned UserIC);
927
928 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
929 /// for each VF.
930 VPlan &getPlanFor(ElementCount VF) const;
931
932 /// Compute and return the most profitable vectorization factor and the
933 /// corresponding best VPlan. Also collect all profitable VFs in
934 /// ProfitableVFs.
935 std::pair<VectorizationFactor, VPlan *> computeBestVF();
936
937 /// \return The desired interleave count.
938 /// If interleave count has been specified by metadata it will be returned.
939 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
940 /// are the selected vectorization factor and the cost of the selected VF.
941 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
942 InstructionCost LoopCost);
943
944 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
945 /// according to the best selected \p VF and \p UF.
946 ///
947 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
948 /// fixed.
949 ///
950 /// Returns a mapping of SCEVs to their expanded IR values.
951 /// Note that this is a temporary workaround needed due to the current
952 /// epilogue handling.
954 None, ///< Not part of epilogue vectorization.
955 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
956 Epilogue ///< Vectorizing the epilogue loop.
957 };
959 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
961 EpilogueVectorizationKind EpilogueVecKind =
963
964#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
965 void printPlans(raw_ostream &O);
966#endif
967
968 /// Look through the existing plans and return true if we have one with
969 /// vectorization factor \p VF.
971 return any_of(VPlans,
972 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
973 }
974
975 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
976 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
977 /// returned value holds for the entire \p Range.
978 static bool
979 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
980 VFRange &Range);
981
982 /// \return A VPlan for the most profitable epilogue vectorization, with its
983 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
984 /// Returns nullptr if epilogue vectorization is not supported or not
985 /// profitable for the loop.
986 std::unique_ptr<VPlan>
987 selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC);
988
989 /// Emit remarks for recipes with invalid costs in the available VPlans.
991
992 /// Create a check to \p Plan to see if the vector loop should be executed
993 /// based on its trip count.
994 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
995 ElementCount MinProfitableTripCount) const;
996
997 /// Returns true if \p Plan requires a scalar epilogue after the vector
998 /// loop. Asserts that the VPlan decision matches the legacy cost model.
999 bool requiresScalarEpilogue(VPlan &Plan, ElementCount VF) const;
1000
1001 /// Attach the runtime checks of \p RTChecks to \p Plan.
1002 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1003 bool HasBranchWeights) const;
1004
1005 /// Update loop metadata and profile info for both the scalar remainder loop
1006 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1007 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1008 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1009 /// the average trip count and invocation weight of the original loop (\p
1010 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1011 /// cannot be retrieved after the plan has been executed, as the original loop
1012 /// may have been removed.
1014 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1015 bool VectorizingEpilogue, MDNode *OrigLoopID,
1016 std::optional<unsigned> OrigAverageTripCount,
1017 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1018 bool DisableRuntimeUnroll);
1019
1020private:
1021 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1022 /// scalar transformations applied. Returns null if an initial VPlan cannot
1023 /// be built.
1024 VPlanPtr tryToBuildVPlan1();
1025
1026 /// Build a VPlan using VPRecipes according to the information gathered by
1027 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1028 /// conversion only. For inner loops, \p Range's largest included VF is
1029 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1030 /// can be built for the input range, set the largest included VF to the
1031 /// maximum VF for which no plan could be built. Each VPlan is built starting
1032 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1033 /// original scalar loop.
1034 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);
1035
1036 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1037 /// based on \p VPlan1 and according to the information gathered by Legal
1038 /// when it checked if it is legal to vectorize the loop.
1039 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);
1040
1041 /// Add ComputeReductionResult recipes to the middle block to compute the
1042 /// final reduction results. Add Select recipes to the latch block when
1043 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1044 /// iteration values according to the header mask.
1045 void addReductionResultComputation(VPlanPtr &Plan,
1046 VPRecipeBuilder &RecipeBuilder,
1047 ElementCount MinVF);
1048
1049 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1050 /// that of B.
1051 bool isMoreProfitable(const VectorizationFactor &A,
1052 const VectorizationFactor &B, bool HasTail,
1053 bool IsEpilogue = false) const;
1054
1055 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1056 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1057 bool isMoreProfitable(const VectorizationFactor &A,
1058 const VectorizationFactor &B,
1059 const unsigned MaxTripCount, bool HasTail,
1060 bool IsEpilogue = false) const;
1061
1062 /// Determines if we have the infrastructure to vectorize the loop and its
1063 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1064 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1065};
1066
1067/// A helper function that returns true if the given type is irregular. The
1068/// type is irregular if its allocated size doesn't equal the store size of an
1069/// element of the corresponding vector type.
1070inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1071 // Determine if an array of N elements of type Ty is "bitcast compatible"
1072 // with a <N x Ty> vector.
1073 // This is only true if there is no padding between the array elements.
1074 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1075}
1076
1077} // namespace llvm
1078
1079#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:151
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:1698
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:1749
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:1663
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1855
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:4376
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4403
iterator end()
Definition VPlan.h:4413
VPlan * getPlan()
Definition VPlan.cpp:211
InsertPointGuard(const InsertPointGuard &)=delete
InsertPointGuard & operator=(const InsertPointGuard &)=delete
InsertPoint - A saved insertion point.
VPInsertPoint(VPBasicBlock *InsertBlock, VPBasicBlock::iterator InsertPoint)
Creates a new insertion point at the given location.
VPBasicBlock::iterator getPoint() const
VPInsertPoint()=default
Creates a new insertion point which doesn't point to anything.
bool isSet() const
Returns true if this insert point is set.
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)
This specifies that created instructions should be inserted at the specified point.
void setInsertPoint(VPRecipeBase *IP)
This specifies that created instructions should be inserted at the specified point.
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:1678
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:1650
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBasicBlock * getInsertBlock() const
VPBasicBlock::iterator getInsertPoint() const
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)
VPBuilder(VPBasicBlock *InsertBB)
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="")
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.
VPBuilder(VPRecipeBase *InsertPt)
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.
void clearInsertionPoint()
Clear the insertion point: created instructions will not be inserted into a block.
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="")
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block.
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4170
Recipe to expand a SCEV expression.
Definition VPlan.h:4002
Class to record and manage LLVM IR flags.
Definition VPlan.h:704
static VPIRFlags getDefaultFlags(unsigned Opcode)
Returns default flags for Opcode 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
VPBasicBlock * getParent()
Definition VPlan.h:483
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3384
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4231
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:2739
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4780
const DataLayout & getDataLayout() const
Definition VPlan.h:4987
LLVMContext & getContext() const
Definition VPlan.h:4983
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:5089
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
self_iterator getIterator()
Definition ilist_node.h:123
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:3795
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3894
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)