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;
54struct VectorizeOptions;
55
56/// \return An upper bound for vscale based on TTI or the vscale_range
57/// attribute.
58std::optional<unsigned> getMaxVScale(const Function &F);
59
60/// \return The upper bound for the runtime value of \p EC, or std::nullopt
61/// if the upper bound is unknown.
62std::optional<uint64_t>
64
65// Utility functions that are used by different vectorization classes
67
68/// Reports a vectorization failure: print \p DebugMsg for debugging
69/// purposes along with the corresponding optimization remark \p RemarkName.
70/// If \p I is passed, it is an instruction that prevents vectorization.
71/// Otherwise, the loop \p TheLoop is used for the location of the remark.
72void reportVectorizationFailure(const StringRef DebugMsg,
73 const StringRef OREMsg, const StringRef ORETag,
75 const Loop *TheLoop, Instruction *I = nullptr);
76
77/// Same as above, but the debug message and optimization remark are identical
78inline void reportVectorizationFailure(const StringRef DebugMsg,
79 const StringRef ORETag,
81 const Loop *TheLoop,
82 Instruction *I = nullptr) {
83 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
84}
85
86/// Reports an informative message: print \p Msg for debugging purposes as well
87/// as an optimization remark. Uses either \p I as location of the remark, or
88/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
89/// remark.
90void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
92 const Loop *TheLoop, Instruction *I = nullptr,
93 DebugLoc DL = {});
94
95/// Report successful vectorization of the loop. In case an outer loop is
96/// vectorized, prepend "outer" to the vectorization remark.
97void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
98 ElementCount VFWidth, unsigned IC);
99
100} // namespace LoopVectorizationUtils
101
102/// Default inserter for VPBuilderBase, inserting \p R before \p It.
105 R->insertBefore(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::iterator Iterator;
115
116 public:
117 /// Creates a new insertion point which doesn't point to anything.
118 VPInsertPoint() = default;
119
120 /// Creates a new insertion point to insert before \p Iterator.
121 VPInsertPoint(VPBasicBlock::iterator Iterator) : Iterator(Iterator) {}
122
123 /// Creates a new insertion point to insert before \p R.
124 VPInsertPoint(VPRecipeBase *R) : Iterator(R->getIterator()) {}
125
126 /// Creates a new insertion point to insert at the end of \p Block.
127 VPInsertPoint(VPBasicBlock *Block) : Iterator(Block->end()) {}
128
129 /// Returns true if this insert point is set.
130 operator bool() const { return Iterator.isValid(); }
131
132 VPBasicBlock *getBlock() const {
133 return Iterator.isValid() ? Iterator.getNodeParent() : nullptr;
134 }
135 VPBasicBlock::iterator getIterator() const { return Iterator; }
136
137 operator VPRecipeBase *() const {
138 return Iterator == getBlock()->end() ? nullptr : &*Iterator;
139 }
140 };
141
142 VPInsertPoint InsertPt;
143
144protected:
145 /// Insert \p R at InsertPt if InsertPt is set.
146 template <typename T> T *tryInsertInstruction(T *R) {
147 if (InsertPt)
148 InserterTy::insertHelper(R, InsertPt.getIterator());
149 return R;
150 }
151
154 const VPIRMetadata &MD, DebugLoc DL,
155 const Twine &Name = "") {
157 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
158 }
159
160public:
161 VPlan &getPlan() const {
162 assert(InsertPt && "Insert block must be set");
163 return *InsertPt.getBlock()->getPlan();
164 }
165
166 VPBuilderBase() = default;
167 VPBuilderBase(const VPInsertPoint &IP) : InsertPt(IP) {}
168 VPBuilderBase(InserterTy Inserter) : InserterTy(Inserter) {}
169
170 /// Get the recipe at the current insert point or nullptr if the insert point
171 /// is the end of the block.
172 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
173
174 VPBasicBlock *getInsertBlock() const { return InsertPt.getBlock(); }
175
176 /// Create a builder to insert after \p R.
178 return VPBuilderBase(std::next(R->getIterator()));
179 }
180
181 /// Sets the current insert point to a previously-saved location.
182 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
183
184 /// Set the current insert point.
185 void setInsertPoint(const VPInsertPoint &IP) {
186 assert(IP && "Attempting to set a null insert point");
187 InsertPt = IP;
188 }
189
190 /// Insert \p R at the current insertion point. Returns \p R unchanged.
191 template <typename T> [[maybe_unused]] T *insert(T *R) {
192 InserterTy::insertHelper(R, InsertPt.getIterator());
193 return R;
194 }
195
196 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
197 /// its underlying Instruction.
199 Instruction *Inst = nullptr,
200 const VPIRFlags &Flags = {},
201 const VPIRMetadata &MD = {},
203 const Twine &Name = "", Type *ResultTy = nullptr,
204 const VPIRAttributes &Attrs = {}) {
205 VPInstruction *NewVPInst = tryInsertInstruction(new VPInstruction(
206 Opcode, Operands, Flags, MD, DL, Name, ResultTy, Attrs));
207 NewVPInst->setUnderlyingValue(Inst);
208 return NewVPInst;
209 }
211 DebugLoc DL, const Twine &Name = "") {
212 return createInstruction(Opcode, Operands, {}, DL, Name);
213 }
215 const VPIRFlags &Flags,
217 const Twine &Name = "") {
219 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
220 }
221
223 Type *ResultTy, const VPIRFlags &Flags = {},
225 const Twine &Name = "") {
227 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
228 }
229
232 const Twine &Name = "") {
233 // Assume that the maximum possible number of elements in a vector fits
234 // within the index type for the default address space.
235 VPlan &Plan = getPlan();
236 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
238 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
239 }
240
243 const Twine &Name = "") {
244 // Assume that the maximum possible number of elements in a vector fits
245 // within the index type for the default address space.
246 VPlan &Plan = getPlan();
247 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
249 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
250 }
251
253 unsigned Opcode, ArrayRef<VPValue *> Operands,
254 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
255 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
257 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
258 }
259
262 const Twine &Name = "") {
263 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
264 }
265
268 const Twine &Name = "") {
269 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
270 Name);
271 }
272
275 const Twine &Name = "") {
276
278 Instruction::BinaryOps::Or, {LHS, RHS},
279 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
280 }
281
284 const Twine &Name = "",
285 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
286 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
287 Name);
288 }
289
290 VPInstruction *
292 const Twine &Name = "",
293 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
294 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
295 Name);
296 }
297
303
309
310 /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
311 /// default flags for the result type, unless \p Flags is set.
313 VPValue *FalseVal,
315 const Twine &Name = "",
316 std::optional<VPIRFlags> Flags = std::nullopt) {
318 new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
319 Flags.value_or(VPIRFlags::getDefaultFlags(
320 Instruction::Select, TrueVal->getScalarType())),
321 {}, DL, Name));
322 }
323
324 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
325 /// and \p B.
328 const Twine &Name = "") {
330 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
332 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
333 }
334
335 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
336 /// and \p B.
339 const Twine &Name = "") {
341 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
343 new VPInstruction(Instruction::FCmp, {A, B},
344 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
345 }
346
347 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
348 /// result, then select between \p TrueVal and \p FalseVal.
350 VPValue *FalseVal,
352 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
353 "ChainOp must be i1 for AnyOf reduction");
354 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
355 FastMathFlags());
357 {ChainOp}, Flags, DL);
358 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
359 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
360 }
361
364 const Twine &Name = "") {
365 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
366 }
367
369 GEPNoWrapFlags GEPFlags,
371 const Twine &Name = "") {
373 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
374 }
375
383
384 /// Create a phi with \p IncomingValues, using the default flags for the
385 /// result type, unless \p Flags is set.
388 const Twine &Name = "",
389 std::optional<VPIRFlags> Flags = std::nullopt,
390 Type *ResultTy = nullptr) {
391 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
392 return tryInsertInstruction(new VPPhi(
393 IncomingValues,
394 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
395 DL, Name, ResultTy));
396 }
397
400 const Twine &Name = "") {
401 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
402 }
403
405 VPlan &Plan = getPlan();
406 unsigned MinEC = EC.getKnownMinValue();
407 if (EC.isScalable()) {
408 VPValue *VScale = createVScale(Ty);
409 if (MinEC == 1)
410 return VScale;
411 // TODO: Move this optimization into createOverflowingOp directly.
412 if (isPowerOf2_32(MinEC)) {
413 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
414 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
415 {true, false});
416 }
417 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
418 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
419 {true, false});
420 }
421 return Plan.getConstantInt(Ty, MinEC);
422 }
423
424 /// Convert \p Current to \p Start + \p Current * \p Step.
426 FPMathOperator *FPBinOp, VPValue *Start,
427 VPValue *Current, VPValue *Step,
428 const VPIRFlags::WrapFlagsTy &Flags = {}) {
430 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
431 }
432
434 Type *ResultTy, DebugLoc DL,
435 std::optional<VPIRFlags> Flags = std::nullopt,
436 const VPIRMetadata &Metadata = {}) {
438 Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
439 Metadata, DL, "", ResultTy));
440 }
441
442 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
443 /// result type \p ResultTy
446 Type *ResultTy, DebugLoc DL,
447 const Twine &Name = "") {
448 VPlan &Plan = getPlan();
450 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
452 {}, {}, DL, Name, ResultTy));
453 }
454
455 /// Create a scalar llvm.vscale call.
458 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
459 }
460
462 Type *SrcTy = Op->getScalarType();
463 if (ResultTy == SrcTy)
464 return Op;
465 Instruction::CastOps CastOp =
466 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
467 ? Instruction::Trunc
468 : Instruction::ZExt;
469 return createScalarCast(CastOp, Op, ResultTy, DL);
470 }
471
473 Type *SrcTy = Op->getScalarType();
474 if (ResultTy == SrcTy)
475 return Op;
476 Instruction::CastOps CastOp =
477 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
478 ? Instruction::Trunc
479 : Instruction::SExt;
480 return createScalarCast(CastOp, Op, ResultTy, DL);
481 }
482
484 const Twine &Name = "") {
485 return createNaryOp(Instruction::Freeze, Op, DL, Name);
486 }
487
489 Type *ResultTy) {
490 assert(Op->getScalarType() != ResultTy &&
491 "must not create a no-op cast recipe");
493 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
494 }
495
496 /// Create a single-scalar recipe with \p Opcode and \p Operands without
497 /// inserting it.
498 static VPSingleDefRecipe *
500 VPValue *Mask, const VPIRFlags &Flags,
502 Type *ResultTy, Instruction *UV) {
503 if (Instruction::isCast(Opcode)) {
504 assert(!Mask && "Cast cannot be predicated");
505 auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
506 UV->getName(), ResultTy);
507 VPI->setUnderlyingValue(UV);
508 return VPI;
509 }
510 auto *RepR = new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true,
511 Mask, Flags, Metadata, DL);
512 assert(RepR->getScalarType() == ResultTy && "unexpected result type");
513 return RepR;
514 }
515
518 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
519 VPValue *VF, DebugLoc DL) {
521 IV, Step, VF, InductionOpcode,
522 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
523 }
524
528
530 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
531 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
533 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
534 }
535
536 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
537 /// with element type \p SourceElementTy.
539 Type *SourceElementTy,
540 bool Reverse, DebugLoc DL) {
541 VPlan &Plan = getPlan();
543 if (Reverse) {
544 // When folding the tail, we may compute an address that we don't in the
545 // original scalar loop: drop the GEP no-wrap flags in this case.
546 // Otherwise preserve existing flags without no-unsigned-wrap, as we will
547 // emit negative indices.
548 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
550 : Flags.withoutNoUnsignedWrap();
552 new VPVectorEndPointerRecipe(Ptr, &Plan.getVF(), SourceElementTy,
553 /*Stride=*/-1, ReverseFlags, DL));
554 }
555 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
556 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
557 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
558 }
559
561 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
562 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
564 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
565 }
566
567 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
568 /// be null).
570 VPValue *Mask, bool Consecutive,
571 Align Alignment,
572 const VPIRMetadata &Metadata,
573 DebugLoc DL) {
575 Load, Addr, Mask, Consecutive, Alignment, Metadata, DL));
576 }
577
578 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
579 /// \p Mask (may be null).
581 VPValue *StoredVal, VPValue *Mask,
582 bool Consecutive, Align Alignment,
583 const VPIRMetadata &Metadata,
584 DebugLoc DL) {
586 Store, Addr, StoredVal, Mask, Consecutive, Alignment, Metadata, DL));
587 }
588
589 //===--------------------------------------------------------------------===//
590 // RAII helpers.
591 //===--------------------------------------------------------------------===//
592
593 /// RAII object that stores the current insertion point and restores it when
594 /// the object is destroyed.
596 VPBuilderBase &Builder;
597 VPInsertPoint InsertPt;
598
599 public:
600 InsertPointGuard(VPBuilderBase &B) : Builder(B), InsertPt(B.InsertPt) {}
601
604
605 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
606 };
607};
608
609/// TODO: The following VectorizationFactor was pulled out of
610/// LoopVectorizationCostModel class. LV also deals with
611/// VectorizerParams::VectorizationFactor.
612/// We need to streamline them.
613
614/// Information about vectorization costs.
616 /// Vector width with best cost.
618
619 /// Cost of the loop with that width.
621
622 /// Cost of the scalar loop.
624
625 /// The minimum trip count required to make vectorization profitable, e.g. due
626 /// to runtime checks.
628
632
633 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
635 return {ElementCount::getFixed(1), 0, 0};
636 }
637};
638
639/// A class that represents two vectorization factors (initialized with 0 by
640/// default). One for fixed-width vectorization and one for scalable
641/// vectorization. This can be used by the vectorizer to choose from a range of
642/// fixed and/or scalable VFs in order to find the most cost-effective VF to
643/// vectorize with.
647
649 : FixedVF(ElementCount::getFixed(0)),
650 ScalableVF(ElementCount::getScalable(0)) {}
652 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
653 }
657 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
658 "Invalid scalable properties");
659 }
660
662
663 /// \return true if either fixed- or scalable VF is non-zero.
664 explicit operator bool() const { return FixedVF || ScalableVF; }
665};
666
667/// Holds state needed to make cost decisions before computing costs per-VF,
668/// including the maximum VFs.
670 /// \return True if maximizing vector bandwidth is enabled by the target or
671 /// user options, for the given register kind (scalable or fixed-width).
672 bool useMaxBandwidth(bool IsScalable) const;
673
674 /// \return the maximized element count based on the targets vector
675 /// registers and the loop trip-count, but limited to a maximum safe VF.
676 /// This is a helper function of computeFeasibleMaxVF.
677 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
678 unsigned SmallestType,
679 unsigned WidestType,
680 ElementCount MaxSafeVF, unsigned UserIC,
681 bool FoldTailByMasking,
682 bool RequiresScalarEpilogue);
683
684 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
685 /// that results in VF * UserIC <= MaxTripCount.
686 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
687 unsigned UserIC, bool FoldTailByMasking,
688 bool RequiresScalarEpilogue) const;
689
690 /// Checks if scalable vectorization is supported and enabled. Caches the
691 /// result to avoid repeated debug dumps for repeated queries.
692 bool isScalableVectorizationAllowed();
693
694 /// \return the maximum legal scalable VF, based on the safe max number
695 /// of elements.
696 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
697
698 /// Initializes the value of vscale used for tuning the cost model. If
699 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
700 /// return the value returned by the corresponding TTI method.
701 void initializeVScaleForTuning();
702
703 const VectorizeOptions &Opts;
704 const TargetTransformInfo &TTI;
705 const LoopVectorizationLegality *Legal;
706 const Loop *TheLoop;
707 const Function &F;
709 DemandedBits *DB;
711 const LoopVectorizeHints *Hints;
712
713 /// Cached result of isScalableVectorizationAllowed.
714 std::optional<bool> IsScalableVectorizationAllowed;
715
716 /// Used to store the value of vscale used for tuning the cost model. It is
717 /// initialized during object construction.
718 std::optional<unsigned> VScaleForTuning;
719
720 /// The highest VF possible for this loop, without using MaxBandwidth.
721 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
722
723 /// All element types found in the loop.
724 SmallPtrSet<Type *, 16> ElementTypesInLoop;
725
726 /// PHINodes of the reductions that should be expanded in-loop. Set by
727 /// collectInLoopReductions.
728 SmallPtrSet<PHINode *, 4> InLoopReductions;
729
730 /// Maximum safe number of elements to be processed per vector iteration,
731 /// which do not prevent store-load forwarding and are safe with regard to the
732 /// memory dependencies. Required for EVL-based vectorization, where this
733 /// value is used as the upper bound of the safe AVL. Set by
734 /// computeFeasibleMaxVF.
735 std::optional<unsigned> MaxSafeElements;
736
737 /// Map of scalar integer values to the smallest bitwidth they can be legally
738 /// represented as. The vector equivalents of these values should be truncated
739 /// to this type.
741
742public:
743 /// The kind of cost that we are calculating.
745
746 /// Whether this loop should be optimized for size based on function attribute
747 /// or profile information.
748 const bool OptForSize;
749
750 VFSelectionContext(const VectorizeOptions &Opts,
751 const TargetTransformInfo &TTI,
752 const LoopVectorizationLegality *Legal,
753 const Loop *TheLoop, const Function &F,
756 const LoopVectorizeHints *Hints, bool OptForSize)
757 : Opts(Opts), TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE),
758 DB(DB), ORE(ORE), Hints(Hints),
759 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
761 initializeVScaleForTuning();
762 }
763
764 /// \return The vscale value used for tuning the cost model.
765 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
766
767 const VectorizeOptions &getOpts() const { return Opts; }
768
769 const TargetTransformInfo &getTTI() const { return TTI; }
770
771 PredicatedScalarEvolution &getPSE() const { return PSE; }
772
773 /// \return The loop being analyzed.
774 const Loop *getLoop() const { return TheLoop; }
775
776 /// \return The vectorization hints for the loop being analyzed.
777 const LoopVectorizeHints &getHints() const { return *Hints; }
778
779 /// Returns true if epilogue vectorization is considered profitable for a
780 /// main loop with vectorization factor \p VF and interleave count \p IC.
781 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
782
783 /// \return True if register pressure should be considered for the given VF.
785
786 /// \return True if scalable vectors are supported by the target or forced.
787 bool supportsScalableVectors() const;
788
789 /// Collect element types in the loop that need widening.
791 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
792
793 /// \return The size (in bits) of the smallest and widest types in the code
794 /// that need to be vectorized. We ignore values that remain scalar such as
795 /// 64 bit loop indices.
796 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
797
798 /// \return An upper bound for the vectorization factors for both
799 /// fixed and scalable vectorization, where the minimum-known number of
800 /// elements is a power-of-2 larger than zero. If scalable vectorization is
801 /// disabled or unsupported, then the scalable part will be equal to
802 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
803 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
804 ElementCount UserVF, unsigned UserIC,
805 bool FoldTailByMasking,
806 bool RequiresScalarEpilogue);
807
808 /// Return maximum safe number of elements to be processed per vector
809 /// iteration, which do not prevent store-load forwarding and are safe with
810 /// regard to the memory dependencies. Required for EVL-based VPlans to
811 /// correctly calculate AVL (application vector length) as min(remaining AVL,
812 /// MaxSafeElements). Set by computeFeasibleMaxVF.
813 /// TODO: need to consider adjusting cost model to use this value as a
814 /// vectorization factor for EVL-based vectorization.
815 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
816
817 /// Returns true if we should use strict in-order reductions for the given
818 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
819 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
820 /// of FP operations.
821 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
822
823 /// Returns true if the target machine supports a masked load (if \p IsLoad)
824 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
825 /// space \p AddressSpace. The caller must ensure the access is consecutive or
826 /// part of an interleave group.
827 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
828 unsigned AddressSpace) const;
829
830 /// Returns true if the target machine supports a gather (if \p IsLoad)
831 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
832 /// factor \p VF.
833 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
834 ElementCount VF) const;
835
836 /// Split reductions into those that happen in the loop, and those that
837 /// happen outside. In-loop reductions are collected into InLoopReductions.
839
840 /// Returns true if the Phi is part of an inloop reduction.
841 bool isInLoopReduction(PHINode *Phi) const {
842 return InLoopReductions.contains(Phi);
843 }
844
845 /// Returns the set of in-loop reduction PHIs.
847 return InLoopReductions;
848 }
849
850 /// Check whether vectorization would require runtime checks. When optimizing
851 /// for size, returning true here aborts vectorization.
853
854 /// Returns a scalable VF to use for outer-loop vectorization if the target
855 /// supports it and a fixed VF otherwise.
857
858 /// Compute smallest bitwidth each instruction can be represented with.
859 /// The vector equivalents of these instructions should be truncated to this
860 /// type.
862
863 /// \returns The smallest bitwidth each instruction can be represented with.
865 return MinBWs;
866 }
867};
868
869/// Planner drives the vectorization process after having passed
870/// Legality checks.
872 const VectorizeOptions &Opts;
873
874 /// The loop that we evaluate.
875 Loop *OrigLoop;
876
877 /// Loop Info analysis.
878 LoopInfo *LI;
879
880 /// The dominator tree.
881 DominatorTree *DT;
882
883 /// Target Library Info.
884 const TargetLibraryInfo *TLI;
885
886 /// Target Transform Info.
887 const TargetTransformInfo &TTI;
888
889 /// The legality analysis.
891
892 /// The profitability analysis. Cleared after making cost based decisions.
893 /// This instance should never be used in any function that takes an explicit
894 /// PlanCM reference, since that instance overrides this one.
895 std::unique_ptr<LoopVectorizationCostModel> CM;
896
897 /// VF selection state independent of cost-modeling decisions.
898 VFSelectionContext &Config;
899
901
903
904 /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
905 std::function<const BranchProbabilityInfo &()> GetBPI;
906
908
909 /// Profitable vector factors.
911
912 /// A builder used to construct the current plan.
913 VPBuilder Builder;
914
915 /// Computes the cost of \p Plan for vectorization factor \p VF, using
916 /// \p PlanCM as the cost model.
917 ///
918 /// The current implementation requires access to the
919 /// LoopVectorizationLegality to handle inductions and reductions, which is
920 /// why it is kept separate from the VPlan-only cost infrastructure.
921 ///
922 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
923 /// been retired.
925 LoopVectorizationCostModel &PlanCM) const;
926
927 /// Precompute costs for certain instructions using the legacy cost model. The
928 /// function is used to bring up the VPlan-based cost model to initially avoid
929 /// taking different decisions due to inaccuracies in the legacy cost model.
930 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
931 VPCostContext &CostCtx) const;
932
933public:
935 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
937 std::unique_ptr<LoopVectorizationCostModel> CM,
940 std::function<const BranchProbabilityInfo &()> GetBPI);
941
943
944 /// Return the cost model. Must not be called after clearCostModel().
946 assert(CM && "Cost model has already been cleared");
947 return *CM;
948 }
949
950 /// Destroy the cost model.
951 void clearCostModel();
952
953 /// Return true if there is at least one VPlan for a vector VF
954 bool hasVectorPlan() const {
955 return any_of(
956 VPlans, [&](const VPlanPtr &Plan) { return !Plan->hasScalarVFOnly(); });
957 }
958
959 /// Returns true if there is at least one VPlan.
960 bool hasAPlan() const { return !VPlans.empty(); }
961
962 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
963 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
964 /// interleaving should be avoided up-front, no plans are generated.
965 void plan(ElementCount UserVF, unsigned UserIC);
966
967 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
968 /// for each VF.
969 VPlan &getPlanFor(ElementCount VF) const;
970
971 /// Compute and return the most profitable vectorization factor and the
972 /// corresponding best VPlan. Also collect all profitable VFs in
973 /// ProfitableVFs.
974 std::pair<VectorizationFactor, VPlan *> computeBestVF();
975
976 /// \return The desired interleave count.
977 /// If interleave count has been specified by metadata it will be returned.
978 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
979 /// are the selected vectorization factor and the cost of the selected VF.
980 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
981 InstructionCost LoopCost);
982
983 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
984 /// according to the best selected \p VF and \p UF.
985 ///
986 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
987 /// fixed.
988 ///
989 /// When vectorizing the main loop, \p TrackedBlocks are updated to the
990 /// VPIRBasicBlocks wrapping the blocks generated for them.
991 ///
992 /// Returns a mapping of SCEVs to their expanded IR values.
993 /// Note that this is a temporary workaround needed due to the current
994 /// epilogue handling.
996 None, ///< Not part of epilogue vectorization.
997 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
998 Epilogue ///< Vectorizing the epilogue loop.
999 };
1001 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
1003 EpilogueVectorizationKind EpilogueVecKind =
1005 MutableArrayRef<VPBasicBlock *> TrackedBlocks = {});
1006
1007#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1008 void printPlans(raw_ostream &O);
1009#endif
1010
1011 /// Look through the existing plans and return true if we have one with
1012 /// vectorization factor \p VF.
1014 return any_of(VPlans,
1015 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
1016 }
1017
1018 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
1019 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
1020 /// returned value holds for the entire \p Range.
1021 static bool
1022 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
1023 VFRange &Range);
1024
1025 /// \return A VPlan for the most profitable epilogue vectorization, with its
1026 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
1027 /// Returns nullptr if epilogue vectorization is not supported or not
1028 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
1029 /// epilogue lowering policy permits creating a scalar epilogue at all.
1030 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
1031 ElementCount MainLoopVF,
1032 unsigned IC,
1033 bool ScalarEpilogueAllowed);
1034
1035 /// Emit remarks for recipes with invalid costs in the available VPlans.
1037
1038 /// Create a check to \p Plan to see if the vector loop should be executed
1039 /// based on its trip count.
1040 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1041 ElementCount MinProfitableTripCount) const;
1042
1043 /// Attach the runtime checks of \p RTChecks to \p Plan. \p VF and \p UF are
1044 /// used to compute the thresholds of difference checks.
1045 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1046 ElementCount VF, unsigned UF,
1047 bool HasBranchWeights) const;
1048
1049 /// Update loop metadata and profile info for both the scalar remainder loop
1050 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1051 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1052 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1053 /// the average trip count and invocation weight of the original loop (\p
1054 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1055 /// cannot be retrieved after the plan has been executed, as the original loop
1056 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1057 /// target wants the vector loop left eligible for runtime unrolling.
1059 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1060 bool VectorizingEpilogue, MDNode *OrigLoopID,
1061 std::optional<unsigned> OrigAverageTripCount,
1062 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1063 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1064
1065private:
1066 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1067 /// scalar transformations applied. Returns null if an initial VPlan cannot
1068 /// be built. \p PlanCM is the cost model to use for decisions made while
1069 /// building the plan.
1070 VPlanPtr tryToBuildVPlan1(LoopVectorizationCostModel &PlanCM);
1071
1072 /// Build a VPlan using VPRecipes according to the information gathered by
1073 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1074 /// conversion only. For inner loops, \p Range's largest included VF is
1075 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1076 /// can be built for the input range, set the largest included VF to the
1077 /// maximum VF for which no plan could be built. Each VPlan is built starting
1078 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1079 /// original scalar loop. \p PlanCM is the cost model used for legality
1080 /// and widening decisions while building the plan.
1081 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range,
1083
1084 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1085 /// based on \p VPlan1 and according to the information gathered by Legal
1086 /// when it checked if it is legal to vectorize the loop. \p PlanCM is
1087 /// the cost model to build these VPlans.
1088 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF,
1090
1091 /// Add ComputeReductionResult recipes to the middle block to compute the
1092 /// final reduction results. Add Select recipes to the latch block when
1093 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1094 /// iteration values according to the header mask. \p PlanCM is the cost
1095 /// model used to build \p Plan.
1096 void addReductionResultComputation(VPlanPtr &Plan, ElementCount MinVF,
1098
1099 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1100 /// that of B.
1101 bool isMoreProfitable(const VectorizationFactor &A,
1102 const VectorizationFactor &B, bool HasTail,
1103 bool IsEpilogue = false) const;
1104
1105 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1106 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1107 bool isMoreProfitable(const VectorizationFactor &A,
1108 const VectorizationFactor &B,
1109 const unsigned MaxTripCount, bool HasTail,
1110 bool IsEpilogue = false) const;
1111
1112 /// Determines if we have the infrastructure to vectorize the loop and its
1113 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1114 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1115};
1116
1117/// A helper function that returns true if the given type is irregular. The
1118/// type is irregular if its allocated size doesn't equal the store size of an
1119/// element of the corresponding vector type.
1120inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1121 // Determine if an array of N elements of type Ty is "bitcast compatible"
1122 // with a <N x Ty> vector.
1123 // This is only true if there is no padding between the array elements.
1124 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1125}
1126
1127} // namespace llvm
1128
1129#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))
SmallVector< MachineOperand, 4 > 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:306
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
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...
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:1660
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:1711
bool hasAPlan() const
Returns true if there is at least one VPlan.
LoopVectorizationCostModel & getCostModel()
Return the cost model. Must not be called after clearCostModel().
LoopVectorizationPlanner(Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, const TargetTransformInfo &TTI, LoopVectorizationLegality *Legal, std::unique_ptr< LoopVectorizationCostModel > CM, VFSelectionContext &Config, PredicatedScalarEvolution &PSE, OptimizationRemarkEmitter *ORE, std::function< const BranchProbabilityInfo &()> GetBPI)
unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF, InstructionCost LoopCost)
void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, ElementCount VF, unsigned UF, bool HasBranchWeights) const
Attach the runtime checks of RTChecks to Plan.
bool hasVectorPlan() const
Return true if there is at least one VPlan for a vector VF.
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:1646
DenseMap< const SCEV *, Value * > executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan, InnerLoopVectorizer &LB, DominatorTree *DT, EpilogueVectorizationKind EpilogueVecKind=EpilogueVectorizationKind::None, MutableArrayRef< VPBasicBlock * > TrackedBlocks={})
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1815
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
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
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 VectorizeOptions & getOpts() 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.
VFSelectionContext(const VectorizeOptions &Opts, const TargetTransformInfo &TTI, const LoopVectorizationLegality *Legal, const Loop *TheLoop, const Function &F, PredicatedScalarEvolution &PSE, DemandedBits *DB, OptimizationRemarkEmitter *ORE, const LoopVectorizeHints *Hints, bool OptForSize)
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
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:4491
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4522
iterator end()
Definition VPlan.h:4532
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 * 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 R at InsertPt if InsertPt 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.
VPWidenLoadRecipe * createWidenLoad(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Load, loading from Addr with Mask (may be null).
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPBasicBlock * getInsertBlock() const
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={})
VPInstruction * createScalarIntrinsic(Intrinsic::ID IntrinsicID, ArrayRef< VPValue * > Operands, Type *ResultTy, DebugLoc DL, const Twine &Name="")
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="")
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPBuilderBase()=default
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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, const VPIRAttributes &Attrs={})
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
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})
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)
VPWidenStoreRecipe * createWidenStore(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Store, storing StoredVal to Addr with Mask (may be null).
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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:4262
Recipe to expand a SCEV expression.
Definition VPlan.h:4086
Class to record and manage LLVM IR flags.
Definition VPlan.h:685
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:1154
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1324
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1451
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1383
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:406
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3454
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4323
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:608
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:142
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2331
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2413
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1913
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2090
A recipe for widened phis.
Definition VPlan.h:2791
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4909
const DataLayout & getDataLayout() const
Definition VPlan.h:5110
LLVMContext & getContext() const
Definition VPlan.h:5106
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:5022
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5097
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:5216
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
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:69
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:80
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 before It.
void insertHelper(VPRecipeBase *R, 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:3869
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3977
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)