LLVM 24.0.0git
LoopVectorizationPlanner.h
Go to the documentation of this file.
1//===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file provides a LoopVectorizationPlanner class.
11/// InnerLoopVectorizer vectorizes loops which contain only one basic
12/// LoopVectorizationPlanner - drives the vectorization process after having
13/// passed Legality checks.
14/// The planner builds and optimizes the Vectorization Plans which record the
15/// decisions how to vectorize the given loop. In particular, represent the
16/// control-flow of the vectorized version, the replication of instructions that
17/// are to be scalarized, and interleave access groups.
18///
19/// Also provides a VPlan-based builder utility analogous to IRBuilder.
20/// It provides an instruction-level API for generating VPInstructions while
21/// abstracting away the Recipe manipulation details.
22//===----------------------------------------------------------------------===//
23
24#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
25#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
26
27#include "VPlan.h"
28#include "llvm/ADT/SmallSet.h"
31#include <optional>
32
33namespace {
34class GeneratedRTChecks;
35}
36
37namespace llvm {
38
40class LoopInfo;
41class DominatorTree;
47class LoopVersioning;
50class VPRecipeBuilder;
51struct VPRegisterUsage;
52struct VFRange;
53
54/// \return An upper bound for vscale based on TTI or the vscale_range
55/// attribute.
56std::optional<unsigned> getMaxVScale(const Function &F);
57
58/// \return The upper bound for the runtime value of \p EC, or std::nullopt
59/// if the upper bound is unknown.
60std::optional<uint64_t>
62
63// Utility functions that are used by different vectorization classes
65
66/// Reports a vectorization failure: print \p DebugMsg for debugging
67/// purposes along with the corresponding optimization remark \p RemarkName.
68/// If \p I is passed, it is an instruction that prevents vectorization.
69/// Otherwise, the loop \p TheLoop is used for the location of the remark.
70void reportVectorizationFailure(const StringRef DebugMsg,
71 const StringRef OREMsg, const StringRef ORETag,
73 const Loop *TheLoop, Instruction *I = nullptr);
74
75/// Same as above, but the debug message and optimization remark are identical
76inline void reportVectorizationFailure(const StringRef DebugMsg,
77 const StringRef ORETag,
79 const Loop *TheLoop,
80 Instruction *I = nullptr) {
81 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
82}
83
84/// Reports an informative message: print \p Msg for debugging purposes as well
85/// as an optimization remark. Uses either \p I as location of the remark, or
86/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
87/// remark.
88void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
90 const Loop *TheLoop, Instruction *I = nullptr,
91 DebugLoc DL = {});
92
93/// Report successful vectorization of the loop. In case an outer loop is
94/// vectorized, prepend "outer" to the vectorization remark.
95void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
96 ElementCount VFWidth, unsigned IC);
97
98} // namespace LoopVectorizationUtils
99
100/// VPlan-based builder utility analogous to IRBuilder.
102private:
103 class VPInsertPoint {
104 VPBasicBlock *Block = nullptr;
106
107 public:
108 /// Creates a new insertion point which doesn't point to anything.
109 VPInsertPoint() = default;
110
111 /// Creates a new insertion point to insert at \p Point in \p Block.
112 VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Point)
113 : Block(Block), Point(Point) {}
114
115 /// Creates a new insertion point to insert before \p R.
116 VPInsertPoint(VPRecipeBase *R)
117 : Block(R->getParent()), Point(R->getIterator()) {}
118
119 /// Creates a new insertion point to insert at the end of \p Block.
120 VPInsertPoint(VPBasicBlock *Block) : Block(Block), Point(Block->end()) {}
121
122 /// Returns true if this insert point is set.
123 operator bool() const { return Block; }
124
125 VPBasicBlock *getBlock() const { return Block; }
126
127 operator VPRecipeBase *() const {
128 return Point == Block->end() ? nullptr : &*Point;
129 }
130
131 template <typename T> void insert(T &R) { return Block->insert(R, Point); }
132 };
133
134 VPInsertPoint InsertPt;
135
136 /// Insert \p VPI in BB at InsertPt if BB is set.
137 template <typename T> T *tryInsertInstruction(T *R) {
138 if (InsertPt)
139 InsertPt.insert(R);
140 return R;
141 }
142
143 VPInstruction *createInstruction(unsigned Opcode,
145 const VPIRMetadata &MD, DebugLoc DL,
146 const Twine &Name = "") {
147 return tryInsertInstruction(
148 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
149 }
150
151public:
152 VPlan &getPlan() const {
153 assert(InsertPt && "Insert block must be set");
154 return *InsertPt.getBlock()->getPlan();
155 }
156
157 VPBuilder() = default;
158 VPBuilder(const VPInsertPoint &IP) : InsertPt(IP) {}
160 : InsertPt(TheBB, IP) {}
161
162 /// Get the recipe at the current insert point or nullptr if the insert point
163 /// is the end of the block.
164 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
165
166 /// Create a VPBuilder to insert after \p R.
168 return {R->getParent(), std::next(R->getIterator())};
169 }
170
171 /// Sets the current insert point to a previously-saved location.
172 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
173
174 /// Set the current insert point.
175 void setInsertPoint(const VPInsertPoint &IP) {
176 assert(IP && "Attempting to set a null insert point");
177 InsertPt = IP;
178 }
180 assert(TheBB && "Attempting to set a null insert point");
181 InsertPt = VPInsertPoint(TheBB, IP);
182 }
183
184 /// Insert \p R at the current insertion point. Returns \p R unchanged.
185 template <typename T> [[maybe_unused]] T *insert(T *R) {
186 InsertPt.insert(R);
187 return R;
188 }
189
190 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
191 /// its underlying Instruction.
193 Instruction *Inst = nullptr,
194 const VPIRFlags &Flags = {},
195 const VPIRMetadata &MD = {},
197 const Twine &Name = "",
198 Type *ResultTy = nullptr) {
199 VPInstruction *NewVPInst = tryInsertInstruction(
200 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
201 NewVPInst->setUnderlyingValue(Inst);
202 return NewVPInst;
203 }
205 DebugLoc DL, const Twine &Name = "") {
206 return createInstruction(Opcode, Operands, {}, DL, Name);
207 }
209 const VPIRFlags &Flags,
211 const Twine &Name = "") {
212 return tryInsertInstruction(
213 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
214 }
215
217 Type *ResultTy, const VPIRFlags &Flags = {},
219 const Twine &Name = "") {
220 return tryInsertInstruction(
221 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
222 }
223
226 const Twine &Name = "") {
227 // Assume that the maximum possible number of elements in a vector fits
228 // within the index type for the default address space.
229 VPlan &Plan = getPlan();
230 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
231 return tryInsertInstruction(new VPInstruction(
232 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
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);
242 return tryInsertInstruction(new VPInstruction(
243 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
244 }
245
247 unsigned Opcode, ArrayRef<VPValue *> Operands,
248 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
249 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
250 return tryInsertInstruction(
251 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
252 }
253
256 const Twine &Name = "") {
257 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
258 }
259
262 const Twine &Name = "") {
263 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
264 Name);
265 }
266
269 const Twine &Name = "") {
270
271 return tryInsertInstruction(new VPInstruction(
272 Instruction::BinaryOps::Or, {LHS, RHS},
273 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
274 }
275
278 const Twine &Name = "",
279 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
280 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
281 Name);
282 }
283
284 VPInstruction *
286 const Twine &Name = "",
287 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
288 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
289 Name);
290 }
291
297
303
304 /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
305 /// default flags for the result type, unless \p Flags is set.
307 VPValue *FalseVal,
309 const Twine &Name = "",
310 std::optional<VPIRFlags> Flags = std::nullopt) {
311 return tryInsertInstruction(
312 new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
313 Flags.value_or(VPIRFlags::getDefaultFlags(
314 Instruction::Select, TrueVal->getScalarType())),
315 {}, DL, Name));
316 }
317
318 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
319 /// and \p B.
322 const Twine &Name = "") {
324 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
325 return tryInsertInstruction(
326 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
327 }
328
329 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
330 /// and \p B.
333 const Twine &Name = "") {
335 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
336 return tryInsertInstruction(
337 new VPInstruction(Instruction::FCmp, {A, B},
338 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
339 }
340
341 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
342 /// result, then select between \p TrueVal and \p FalseVal.
344 VPValue *FalseVal,
346
349 const Twine &Name = "") {
350 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
351 }
352
354 GEPNoWrapFlags GEPFlags,
356 const Twine &Name = "") {
357 return tryInsertInstruction(new VPInstruction(
358 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
359 }
360
363 const Twine &Name = "") {
364 return tryInsertInstruction(
366 GEPNoWrapFlags::none(), {}, DL, Name));
367 }
368
369 /// Create a phi with \p IncomingValues, using the default flags for the
370 /// result type, unless \p Flags is set.
373 const Twine &Name = "",
374 std::optional<VPIRFlags> Flags = std::nullopt,
375 Type *ResultTy = nullptr) {
376 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
377 return tryInsertInstruction(new VPPhi(
378 IncomingValues,
379 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
380 DL, Name, ResultTy));
381 }
382
385 const Twine &Name = "") {
386 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
387 }
388
390 VPlan &Plan = getPlan();
391 unsigned MinEC = EC.getKnownMinValue();
392 if (EC.isScalable()) {
393 VPValue *VScale = createVScale(Ty);
394 if (MinEC == 1)
395 return VScale;
396 // TODO: Move this optimization into createOverflowingOp directly.
397 if (isPowerOf2_32(MinEC)) {
398 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
399 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
400 {true, false});
401 }
402 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
403 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
404 {true, false});
405 }
406 return Plan.getConstantInt(Ty, MinEC);
407 }
408
409 /// Convert \p Current to \p Start + \p Current * \p Step.
411 FPMathOperator *FPBinOp, VPValue *Start,
412 VPValue *Current, VPValue *Step,
413 const VPIRFlags::WrapFlagsTy &Flags = {}) {
414 return tryInsertInstruction(
415 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
416 }
417
419 Type *ResultTy, DebugLoc DL,
420 std::optional<VPIRFlags> Flags = std::nullopt,
421 const VPIRMetadata &Metadata = {}) {
422 return tryInsertInstruction(new VPInstruction(
423 Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
424 Metadata, DL, "", ResultTy));
425 }
426
427 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
428 /// result type \p ResultTy
431 Type *ResultTy, DebugLoc DL) {
432 VPlan &Plan = getPlan();
434 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
435 return tryInsertInstruction(new VPInstruction(VPInstruction::Intrinsic, Ops,
436 {}, {}, DL, "", ResultTy));
437 }
438
439 /// Create a scalar llvm.vscale call.
442 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
443 }
444
446 Type *SrcTy = Op->getScalarType();
447 if (ResultTy == SrcTy)
448 return Op;
449 Instruction::CastOps CastOp =
450 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
451 ? Instruction::Trunc
452 : Instruction::ZExt;
453 return createScalarCast(CastOp, Op, ResultTy, DL);
454 }
455
457 Type *SrcTy = Op->getScalarType();
458 if (ResultTy == SrcTy)
459 return Op;
460 Instruction::CastOps CastOp =
461 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
462 ? Instruction::Trunc
463 : Instruction::SExt;
464 return createScalarCast(CastOp, Op, ResultTy, DL);
465 }
466
468 return tryInsertInstruction(
469 new VPInstruction(Instruction::Freeze, Op, {}, {}, DL));
470 }
471
473 Type *ResultTy) {
474 return tryInsertInstruction(new VPWidenCastRecipe(
475 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
476 }
477
478 /// Create a single-scalar recipe with \p Opcode and \p Operands without
479 /// inserting it.
482 VPValue *Mask,
483 const VPIRFlags &Flags,
484 const VPIRMetadata &Metadata,
485 DebugLoc DL, Instruction *UV) {
486 if (Instruction::isCast(Opcode)) {
487 assert(!Mask && "Cast cannot be predicated");
488 auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
489 UV->getName(), UV->getType());
490 VPI->setUnderlyingValue(UV);
491 return VPI;
492 }
493 return new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true, Mask,
494 Flags, Metadata, DL);
495 }
496
499 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
500 VPValue *VF, DebugLoc DL) {
501 return tryInsertInstruction(new VPScalarIVStepsRecipe(
502 IV, Step, VF, InductionOpcode,
503 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
504 }
505
507 return tryInsertInstruction(new VPExpandSCEVRecipe(Expr));
508 }
509
511 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
512 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
513 return tryInsertInstruction(
514 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
515 }
516
517 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
518 /// with element type \p SourceElementTy.
520 Type *SourceElementTy,
521 bool Reverse, DebugLoc DL);
522
524 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
525 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
526 return tryInsertInstruction(new VPWidenMemIntrinsicRecipe(
527 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
528 }
529
530 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
531 /// be null).
533 VPValue *Mask, bool Consecutive,
534 const VPIRMetadata &Metadata,
535 DebugLoc DL) {
536 return tryInsertInstruction(
537 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
538 }
539
540 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
541 /// \p Mask (may be null).
543 VPValue *StoredVal, VPValue *Mask,
544 bool Consecutive,
545 const VPIRMetadata &Metadata,
546 DebugLoc DL) {
547 return tryInsertInstruction(new VPWidenStoreRecipe(
548 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
549 }
550
551 //===--------------------------------------------------------------------===//
552 // RAII helpers.
553 //===--------------------------------------------------------------------===//
554
555 /// RAII object that stores the current insertion point and restores it when
556 /// the object is destroyed.
558 VPBuilder &Builder;
559 VPInsertPoint InsertPt;
560
561 public:
562 InsertPointGuard(VPBuilder &B) : Builder(B), InsertPt(B.InsertPt) {}
563
566
567 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
568 };
569};
570
571/// TODO: The following VectorizationFactor was pulled out of
572/// LoopVectorizationCostModel class. LV also deals with
573/// VectorizerParams::VectorizationFactor.
574/// We need to streamline them.
575
576/// Information about vectorization costs.
578 /// Vector width with best cost.
580
581 /// Cost of the loop with that width.
583
584 /// Cost of the scalar loop.
586
587 /// The minimum trip count required to make vectorization profitable, e.g. due
588 /// to runtime checks.
590
594
595 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
597 return {ElementCount::getFixed(1), 0, 0};
598 }
599
600 bool operator==(const VectorizationFactor &rhs) const {
601 return Width == rhs.Width && Cost == rhs.Cost;
602 }
603
604 bool operator!=(const VectorizationFactor &rhs) const {
605 return !(*this == rhs);
606 }
607};
608
609/// A class that represents two vectorization factors (initialized with 0 by
610/// default). One for fixed-width vectorization and one for scalable
611/// vectorization. This can be used by the vectorizer to choose from a range of
612/// fixed and/or scalable VFs in order to find the most cost-effective VF to
613/// vectorize with.
617
619 : FixedVF(ElementCount::getFixed(0)),
620 ScalableVF(ElementCount::getScalable(0)) {}
622 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
623 }
627 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
628 "Invalid scalable properties");
629 }
630
632
633 /// \return true if either fixed- or scalable VF is non-zero.
634 explicit operator bool() const { return FixedVF || ScalableVF; }
635
636 /// \return true if either fixed- or scalable VF is a valid vector VF.
637 bool hasVector() const { return FixedVF.isVector() || ScalableVF.isVector(); }
638};
639
640/// Holds state needed to make cost decisions before computing costs per-VF,
641/// including the maximum VFs.
643 /// \return True if maximizing vector bandwidth is enabled by the target or
644 /// user options, for the given register kind (scalable or fixed-width).
645 bool useMaxBandwidth(bool IsScalable) const;
646
647 /// \return the maximized element count based on the targets vector
648 /// registers and the loop trip-count, but limited to a maximum safe VF.
649 /// This is a helper function of computeFeasibleMaxVF.
650 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
651 unsigned SmallestType,
652 unsigned WidestType,
653 ElementCount MaxSafeVF, unsigned UserIC,
654 bool FoldTailByMasking,
655 bool RequiresScalarEpilogue);
656
657 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
658 /// that results in VF * UserIC <= MaxTripCount.
659 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
660 unsigned UserIC, bool FoldTailByMasking,
661 bool RequiresScalarEpilogue) const;
662
663 /// Checks if scalable vectorization is supported and enabled. Caches the
664 /// result to avoid repeated debug dumps for repeated queries.
665 bool isScalableVectorizationAllowed();
666
667 /// \return the maximum legal scalable VF, based on the safe max number
668 /// of elements.
669 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
670
671 /// Initializes the value of vscale used for tuning the cost model. If
672 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
673 /// return the value returned by the corresponding TTI method.
674 void initializeVScaleForTuning();
675
676 const TargetTransformInfo &TTI;
677 const LoopVectorizationLegality *Legal;
678 const Loop *TheLoop;
679 const Function &F;
681 DemandedBits *DB;
683 const LoopVectorizeHints *Hints;
684
685 /// Cached result of isScalableVectorizationAllowed.
686 std::optional<bool> IsScalableVectorizationAllowed;
687
688 /// Used to store the value of vscale used for tuning the cost model. It is
689 /// initialized during object construction.
690 std::optional<unsigned> VScaleForTuning;
691
692 /// The highest VF possible for this loop, without using MaxBandwidth.
693 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
694
695 /// All element types found in the loop.
696 SmallPtrSet<Type *, 16> ElementTypesInLoop;
697
698 /// PHINodes of the reductions that should be expanded in-loop. Set by
699 /// collectInLoopReductions.
700 SmallPtrSet<PHINode *, 4> InLoopReductions;
701
702 /// A Map of inloop reduction operations and their immediate chain operand.
703 /// FIXME: This can be removed once reductions can be costed correctly in
704 /// VPlan. This was added to allow quick lookup of the inloop operations.
705 /// Set by collectInLoopReductions.
706 DenseMap<Instruction *, Instruction *> InLoopReductionImmediateChains;
707
708 /// Maximum safe number of elements to be processed per vector iteration,
709 /// which do not prevent store-load forwarding and are safe with regard to the
710 /// memory dependencies. Required for EVL-based vectorization, where this
711 /// value is used as the upper bound of the safe AVL. Set by
712 /// computeFeasibleMaxVF.
713 std::optional<unsigned> MaxSafeElements;
714
715 /// Map of scalar integer values to the smallest bitwidth they can be legally
716 /// represented as. The vector equivalents of these values should be truncated
717 /// to this type.
719
720public:
721 /// The kind of cost that we are calculating.
723
724 /// Whether this loop should be optimized for size based on function attribute
725 /// or profile information.
726 const bool OptForSize;
727
729 const LoopVectorizationLegality *Legal,
730 const Loop *TheLoop, const Function &F,
733 const LoopVectorizeHints *Hints, bool OptForSize)
734 : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
735 ORE(ORE), Hints(Hints),
736 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
738 initializeVScaleForTuning();
739 }
740
741 /// \return The vscale value used for tuning the cost model.
742 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
743
744 const TargetTransformInfo &getTTI() const { return TTI; }
745
746 PredicatedScalarEvolution &getPSE() const { return PSE; }
747
748 /// \return The loop being analyzed.
749 const Loop *getLoop() const { return TheLoop; }
750
751 /// \return The vectorization hints for the loop being analyzed.
752 const LoopVectorizeHints &getHints() const { return *Hints; }
753
754 /// Returns true if epilogue vectorization is considered profitable for a
755 /// main loop with vectorization factor \p VF and interleave count \p IC.
756 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
757
758 /// \return True if register pressure should be considered for the given VF.
760
761 /// \return True if scalable vectors are supported by the target or forced.
762 bool supportsScalableVectors() const;
763
764 /// Collect element types in the loop that need widening.
766 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
767
768 /// \return The size (in bits) of the smallest and widest types in the code
769 /// that need to be vectorized. We ignore values that remain scalar such as
770 /// 64 bit loop indices.
771 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
772
773 /// \return An upper bound for the vectorization factors for both
774 /// fixed and scalable vectorization, where the minimum-known number of
775 /// elements is a power-of-2 larger than zero. If scalable vectorization is
776 /// disabled or unsupported, then the scalable part will be equal to
777 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
778 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
779 ElementCount UserVF, unsigned UserIC,
780 bool FoldTailByMasking,
781 bool RequiresScalarEpilogue);
782
783 /// Return maximum safe number of elements to be processed per vector
784 /// iteration, which do not prevent store-load forwarding and are safe with
785 /// regard to the memory dependencies. Required for EVL-based VPlans to
786 /// correctly calculate AVL (application vector length) as min(remaining AVL,
787 /// MaxSafeElements). Set by computeFeasibleMaxVF.
788 /// TODO: need to consider adjusting cost model to use this value as a
789 /// vectorization factor for EVL-based vectorization.
790 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
791
792 /// Returns true if we should use strict in-order reductions for the given
793 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
794 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
795 /// of FP operations.
796 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
797
798 /// Returns true if the target machine supports a masked load (if \p IsLoad)
799 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
800 /// space \p AddressSpace. The caller must ensure the access is consecutive or
801 /// part of an interleave group.
802 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
803 unsigned AddressSpace) const;
804
805 /// Returns true if the target machine supports a gather (if \p IsLoad)
806 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
807 /// factor \p VF.
808 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
809 ElementCount VF) const;
810
811 /// Split reductions into those that happen in the loop, and those that
812 /// happen outside. In-loop reductions are collected into InLoopReductions.
813 /// InLoopReductionImmediateChains is filled with each in-loop reduction
814 /// operation and its immediate chain operand for use during cost modelling.
816
817 /// Returns true if the Phi is part of an inloop reduction.
818 bool isInLoopReduction(PHINode *Phi) const {
819 return InLoopReductions.contains(Phi);
820 }
821
822 /// Returns the set of in-loop reduction PHIs.
824 return InLoopReductions;
825 }
826
827 /// Returns the immediate chain operand of in-loop reduction operation \p I,
828 /// or nullptr if \p I is not an in-loop reduction operation.
830 return InLoopReductionImmediateChains.lookup(I);
831 }
832
833 /// Check whether vectorization would require runtime checks. When optimizing
834 /// for size, returning true here aborts vectorization.
836
837 /// Returns a scalable VF to use for outer-loop vectorization if the target
838 /// supports it and a fixed VF otherwise.
840
841 /// Compute smallest bitwidth each instruction can be represented with.
842 /// The vector equivalents of these instructions should be truncated to this
843 /// type.
845
846 /// \returns The smallest bitwidth each instruction can be represented with.
848 return MinBWs;
849 }
850};
851
852/// Planner drives the vectorization process after having passed
853/// Legality checks.
855 /// The loop that we evaluate.
856 Loop *OrigLoop;
857
858 /// Loop Info analysis.
859 LoopInfo *LI;
860
861 /// The dominator tree.
862 DominatorTree *DT;
863
864 /// Target Library Info.
865 const TargetLibraryInfo *TLI;
866
867 /// Target Transform Info.
868 const TargetTransformInfo &TTI;
869
870 /// The legality analysis.
872
873 /// The profitability analysis. Cleared after making cost based decisions.
874 std::unique_ptr<LoopVectorizationCostModel> CM;
875
876 /// VF selection state independent of cost-modeling decisions.
877 VFSelectionContext &Config;
878
879 /// The interleaved access analysis.
881
883
885
886 /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
887 std::function<const BranchProbabilityInfo &()> GetBPI;
888
890
891 /// Profitable vector factors.
893
894 /// A builder used to construct the current plan.
895 VPBuilder Builder;
896
897 /// Computes the cost of \p Plan for vectorization factor \p VF.
898 ///
899 /// The current implementation requires access to the
900 /// LoopVectorizationLegality to handle inductions and reductions, which is
901 /// why it is kept separate from the VPlan-only cost infrastructure.
902 ///
903 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
904 /// been retired.
905 InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;
906
907 /// Precompute costs for certain instructions using the legacy cost model. The
908 /// function is used to bring up the VPlan-based cost model to initially avoid
909 /// taking different decisions due to inaccuracies in the legacy cost model.
910 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
911 VPCostContext &CostCtx) const;
912
913public:
915 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
917 std::unique_ptr<LoopVectorizationCostModel> CM,
920 std::function<const BranchProbabilityInfo &()> GetBPI);
921
923
924 /// Return the cost model. Must not be called after clearCostModel().
926 assert(CM && "Cost model has already been cleared");
927 return *CM;
928 }
929
930 /// Destroy the cost model.
931 void clearCostModel();
932
933 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
934 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
935 /// interleaving should be avoided up-front, no plans are generated.
936 void plan(ElementCount UserVF, unsigned UserIC);
937
938 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
939 /// for each VF.
940 VPlan &getPlanFor(ElementCount VF) const;
941
942 /// Compute and return the most profitable vectorization factor and the
943 /// corresponding best VPlan. Also collect all profitable VFs in
944 /// ProfitableVFs.
945 std::pair<VectorizationFactor, VPlan *> computeBestVF();
946
947 /// \return The desired interleave count.
948 /// If interleave count has been specified by metadata it will be returned.
949 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
950 /// are the selected vectorization factor and the cost of the selected VF.
951 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
952 InstructionCost LoopCost);
953
954 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
955 /// according to the best selected \p VF and \p UF.
956 ///
957 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
958 /// fixed.
959 ///
960 /// Returns a mapping of SCEVs to their expanded IR values.
961 /// Note that this is a temporary workaround needed due to the current
962 /// epilogue handling.
964 None, ///< Not part of epilogue vectorization.
965 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
966 Epilogue ///< Vectorizing the epilogue loop.
967 };
969 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
971 EpilogueVectorizationKind EpilogueVecKind =
973
974#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
975 void printPlans(raw_ostream &O);
976#endif
977
978 /// Look through the existing plans and return true if we have one with
979 /// vectorization factor \p VF.
981 return any_of(VPlans,
982 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
983 }
984
985 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
986 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
987 /// returned value holds for the entire \p Range.
988 static bool
989 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
990 VFRange &Range);
991
992 /// \return A VPlan for the most profitable epilogue vectorization, with its
993 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
994 /// Returns nullptr if epilogue vectorization is not supported or not
995 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
996 /// epilogue lowering policy permits creating a scalar epilogue at all.
997 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
998 ElementCount MainLoopVF,
999 unsigned IC,
1000 bool ScalarEpilogueAllowed);
1001
1002 /// Emit remarks for recipes with invalid costs in the available VPlans.
1004
1005 /// Create a check to \p Plan to see if the vector loop should be executed
1006 /// based on its trip count.
1007 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1008 ElementCount MinProfitableTripCount) const;
1009
1010 /// Attach the runtime checks of \p RTChecks to \p Plan.
1011 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1012 bool HasBranchWeights) const;
1013
1014 /// Update loop metadata and profile info for both the scalar remainder loop
1015 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1016 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1017 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1018 /// the average trip count and invocation weight of the original loop (\p
1019 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1020 /// cannot be retrieved after the plan has been executed, as the original loop
1021 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1022 /// target wants the vector loop left eligible for runtime unrolling.
1024 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1025 bool VectorizingEpilogue, MDNode *OrigLoopID,
1026 std::optional<unsigned> OrigAverageTripCount,
1027 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1028 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1029
1030private:
1031 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1032 /// scalar transformations applied. Returns null if an initial VPlan cannot
1033 /// be built.
1034 VPlanPtr tryToBuildVPlan1();
1035
1036 /// Build a VPlan using VPRecipes according to the information gathered by
1037 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1038 /// conversion only. For inner loops, \p Range's largest included VF is
1039 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1040 /// can be built for the input range, set the largest included VF to the
1041 /// maximum VF for which no plan could be built. Each VPlan is built starting
1042 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1043 /// original scalar loop.
1044 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);
1045
1046 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1047 /// based on \p VPlan1 and according to the information gathered by Legal
1048 /// when it checked if it is legal to vectorize the loop.
1049 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);
1050
1051 /// Add ComputeReductionResult recipes to the middle block to compute the
1052 /// final reduction results. Add Select recipes to the latch block when
1053 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1054 /// iteration values according to the header mask.
1055 void addReductionResultComputation(VPlanPtr &Plan,
1056 VPRecipeBuilder &RecipeBuilder,
1057 ElementCount MinVF);
1058
1059 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1060 /// that of B.
1061 bool isMoreProfitable(const VectorizationFactor &A,
1062 const VectorizationFactor &B, bool HasTail,
1063 bool IsEpilogue = false) const;
1064
1065 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1066 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1067 bool isMoreProfitable(const VectorizationFactor &A,
1068 const VectorizationFactor &B,
1069 const unsigned MaxTripCount, bool HasTail,
1070 bool IsEpilogue = false) const;
1071
1072 /// Determines if we have the infrastructure to vectorize the loop and its
1073 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1074 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1075};
1076
1077/// A helper function that returns true if the given type is irregular. The
1078/// type is irregular if its allocated size doesn't equal the store size of an
1079/// element of the corresponding vector type.
1080inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1081 // Determine if an array of N elements of type Ty is "bitcast compatible"
1082 // with a <N x Ty> vector.
1083 // This is only true if there is no padding between the array elements.
1084 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1085}
1086
1087} // namespace llvm
1088
1089#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:1720
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:1771
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:1685
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1875
std::unique_ptr< VPlan > selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC, bool ScalarEpilogueAllowed)
void plan(ElementCount UserVF, unsigned UserIC)
Build VPlans for the specified UserVF and UserIC if they are non-zero or all applicable candidate VFs...
void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount) const
Create a check to Plan to see if the vector loop should be executed based on its trip count.
bool hasPlanWithVF(ElementCount VF) const
Look through the existing plans and return true if we have one with vectorization factor VF.
std::pair< VectorizationFactor, VPlan * > computeBestVF()
Compute and return the most profitable vectorization factor and the corresponding best VPlan.
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Root of the metadata hierarchy.
Definition Metadata.h:64
The optimization diagnostic interface.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an analyzed expression in the program.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
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)
Instruction * getInLoopReductionImmediateChain(Instruction *I) const
Returns the immediate chain operand of in-loop reduction operation I, or nullptr if I is not an in-lo...
bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const
Returns true if epilogue vectorization is considered profitable for a main loop with vectorization fa...
bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const
Returns true if we should use strict in-order reductions for the given RdxDesc.
bool shouldConsiderRegPressureForVF(ElementCount VF) const
void collectElementTypesForWidening(const SmallPtrSetImpl< const Value * > *ValuesToIgnore=nullptr)
Collect element types in the loop that need widening.
std::optional< unsigned > getVScaleForTuning() const
void computeMinimalBitwidths()
Compute smallest bitwidth each instruction can be represented with.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4415
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4442
InsertPointGuard(const InsertPointGuard &)=delete
InsertPointGuard & operator=(const InsertPointGuard &)=delete
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createFirstActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenStoreRecipe * createWidenStore(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Store, storing StoredVal to Addr with Mask (may be null).
VPInstruction * createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPValue * createElementCount(Type *Ty, ElementCount EC)
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createVScale(Type *ResultTy, DebugLoc DL=DebugLoc::getUnknown())
Create a scalar llvm.vscale call.
VPSingleDefRecipe * createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, bool Reverse, DebugLoc DL)
Create a vector pointer recipe for a consecutive memory access to Ptr with element type SourceElement...
Definition VPlan.cpp:1700
VPWidenLoadRecipe * createWidenLoad(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Load, loading from Addr with Mask (may be null).
void restoreIP(VPInsertPoint IP)
Sets the current insert point to a previously-saved location.
VPVectorPointerRecipe * createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnyOfReduction(VPValue *ChainOp, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown())
Create an AnyOf reduction pattern: or-reduce ChainOp, freeze the result, then select between TrueVal ...
Definition VPlan.cpp:1672
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, std::optional< VPIRFlags > Flags=std::nullopt, const VPIRMetadata &Metadata={})
VPValue * createScalarFreeze(VPValue *Op, DebugLoc DL)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags GEPFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenPHIRecipe * createWidenPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Convert Current to Start + Current * Step.
VPWidenMemIntrinsicRecipe * createWidenMemIntrinsic(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL)
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createScalarIntrinsic(Intrinsic::ID IntrinsicID, ArrayRef< VPValue * > Operands, Type *ResultTy, DebugLoc DL)
Create a scalar call to the intrinsic IntrinsicID with Operands, and result type ResultTy.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilder()=default
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPExpandSCEVRecipe * createExpandSCEV(const SCEV *Expr)
VPBuilder(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPInstruction * createWidePtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilder(const VPInsertPoint &IP)
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4196
Recipe to expand a SCEV expression.
Definition VPlan.h:4028
Class to record and manage LLVM IR flags.
Definition VPlan.h:705
static VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
Helper to manage IR metadata for recipes.
Definition VPlan.h:1193
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1306
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1428
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:412
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3398
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4257
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:620
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2359
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1890
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2065
A recipe for widened phis.
Definition VPlan.h:2748
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4827
const DataLayout & getDataLayout() const
Definition VPlan.h:5041
LLVMContext & getContext() const
Definition VPlan.h:5037
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:5143
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr, DebugLoc DL={})
Reports an informative message: print Msg for debugging purposes as well as an optimization remark.
void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop, ElementCount VFWidth, unsigned IC)
Report successful vectorization of the loop.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
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.
DWARFExpression::Operation Op
std::optional< unsigned > getMaxVScale(const Function &F)
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:76
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A class that represents two vectorization factors (initialized with 0 by default).
FixedScalableVFPair(const ElementCount &FixedVF, const ElementCount &ScalableVF)
FixedScalableVFPair(const ElementCount &Max)
static FixedScalableVFPair getNone()
A range of powers-of-2 vectorization factors with fixed start and adjustable end.
Struct to hold various analysis needed for cost computations.
A struct that represents some properties of the register usage of a loop.
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3815
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3920
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class.
InstructionCost Cost
Cost of the loop with that width.
ElementCount MinProfitableTripCount
The minimum trip count required to make vectorization profitable, e.g.
bool operator==(const VectorizationFactor &rhs) const
ElementCount Width
Vector width with best cost.
InstructionCost ScalarCost
Cost of the scalar loop.
bool operator!=(const VectorizationFactor &rhs) const
static VectorizationFactor Disabled()
Width 1 means no vectorization, cost 0 means uncomputed cost.
VectorizationFactor(ElementCount Width, InstructionCost Cost, InstructionCost ScalarCost)