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 "VPlanUtils.h"
29#include "llvm/ADT/SmallSet.h"
32#include <optional>
33
34namespace {
35class GeneratedRTChecks;
36}
37
38namespace llvm {
39
41class LoopInfo;
42class DominatorTree;
48class LoopVersioning;
51class VPRecipeBuilder;
52struct VPRegisterUsage;
53struct VFRange;
54
55/// \return An upper bound for vscale based on TTI or the vscale_range
56/// attribute.
57std::optional<unsigned> getMaxVScale(const Function &F);
58
59/// \return The upper bound for the runtime value of \p EC, or std::nullopt
60/// if the upper bound is unknown.
61std::optional<uint64_t>
63
64// Utility functions that are used by different vectorization classes
66
67/// Reports a vectorization failure: print \p DebugMsg for debugging
68/// purposes along with the corresponding optimization remark \p RemarkName.
69/// If \p I is passed, it is an instruction that prevents vectorization.
70/// Otherwise, the loop \p TheLoop is used for the location of the remark.
71void reportVectorizationFailure(const StringRef DebugMsg,
72 const StringRef OREMsg, const StringRef ORETag,
74 const Loop *TheLoop, Instruction *I = nullptr);
75
76/// Same as above, but the debug message and optimization remark are identical
77inline void reportVectorizationFailure(const StringRef DebugMsg,
78 const StringRef ORETag,
80 const Loop *TheLoop,
81 Instruction *I = nullptr) {
82 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
83}
84
85/// Reports an informative message: print \p Msg for debugging purposes as well
86/// as an optimization remark. Uses either \p I as location of the remark, or
87/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
88/// remark.
89void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
91 const Loop *TheLoop, Instruction *I = nullptr,
92 DebugLoc DL = {});
93
94/// Report successful vectorization of the loop. In case an outer loop is
95/// vectorized, prepend "outer" to the vectorization remark.
96void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
97 ElementCount VFWidth, unsigned IC);
98
99} // namespace LoopVectorizationUtils
100
101/// Default inserter for VPBuilderBase, inserting \p R at \p It in \p VPBB.
105 VPBB->insert(R, It);
106 }
107};
108
109/// VPlan-based builder utility similar to IRBuilder. Recipes are inserted via
110/// \p InserterTy.
111template <typename InserterTy> class VPBuilderBase : public InserterTy {
112private:
113 class VPInsertPoint {
114 VPBasicBlock *Block = nullptr;
115 VPBasicBlock::iterator Iterator;
116
117 public:
118 /// Creates a new insertion point which doesn't point to anything.
119 VPInsertPoint() = default;
120
121 /// Creates a new insertion point to insert at \p Iterator in \p Block.
122 VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Iterator)
123 : Block(Block), Iterator(Iterator) {}
124
125 /// Creates a new insertion point to insert before \p R.
126 VPInsertPoint(VPRecipeBase *R)
127 : Block(R->getParent()), Iterator(R->getIterator()) {}
128
129 /// Creates a new insertion point to insert at the end of \p Block.
130 VPInsertPoint(VPBasicBlock *Block) : Block(Block), Iterator(Block->end()) {}
131
132 /// Returns true if this insert point is set.
133 operator bool() const { return Block; }
134
135 VPBasicBlock *getBlock() const { return Block; }
136 VPBasicBlock::iterator getIterator() const { return Iterator; }
137
138 operator VPRecipeBase *() const {
139 return Iterator == Block->end() ? nullptr : &*Iterator;
140 }
141 };
142
143 VPInsertPoint InsertPt;
144
145protected:
146 /// Insert \p VPI in BB at InsertPt if BB is set.
147 template <typename T> T *tryInsertInstruction(T *R) {
148 if (InsertPt)
149 InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
150 return R;
151 }
152
155 const VPIRMetadata &MD, DebugLoc DL,
156 const Twine &Name = "") {
158 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
159 }
160
161public:
162 VPlan &getPlan() const {
163 assert(InsertPt && "Insert block must be set");
164 return *InsertPt.getBlock()->getPlan();
165 }
166
167 VPBuilderBase() = default;
168 VPBuilderBase(const VPInsertPoint &IP) : InsertPt(IP) {}
169 VPBuilderBase(InserterTy Inserter) : InserterTy(Inserter) {}
171 : InsertPt(TheBB, IP) {}
172
173 /// Get the recipe at the current insert point or nullptr if the insert point
174 /// is the end of the block.
175 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
176
177 /// Create a builder to insert after \p R.
179 return {R->getParent(), std::next(R->getIterator())};
180 }
181
182 /// Sets the current insert point to a previously-saved location.
183 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
184
185 /// Set the current insert point.
186 void setInsertPoint(const VPInsertPoint &IP) {
187 assert(IP && "Attempting to set a null insert point");
188 InsertPt = IP;
189 }
191 assert(TheBB && "Attempting to set a null insert point");
192 InsertPt = VPInsertPoint(TheBB, IP);
193 }
194
195 /// Insert \p R at the current insertion point. Returns \p R unchanged.
196 template <typename T> [[maybe_unused]] T *insert(T *R) {
197 InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
198 return R;
199 }
200
201 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
202 /// its underlying Instruction.
204 Instruction *Inst = nullptr,
205 const VPIRFlags &Flags = {},
206 const VPIRMetadata &MD = {},
208 const Twine &Name = "",
209 Type *ResultTy = nullptr) {
210 VPInstruction *NewVPInst = tryInsertInstruction(
211 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
212 NewVPInst->setUnderlyingValue(Inst);
213 return NewVPInst;
214 }
216 DebugLoc DL, const Twine &Name = "") {
217 return createInstruction(Opcode, Operands, {}, DL, Name);
218 }
220 const VPIRFlags &Flags,
222 const Twine &Name = "") {
224 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
225 }
226
228 Type *ResultTy, const VPIRFlags &Flags = {},
230 const Twine &Name = "") {
232 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
233 }
234
237 const Twine &Name = "") {
238 // Assume that the maximum possible number of elements in a vector fits
239 // within the index type for the default address space.
240 VPlan &Plan = getPlan();
241 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
243 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
244 }
245
248 const Twine &Name = "") {
249 // Assume that the maximum possible number of elements in a vector fits
250 // within the index type for the default address space.
251 VPlan &Plan = getPlan();
252 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
254 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
255 }
256
258 unsigned Opcode, ArrayRef<VPValue *> Operands,
259 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
260 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
262 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
263 }
264
267 const Twine &Name = "") {
268 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
269 }
270
273 const Twine &Name = "") {
274 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
275 Name);
276 }
277
280 const Twine &Name = "") {
281
283 Instruction::BinaryOps::Or, {LHS, RHS},
284 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
285 }
286
289 const Twine &Name = "",
290 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
291 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
292 Name);
293 }
294
295 VPInstruction *
297 const Twine &Name = "",
298 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
299 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
300 Name);
301 }
302
308
314
315 /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
316 /// default flags for the result type, unless \p Flags is set.
318 VPValue *FalseVal,
320 const Twine &Name = "",
321 std::optional<VPIRFlags> Flags = std::nullopt) {
323 new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
324 Flags.value_or(VPIRFlags::getDefaultFlags(
325 Instruction::Select, TrueVal->getScalarType())),
326 {}, DL, Name));
327 }
328
329 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
330 /// and \p B.
333 const Twine &Name = "") {
335 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
337 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
338 }
339
340 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
341 /// and \p B.
344 const Twine &Name = "") {
346 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
348 new VPInstruction(Instruction::FCmp, {A, B},
349 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
350 }
351
352 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
353 /// result, then select between \p TrueVal and \p FalseVal.
355 VPValue *FalseVal,
357 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
358 "ChainOp must be i1 for AnyOf reduction");
359 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
360 FastMathFlags());
362 {ChainOp}, Flags, DL);
363 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
364 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
365 }
366
369 const Twine &Name = "") {
370 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
371 }
372
374 GEPNoWrapFlags GEPFlags,
376 const Twine &Name = "") {
378 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
379 }
380
388
389 /// Create a phi with \p IncomingValues, using the default flags for the
390 /// result type, unless \p Flags is set.
393 const Twine &Name = "",
394 std::optional<VPIRFlags> Flags = std::nullopt,
395 Type *ResultTy = nullptr) {
396 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
397 return tryInsertInstruction(new VPPhi(
398 IncomingValues,
399 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
400 DL, Name, ResultTy));
401 }
402
405 const Twine &Name = "") {
406 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
407 }
408
410 VPlan &Plan = getPlan();
411 unsigned MinEC = EC.getKnownMinValue();
412 if (EC.isScalable()) {
413 VPValue *VScale = createVScale(Ty);
414 if (MinEC == 1)
415 return VScale;
416 // TODO: Move this optimization into createOverflowingOp directly.
417 if (isPowerOf2_32(MinEC)) {
418 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
419 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
420 {true, false});
421 }
422 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
423 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
424 {true, false});
425 }
426 return Plan.getConstantInt(Ty, MinEC);
427 }
428
429 /// Convert \p Current to \p Start + \p Current * \p Step.
431 FPMathOperator *FPBinOp, VPValue *Start,
432 VPValue *Current, VPValue *Step,
433 const VPIRFlags::WrapFlagsTy &Flags = {}) {
435 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
436 }
437
439 Type *ResultTy, DebugLoc DL,
440 std::optional<VPIRFlags> Flags = std::nullopt,
441 const VPIRMetadata &Metadata = {}) {
443 Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
444 Metadata, DL, "", ResultTy));
445 }
446
447 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
448 /// result type \p ResultTy
451 Type *ResultTy, DebugLoc DL) {
452 VPlan &Plan = getPlan();
454 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
456 {}, {}, DL, "", ResultTy));
457 }
458
459 /// Create a scalar llvm.vscale call.
462 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
463 }
464
466 Type *SrcTy = Op->getScalarType();
467 if (ResultTy == SrcTy)
468 return Op;
469 Instruction::CastOps CastOp =
470 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
471 ? Instruction::Trunc
472 : Instruction::ZExt;
473 return createScalarCast(CastOp, Op, ResultTy, DL);
474 }
475
477 Type *SrcTy = Op->getScalarType();
478 if (ResultTy == SrcTy)
479 return Op;
480 Instruction::CastOps CastOp =
481 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
482 ? Instruction::Trunc
483 : Instruction::SExt;
484 return createScalarCast(CastOp, Op, ResultTy, DL);
485 }
486
488 const Twine &Name = "") {
489 return createNaryOp(Instruction::Freeze, Op, DL, Name);
490 }
491
493 Type *ResultTy) {
494 assert(Op->getScalarType() != ResultTy &&
495 "must not create a no-op cast recipe");
497 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
498 }
499
500 /// Create a single-scalar recipe with \p Opcode and \p Operands without
501 /// inserting it.
502 static VPSingleDefRecipe *
504 VPValue *Mask, const VPIRFlags &Flags,
506 Type *ResultTy, Instruction *UV) {
507 if (Instruction::isCast(Opcode)) {
508 assert(!Mask && "Cast cannot be predicated");
509 auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
510 UV->getName(), ResultTy);
511 VPI->setUnderlyingValue(UV);
512 return VPI;
513 }
514 auto *RepR = new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true,
515 Mask, Flags, Metadata, DL);
516 assert(RepR->getScalarType() == ResultTy && "unexpected result type");
517 return RepR;
518 }
519
522 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
523 VPValue *VF, DebugLoc DL) {
525 IV, Step, VF, InductionOpcode,
526 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
527 }
528
532
534 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
535 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
537 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
538 }
539
540 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
541 /// with element type \p SourceElementTy.
543 Type *SourceElementTy,
544 bool Reverse, DebugLoc DL) {
545 VPlan &Plan = getPlan();
547 if (Reverse) {
548 // When folding the tail, we may compute an address that we don't in the
549 // original scalar loop: drop the GEP no-wrap flags in this case.
550 // Otherwise preserve existing flags without no-unsigned-wrap, as we will
551 // emit negative indices.
552 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
554 : Flags.withoutNoUnsignedWrap();
556 new VPVectorEndPointerRecipe(Ptr, &Plan.getVF(), SourceElementTy,
557 /*Stride=*/-1, ReverseFlags, DL));
558 }
559 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
560 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
561 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
562 }
563
565 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
566 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
568 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
569 }
570
571 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
572 /// be null).
574 VPValue *Mask, bool Consecutive,
575 const VPIRMetadata &Metadata,
576 DebugLoc DL) {
578 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
579 }
580
581 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
582 /// \p Mask (may be null).
584 VPValue *StoredVal, VPValue *Mask,
585 bool Consecutive,
586 const VPIRMetadata &Metadata,
587 DebugLoc DL) {
589 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
590 }
591
592 //===--------------------------------------------------------------------===//
593 // RAII helpers.
594 //===--------------------------------------------------------------------===//
595
596 /// RAII object that stores the current insertion point and restores it when
597 /// the object is destroyed.
599 VPBuilderBase &Builder;
600 VPInsertPoint InsertPt;
601
602 public:
603 InsertPointGuard(VPBuilderBase &B) : Builder(B), InsertPt(B.InsertPt) {}
604
607
608 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
609 };
610};
611
612/// TODO: The following VectorizationFactor was pulled out of
613/// LoopVectorizationCostModel class. LV also deals with
614/// VectorizerParams::VectorizationFactor.
615/// We need to streamline them.
616
617/// Information about vectorization costs.
619 /// Vector width with best cost.
621
622 /// Cost of the loop with that width.
624
625 /// Cost of the scalar loop.
627
628 /// The minimum trip count required to make vectorization profitable, e.g. due
629 /// to runtime checks.
631
635
636 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
638 return {ElementCount::getFixed(1), 0, 0};
639 }
640};
641
642/// A class that represents two vectorization factors (initialized with 0 by
643/// default). One for fixed-width vectorization and one for scalable
644/// vectorization. This can be used by the vectorizer to choose from a range of
645/// fixed and/or scalable VFs in order to find the most cost-effective VF to
646/// vectorize with.
650
652 : FixedVF(ElementCount::getFixed(0)),
653 ScalableVF(ElementCount::getScalable(0)) {}
655 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
656 }
660 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
661 "Invalid scalable properties");
662 }
663
665
666 /// \return true if either fixed- or scalable VF is non-zero.
667 explicit operator bool() const { return FixedVF || ScalableVF; }
668};
669
670/// Holds state needed to make cost decisions before computing costs per-VF,
671/// including the maximum VFs.
673 /// \return True if maximizing vector bandwidth is enabled by the target or
674 /// user options, for the given register kind (scalable or fixed-width).
675 bool useMaxBandwidth(bool IsScalable) const;
676
677 /// \return the maximized element count based on the targets vector
678 /// registers and the loop trip-count, but limited to a maximum safe VF.
679 /// This is a helper function of computeFeasibleMaxVF.
680 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
681 unsigned SmallestType,
682 unsigned WidestType,
683 ElementCount MaxSafeVF, unsigned UserIC,
684 bool FoldTailByMasking,
685 bool RequiresScalarEpilogue);
686
687 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
688 /// that results in VF * UserIC <= MaxTripCount.
689 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
690 unsigned UserIC, bool FoldTailByMasking,
691 bool RequiresScalarEpilogue) const;
692
693 /// Checks if scalable vectorization is supported and enabled. Caches the
694 /// result to avoid repeated debug dumps for repeated queries.
695 bool isScalableVectorizationAllowed();
696
697 /// \return the maximum legal scalable VF, based on the safe max number
698 /// of elements.
699 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
700
701 /// Initializes the value of vscale used for tuning the cost model. If
702 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
703 /// return the value returned by the corresponding TTI method.
704 void initializeVScaleForTuning();
705
706 const TargetTransformInfo &TTI;
707 const LoopVectorizationLegality *Legal;
708 const Loop *TheLoop;
709 const Function &F;
711 DemandedBits *DB;
713 const LoopVectorizeHints *Hints;
714
715 /// Cached result of isScalableVectorizationAllowed.
716 std::optional<bool> IsScalableVectorizationAllowed;
717
718 /// Used to store the value of vscale used for tuning the cost model. It is
719 /// initialized during object construction.
720 std::optional<unsigned> VScaleForTuning;
721
722 /// The highest VF possible for this loop, without using MaxBandwidth.
723 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
724
725 /// All element types found in the loop.
726 SmallPtrSet<Type *, 16> ElementTypesInLoop;
727
728 /// PHINodes of the reductions that should be expanded in-loop. Set by
729 /// collectInLoopReductions.
730 SmallPtrSet<PHINode *, 4> InLoopReductions;
731
732 /// Maximum safe number of elements to be processed per vector iteration,
733 /// which do not prevent store-load forwarding and are safe with regard to the
734 /// memory dependencies. Required for EVL-based vectorization, where this
735 /// value is used as the upper bound of the safe AVL. Set by
736 /// computeFeasibleMaxVF.
737 std::optional<unsigned> MaxSafeElements;
738
739 /// Map of scalar integer values to the smallest bitwidth they can be legally
740 /// represented as. The vector equivalents of these values should be truncated
741 /// to this type.
743
744public:
745 /// The kind of cost that we are calculating.
747
748 /// Whether this loop should be optimized for size based on function attribute
749 /// or profile information.
750 const bool OptForSize;
751
753 const LoopVectorizationLegality *Legal,
754 const Loop *TheLoop, const Function &F,
757 const LoopVectorizeHints *Hints, bool OptForSize)
758 : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
759 ORE(ORE), Hints(Hints),
760 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
762 initializeVScaleForTuning();
763 }
764
765 /// \return The vscale value used for tuning the cost model.
766 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
767
768 const TargetTransformInfo &getTTI() const { return TTI; }
769
770 PredicatedScalarEvolution &getPSE() const { return PSE; }
771
772 /// \return The loop being analyzed.
773 const Loop *getLoop() const { return TheLoop; }
774
775 /// \return The vectorization hints for the loop being analyzed.
776 const LoopVectorizeHints &getHints() const { return *Hints; }
777
778 /// Returns true if epilogue vectorization is considered profitable for a
779 /// main loop with vectorization factor \p VF and interleave count \p IC.
780 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
781
782 /// \return True if register pressure should be considered for the given VF.
784
785 /// \return True if scalable vectors are supported by the target or forced.
786 bool supportsScalableVectors() const;
787
788 /// Collect element types in the loop that need widening.
790 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
791
792 /// \return The size (in bits) of the smallest and widest types in the code
793 /// that need to be vectorized. We ignore values that remain scalar such as
794 /// 64 bit loop indices.
795 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
796
797 /// \return An upper bound for the vectorization factors for both
798 /// fixed and scalable vectorization, where the minimum-known number of
799 /// elements is a power-of-2 larger than zero. If scalable vectorization is
800 /// disabled or unsupported, then the scalable part will be equal to
801 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
802 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
803 ElementCount UserVF, unsigned UserIC,
804 bool FoldTailByMasking,
805 bool RequiresScalarEpilogue);
806
807 /// Return maximum safe number of elements to be processed per vector
808 /// iteration, which do not prevent store-load forwarding and are safe with
809 /// regard to the memory dependencies. Required for EVL-based VPlans to
810 /// correctly calculate AVL (application vector length) as min(remaining AVL,
811 /// MaxSafeElements). Set by computeFeasibleMaxVF.
812 /// TODO: need to consider adjusting cost model to use this value as a
813 /// vectorization factor for EVL-based vectorization.
814 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
815
816 /// Returns true if we should use strict in-order reductions for the given
817 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
818 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
819 /// of FP operations.
820 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
821
822 /// Returns true if the target machine supports a masked load (if \p IsLoad)
823 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
824 /// space \p AddressSpace. The caller must ensure the access is consecutive or
825 /// part of an interleave group.
826 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
827 unsigned AddressSpace) const;
828
829 /// Returns true if the target machine supports a gather (if \p IsLoad)
830 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
831 /// factor \p VF.
832 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
833 ElementCount VF) const;
834
835 /// Split reductions into those that happen in the loop, and those that
836 /// happen outside. In-loop reductions are collected into InLoopReductions.
838
839 /// Returns true if the Phi is part of an inloop reduction.
840 bool isInLoopReduction(PHINode *Phi) const {
841 return InLoopReductions.contains(Phi);
842 }
843
844 /// Returns the set of in-loop reduction PHIs.
846 return InLoopReductions;
847 }
848
849 /// Check whether vectorization would require runtime checks. When optimizing
850 /// for size, returning true here aborts vectorization.
852
853 /// Returns a scalable VF to use for outer-loop vectorization if the target
854 /// supports it and a fixed VF otherwise.
856
857 /// Compute smallest bitwidth each instruction can be represented with.
858 /// The vector equivalents of these instructions should be truncated to this
859 /// type.
861
862 /// \returns The smallest bitwidth each instruction can be represented with.
864 return MinBWs;
865 }
866};
867
868/// Planner drives the vectorization process after having passed
869/// Legality checks.
871 /// The loop that we evaluate.
872 Loop *OrigLoop;
873
874 /// Loop Info analysis.
875 LoopInfo *LI;
876
877 /// The dominator tree.
878 DominatorTree *DT;
879
880 /// Target Library Info.
881 const TargetLibraryInfo *TLI;
882
883 /// Target Transform Info.
884 const TargetTransformInfo &TTI;
885
886 /// The legality analysis.
888
889 /// The profitability analysis. Cleared after making cost based decisions.
890 std::unique_ptr<LoopVectorizationCostModel> CM;
891
892 /// VF selection state independent of cost-modeling decisions.
893 VFSelectionContext &Config;
894
895 /// The interleaved access analysis.
897
899
901
902 /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
903 std::function<const BranchProbabilityInfo &()> GetBPI;
904
906
907 /// Profitable vector factors.
909
910 /// A builder used to construct the current plan.
911 VPBuilder Builder;
912
913 /// Computes the cost of \p Plan for vectorization factor \p VF.
914 ///
915 /// The current implementation requires access to the
916 /// LoopVectorizationLegality to handle inductions and reductions, which is
917 /// why it is kept separate from the VPlan-only cost infrastructure.
918 ///
919 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
920 /// been retired.
921 InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;
922
923 /// Precompute costs for certain instructions using the legacy cost model. The
924 /// function is used to bring up the VPlan-based cost model to initially avoid
925 /// taking different decisions due to inaccuracies in the legacy cost model.
926 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
927 VPCostContext &CostCtx) const;
928
929public:
931 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
933 std::unique_ptr<LoopVectorizationCostModel> CM,
936 std::function<const BranchProbabilityInfo &()> GetBPI);
937
939
940 /// Return the cost model. Must not be called after clearCostModel().
942 assert(CM && "Cost model has already been cleared");
943 return *CM;
944 }
945
946 /// Destroy the cost model.
947 void clearCostModel();
948
949 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
950 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
951 /// interleaving should be avoided up-front, no plans are generated.
952 void plan(ElementCount UserVF, unsigned UserIC);
953
954 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
955 /// for each VF.
956 VPlan &getPlanFor(ElementCount VF) const;
957
958 /// Compute and return the most profitable vectorization factor and the
959 /// corresponding best VPlan. Also collect all profitable VFs in
960 /// ProfitableVFs.
961 std::pair<VectorizationFactor, VPlan *> computeBestVF();
962
963 /// \return The desired interleave count.
964 /// If interleave count has been specified by metadata it will be returned.
965 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
966 /// are the selected vectorization factor and the cost of the selected VF.
967 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
968 InstructionCost LoopCost);
969
970 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
971 /// according to the best selected \p VF and \p UF.
972 ///
973 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
974 /// fixed.
975 ///
976 /// Returns a mapping of SCEVs to their expanded IR values.
977 /// Note that this is a temporary workaround needed due to the current
978 /// epilogue handling.
980 None, ///< Not part of epilogue vectorization.
981 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
982 Epilogue ///< Vectorizing the epilogue loop.
983 };
985 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
987 EpilogueVectorizationKind EpilogueVecKind =
989
990#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
991 void printPlans(raw_ostream &O);
992#endif
993
994 /// Look through the existing plans and return true if we have one with
995 /// vectorization factor \p VF.
997 return any_of(VPlans,
998 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
999 }
1000
1001 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
1002 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
1003 /// returned value holds for the entire \p Range.
1004 static bool
1005 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
1006 VFRange &Range);
1007
1008 /// \return A VPlan for the most profitable epilogue vectorization, with its
1009 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
1010 /// Returns nullptr if epilogue vectorization is not supported or not
1011 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
1012 /// epilogue lowering policy permits creating a scalar epilogue at all.
1013 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
1014 ElementCount MainLoopVF,
1015 unsigned IC,
1016 bool ScalarEpilogueAllowed);
1017
1018 /// Emit remarks for recipes with invalid costs in the available VPlans.
1020
1021 /// Create a check to \p Plan to see if the vector loop should be executed
1022 /// based on its trip count.
1023 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1024 ElementCount MinProfitableTripCount) const;
1025
1026 /// Attach the runtime checks of \p RTChecks to \p Plan.
1027 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1028 bool HasBranchWeights) const;
1029
1030 /// Update loop metadata and profile info for both the scalar remainder loop
1031 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1032 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1033 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1034 /// the average trip count and invocation weight of the original loop (\p
1035 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1036 /// cannot be retrieved after the plan has been executed, as the original loop
1037 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1038 /// target wants the vector loop left eligible for runtime unrolling.
1040 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1041 bool VectorizingEpilogue, MDNode *OrigLoopID,
1042 std::optional<unsigned> OrigAverageTripCount,
1043 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1044 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1045
1046private:
1047 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1048 /// scalar transformations applied. Returns null if an initial VPlan cannot
1049 /// be built.
1050 VPlanPtr tryToBuildVPlan1();
1051
1052 /// Build a VPlan using VPRecipes according to the information gathered by
1053 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1054 /// conversion only. For inner loops, \p Range's largest included VF is
1055 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1056 /// can be built for the input range, set the largest included VF to the
1057 /// maximum VF for which no plan could be built. Each VPlan is built starting
1058 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1059 /// original scalar loop.
1060 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);
1061
1062 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1063 /// based on \p VPlan1 and according to the information gathered by Legal
1064 /// when it checked if it is legal to vectorize the loop.
1065 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);
1066
1067 /// Add ComputeReductionResult recipes to the middle block to compute the
1068 /// final reduction results. Add Select recipes to the latch block when
1069 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1070 /// iteration values according to the header mask.
1071 void addReductionResultComputation(VPlanPtr &Plan, ElementCount MinVF);
1072
1073 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1074 /// that of B.
1075 bool isMoreProfitable(const VectorizationFactor &A,
1076 const VectorizationFactor &B, bool HasTail,
1077 bool IsEpilogue = false) const;
1078
1079 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1080 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1081 bool isMoreProfitable(const VectorizationFactor &A,
1082 const VectorizationFactor &B,
1083 const unsigned MaxTripCount, bool HasTail,
1084 bool IsEpilogue = false) const;
1085
1086 /// Determines if we have the infrastructure to vectorize the loop and its
1087 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1088 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1089};
1090
1091/// A helper function that returns true if the given type is irregular. The
1092/// type is irregular if its allocated size doesn't equal the store size of an
1093/// element of the corresponding vector type.
1094inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1095 // Determine if an array of N elements of type Ty is "bitcast compatible"
1096 // with a <N x Ty> vector.
1097 // This is only true if there is no padding between the array elements.
1098 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1099}
1100
1101} // namespace llvm
1102
1103#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")
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
Analysis providing branch probability information.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags.
Definition Operator.h:291
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
InductionKind
This enum represents the kinds of inductions that we support.
InnerLoopVectorizer vectorizes loops which contain only one basic block to a specified vectorization ...
bool isCast() const
Drive the analysis of interleaved memory accesses in the loop.
An instruction for reading from memory.
LoopVectorizationCostModel - estimates the expected speedups due to vectorization.
LoopVectorizationLegality checks if it is legal to vectorize a loop, and to what vectorization factor...
DenseMap< const SCEV *, Value * > executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan, InnerLoopVectorizer &LB, DominatorTree *DT, EpilogueVectorizationKind EpilogueVecKind=EpilogueVectorizationKind::None)
EpilogueVectorizationKind
Generate the IR code for the vectorized loop captured in VPlan BestPlan according to the best selecte...
@ MainLoop
Vectorizing the main loop of epilogue vectorization.
void clearCostModel()
Destroy the cost model.
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
Definition VPlan.cpp:1652
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:1703
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, std::function< const BranchProbabilityInfo &()> GetBPI)
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1638
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1807
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:1081
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:222
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
Holds state needed to make cost decisions before computing costs per-VF, including the maximum VFs.
PredicatedScalarEvolution & getPSE() const
const bool OptForSize
Whether this loop should be optimized for size based on function attribute or profile information.
FixedScalableVFPair computeVPlanOuterloopVF(ElementCount UserVF)
Returns a scalable VF to use for outer-loop vectorization if the target supports it and a fixed VF ot...
bool isInLoopReduction(PHINode *Phi) const
Returns true if the Phi is part of an inloop reduction.
std::pair< unsigned, unsigned > getSmallestAndWidestTypes() const
const TTI::TargetCostKind CostKind
The kind of cost that we are calculating.
bool runtimeChecksRequired()
Check whether vectorization would require runtime checks.
bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment, ElementCount VF) const
Returns true if the target machine supports a gather (if IsLoad) or scatter of scalar type ScalarTy w...
bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment, unsigned AddressSpace) const
Returns true if the target machine supports a masked load (if IsLoad) or masked store of scalar type ...
void collectInLoopReductions()
Split reductions into those that happen in the loop, and those that happen outside.
const TargetTransformInfo & getTTI() const
const SmallPtrSetImpl< PHINode * > & getInLoopReductions() const
Returns the set of in-loop reduction PHIs.
std::optional< unsigned > getMaxSafeElements() const
Return maximum safe number of elements to be processed per vector iteration, which do not prevent sto...
FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC, bool FoldTailByMasking, bool RequiresScalarEpilogue)
const MapVector< Instruction *, uint64_t > & getMinimalBitwidths() const
const LoopVectorizeHints & getHints() const
VFSelectionContext(const TargetTransformInfo &TTI, const LoopVectorizationLegality *Legal, const Loop *TheLoop, const Function &F, PredicatedScalarEvolution &PSE, DemandedBits *DB, OptimizationRemarkEmitter *ORE, const LoopVectorizeHints *Hints, bool OptForSize)
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:4414
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4441
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4480
InsertPointGuard(const InsertPointGuard &)=delete
InsertPointGuard & operator=(const InsertPointGuard &)=delete
VPInstruction * createFreeze(VPValue *Op, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRMetadata &MD, DebugLoc DL, const Twine &Name="")
static VPBuilderBase getToInsertAfter(VPRecipeBase *R)
Create a builder to insert after R.
void restoreIP(VPInsertPoint IP)
Sets the current insert point to a previously-saved location.
VPVectorPointerRecipe * createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * 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 * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createWidePtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnyOfReduction(VPValue *ChainOp, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown())
Create an AnyOf reduction pattern: or-reduce ChainOp, freeze the result, then select between TrueVal ...
T * tryInsertInstruction(T *R)
Insert VPI in BB at InsertPt if BB is set.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags GEPFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
VPExpandSCEVRecipe * createExpandSCEV(const SCEV *Expr)
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Convert Current to Start + Current * Step.
VPBuilderBase(const VPInsertPoint &IP)
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Type *ResultTy, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPInstruction * createVScale(Type *ResultTy, DebugLoc DL=DebugLoc::getUnknown())
Create a scalar llvm.vscale call.
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, std::optional< VPIRFlags > Flags=std::nullopt, const VPIRMetadata &Metadata={})
void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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 setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPBuilderBase()=default
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 * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPSingleDefRecipe * createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, bool Reverse, DebugLoc DL)
Create a vector pointer recipe for a consecutive memory access to Ptr with element type SourceElement...
VPInstruction * createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
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.
VPWidenMemIntrinsicRecipe * createWidenMemIntrinsic(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL)
VPInstruction * createFirstActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilderBase(InserterTy Inserter)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPWidenPHIRecipe * createWidenPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createElementCount(Type *Ty, ElementCount EC)
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilderBase(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4195
Recipe to expand a SCEV expression.
Definition VPlan.h:4027
Class to record and manage LLVM IR flags.
Definition VPlan.h:696
static LLVM_ABI_FOR_TEST VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
Helper to manage IR metadata for recipes.
Definition VPlan.h:1181
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1300
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1421
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1354
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:403
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3397
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4256
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:611
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:147
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2278
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2360
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1885
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2061
A recipe for widened phis.
Definition VPlan.h:2750
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4826
const DataLayout & getDataLayout() const
Definition VPlan.h:5040
LLVMContext & getContext() const
Definition VPlan.h:5036
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:4943
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5027
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:5146
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.
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
VPBuilderBase<> VPBuilder
Definition VPlan.h:67
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
std::optional< uint64_t > getMaxRuntimeElementCount(ElementCount EC, const Function &F)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
@ Or
Bitwise or logical OR of integers.
DWARFExpression::Operation Op
std::optional< unsigned > getMaxVScale(const Function &F)
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:78
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A class that represents two vectorization factors (initialized with 0 by default).
FixedScalableVFPair(const ElementCount &FixedVF, const ElementCount &ScalableVF)
FixedScalableVFPair(const ElementCount &Max)
static FixedScalableVFPair getNone()
A range of powers-of-2 vectorization factors with fixed start and adjustable end.
Default inserter for VPBuilderBase, inserting R at It in VPBB.
void insertHelper(VPRecipeBase *R, VPBasicBlock *VPBB, VPBasicBlock::iterator It)
Struct to hold various analysis needed for cost computations.
A struct that represents some properties of the register usage of a loop.
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3814
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3919
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class.
InstructionCost Cost
Cost of the loop with that width.
ElementCount MinProfitableTripCount
The minimum trip count required to make vectorization profitable, e.g.
ElementCount Width
Vector width with best cost.
InstructionCost ScalarCost
Cost of the scalar loop.
static VectorizationFactor Disabled()
Width 1 means no vectorization, cost 0 means uncomputed cost.
VectorizationFactor(ElementCount Width, InstructionCost Cost, InstructionCost ScalarCost)