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 at \p It in \p VPBB.
106 VPBB->insert(R, It);
107 }
108};
109
110/// VPlan-based builder utility similar to IRBuilder. Recipes are inserted via
111/// \p InserterTy.
112template <typename InserterTy> class VPBuilderBase : public InserterTy {
113private:
114 class VPInsertPoint {
115 VPBasicBlock *Block = nullptr;
116 VPBasicBlock::iterator Iterator;
117
118 public:
119 /// Creates a new insertion point which doesn't point to anything.
120 VPInsertPoint() = default;
121
122 /// Creates a new insertion point to insert at \p Iterator in \p Block.
123 VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Iterator)
124 : Block(Block), Iterator(Iterator) {}
125
126 /// Creates a new insertion point to insert before \p R.
127 VPInsertPoint(VPRecipeBase *R)
128 : Block(R->getParent()), Iterator(R->getIterator()) {}
129
130 /// Creates a new insertion point to insert at the end of \p Block.
131 VPInsertPoint(VPBasicBlock *Block) : Block(Block), Iterator(Block->end()) {}
132
133 /// Returns true if this insert point is set.
134 operator bool() const { return Block; }
135
136 VPBasicBlock *getBlock() const { return Block; }
137 VPBasicBlock::iterator getIterator() const { return Iterator; }
138
139 operator VPRecipeBase *() const {
140 return Iterator == Block->end() ? nullptr : &*Iterator;
141 }
142 };
143
144 VPInsertPoint InsertPt;
145
146protected:
147 /// Insert \p VPI in BB at InsertPt if BB is set.
148 template <typename T> T *tryInsertInstruction(T *R) {
149 if (InsertPt)
150 InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
151 return R;
152 }
153
156 const VPIRMetadata &MD, DebugLoc DL,
157 const Twine &Name = "") {
159 new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
160 }
161
162public:
163 VPlan &getPlan() const {
164 assert(InsertPt && "Insert block must be set");
165 return *InsertPt.getBlock()->getPlan();
166 }
167
168 VPBuilderBase() = default;
169 VPBuilderBase(const VPInsertPoint &IP) : InsertPt(IP) {}
170 VPBuilderBase(InserterTy Inserter) : InserterTy(Inserter) {}
172 : InsertPt(TheBB, IP) {}
173
174 /// Get the recipe at the current insert point or nullptr if the insert point
175 /// is the end of the block.
176 VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }
177
178 /// Create a builder to insert after \p R.
180 return {R->getParent(), std::next(R->getIterator())};
181 }
182
183 /// Sets the current insert point to a previously-saved location.
184 void restoreIP(VPInsertPoint IP) { InsertPt = IP; }
185
186 /// Set the current insert point.
187 void setInsertPoint(const VPInsertPoint &IP) {
188 assert(IP && "Attempting to set a null insert point");
189 InsertPt = IP;
190 }
192 assert(TheBB && "Attempting to set a null insert point");
193 InsertPt = VPInsertPoint(TheBB, IP);
194 }
195
196 /// Insert \p R at the current insertion point. Returns \p R unchanged.
197 template <typename T> [[maybe_unused]] T *insert(T *R) {
198 InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
199 return R;
200 }
201
202 /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
203 /// its underlying Instruction.
205 Instruction *Inst = nullptr,
206 const VPIRFlags &Flags = {},
207 const VPIRMetadata &MD = {},
209 const Twine &Name = "",
210 Type *ResultTy = nullptr) {
211 VPInstruction *NewVPInst = tryInsertInstruction(
212 new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
213 NewVPInst->setUnderlyingValue(Inst);
214 return NewVPInst;
215 }
217 DebugLoc DL, const Twine &Name = "") {
218 return createInstruction(Opcode, Operands, {}, DL, Name);
219 }
221 const VPIRFlags &Flags,
223 const Twine &Name = "") {
225 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
226 }
227
229 Type *ResultTy, const VPIRFlags &Flags = {},
231 const Twine &Name = "") {
233 new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
234 }
235
238 const Twine &Name = "") {
239 // Assume that the maximum possible number of elements in a vector fits
240 // within the index type for the default address space.
241 VPlan &Plan = getPlan();
242 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
244 VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
245 }
246
249 const Twine &Name = "") {
250 // Assume that the maximum possible number of elements in a vector fits
251 // within the index type for the default address space.
252 VPlan &Plan = getPlan();
253 Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
255 VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
256 }
257
259 unsigned Opcode, ArrayRef<VPValue *> Operands,
260 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
261 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
263 new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
264 }
265
268 const Twine &Name = "") {
269 return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
270 }
271
274 const Twine &Name = "") {
275 return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
276 Name);
277 }
278
281 const Twine &Name = "") {
282
284 Instruction::BinaryOps::Or, {LHS, RHS},
285 VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
286 }
287
290 const Twine &Name = "",
291 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
292 return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
293 Name);
294 }
295
296 VPInstruction *
298 const Twine &Name = "",
299 VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
300 return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
301 Name);
302 }
303
309
315
316 /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
317 /// default flags for the result type, unless \p Flags is set.
319 VPValue *FalseVal,
321 const Twine &Name = "",
322 std::optional<VPIRFlags> Flags = std::nullopt) {
324 new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
325 Flags.value_or(VPIRFlags::getDefaultFlags(
326 Instruction::Select, TrueVal->getScalarType())),
327 {}, DL, Name));
328 }
329
330 /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
331 /// and \p B.
334 const Twine &Name = "") {
336 Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
338 new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
339 }
340
341 /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
342 /// and \p B.
345 const Twine &Name = "") {
347 Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
349 new VPInstruction(Instruction::FCmp, {A, B},
350 VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
351 }
352
353 /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
354 /// result, then select between \p TrueVal and \p FalseVal.
356 VPValue *FalseVal,
358 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
359 "ChainOp must be i1 for AnyOf reduction");
360 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
361 FastMathFlags());
363 {ChainOp}, Flags, DL);
364 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
365 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
366 }
367
370 const Twine &Name = "") {
371 return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
372 }
373
375 GEPNoWrapFlags GEPFlags,
377 const Twine &Name = "") {
379 VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
380 }
381
389
390 /// Create a phi with \p IncomingValues, using the default flags for the
391 /// result type, unless \p Flags is set.
394 const Twine &Name = "",
395 std::optional<VPIRFlags> Flags = std::nullopt,
396 Type *ResultTy = nullptr) {
397 Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
398 return tryInsertInstruction(new VPPhi(
399 IncomingValues,
400 Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
401 DL, Name, ResultTy));
402 }
403
406 const Twine &Name = "") {
407 return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
408 }
409
411 VPlan &Plan = getPlan();
412 unsigned MinEC = EC.getKnownMinValue();
413 if (EC.isScalable()) {
414 VPValue *VScale = createVScale(Ty);
415 if (MinEC == 1)
416 return VScale;
417 // TODO: Move this optimization into createOverflowingOp directly.
418 if (isPowerOf2_32(MinEC)) {
419 VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
420 return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
421 {true, false});
422 }
423 VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
424 return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
425 {true, false});
426 }
427 return Plan.getConstantInt(Ty, MinEC);
428 }
429
430 /// Convert \p Current to \p Start + \p Current * \p Step.
432 FPMathOperator *FPBinOp, VPValue *Start,
433 VPValue *Current, VPValue *Step,
434 const VPIRFlags::WrapFlagsTy &Flags = {}) {
436 new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
437 }
438
440 Type *ResultTy, DebugLoc DL,
441 std::optional<VPIRFlags> Flags = std::nullopt,
442 const VPIRMetadata &Metadata = {}) {
444 Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
445 Metadata, DL, "", ResultTy));
446 }
447
448 /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
449 /// result type \p ResultTy
452 Type *ResultTy, DebugLoc DL,
453 const Twine &Name = "") {
454 VPlan &Plan = getPlan();
456 Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
458 {}, {}, DL, Name, ResultTy));
459 }
460
461 /// Create a scalar llvm.vscale call.
464 return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
465 }
466
468 Type *SrcTy = Op->getScalarType();
469 if (ResultTy == SrcTy)
470 return Op;
471 Instruction::CastOps CastOp =
472 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
473 ? Instruction::Trunc
474 : Instruction::ZExt;
475 return createScalarCast(CastOp, Op, ResultTy, DL);
476 }
477
479 Type *SrcTy = Op->getScalarType();
480 if (ResultTy == SrcTy)
481 return Op;
482 Instruction::CastOps CastOp =
483 ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
484 ? Instruction::Trunc
485 : Instruction::SExt;
486 return createScalarCast(CastOp, Op, ResultTy, DL);
487 }
488
490 const Twine &Name = "") {
491 return createNaryOp(Instruction::Freeze, Op, DL, Name);
492 }
493
495 Type *ResultTy) {
496 assert(Op->getScalarType() != ResultTy &&
497 "must not create a no-op cast recipe");
499 Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
500 }
501
502 /// Create a single-scalar recipe with \p Opcode and \p Operands without
503 /// inserting it.
504 static VPSingleDefRecipe *
506 VPValue *Mask, const VPIRFlags &Flags,
508 Type *ResultTy, Instruction *UV) {
509 if (Instruction::isCast(Opcode)) {
510 assert(!Mask && "Cast cannot be predicated");
511 auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
512 UV->getName(), ResultTy);
513 VPI->setUnderlyingValue(UV);
514 return VPI;
515 }
516 auto *RepR = new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true,
517 Mask, Flags, Metadata, DL);
518 assert(RepR->getScalarType() == ResultTy && "unexpected result type");
519 return RepR;
520 }
521
524 FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
525 VPValue *VF, DebugLoc DL) {
527 IV, Step, VF, InductionOpcode,
528 FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
529 }
530
534
536 createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
537 GEPNoWrapFlags GEPFlags, DebugLoc DL) {
539 new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
540 }
541
542 /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
543 /// with element type \p SourceElementTy.
545 Type *SourceElementTy,
546 bool Reverse, DebugLoc DL) {
547 VPlan &Plan = getPlan();
549 if (Reverse) {
550 // When folding the tail, we may compute an address that we don't in the
551 // original scalar loop: drop the GEP no-wrap flags in this case.
552 // Otherwise preserve existing flags without no-unsigned-wrap, as we will
553 // emit negative indices.
554 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
556 : Flags.withoutNoUnsignedWrap();
558 new VPVectorEndPointerRecipe(Ptr, &Plan.getVF(), SourceElementTy,
559 /*Stride=*/-1, ReverseFlags, DL));
560 }
561 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
562 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
563 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
564 }
565
567 Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
568 Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
570 VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
571 }
572
573 /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
574 /// be null).
576 VPValue *Mask, bool Consecutive,
577 const VPIRMetadata &Metadata,
578 DebugLoc DL) {
580 new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
581 }
582
583 /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
584 /// \p Mask (may be null).
586 VPValue *StoredVal, VPValue *Mask,
587 bool Consecutive,
588 const VPIRMetadata &Metadata,
589 DebugLoc DL) {
591 Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
592 }
593
594 //===--------------------------------------------------------------------===//
595 // RAII helpers.
596 //===--------------------------------------------------------------------===//
597
598 /// RAII object that stores the current insertion point and restores it when
599 /// the object is destroyed.
601 VPBuilderBase &Builder;
602 VPInsertPoint InsertPt;
603
604 public:
605 InsertPointGuard(VPBuilderBase &B) : Builder(B), InsertPt(B.InsertPt) {}
606
609
610 ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
611 };
612};
613
614/// TODO: The following VectorizationFactor was pulled out of
615/// LoopVectorizationCostModel class. LV also deals with
616/// VectorizerParams::VectorizationFactor.
617/// We need to streamline them.
618
619/// Information about vectorization costs.
621 /// Vector width with best cost.
623
624 /// Cost of the loop with that width.
626
627 /// Cost of the scalar loop.
629
630 /// The minimum trip count required to make vectorization profitable, e.g. due
631 /// to runtime checks.
633
637
638 /// Width 1 means no vectorization, cost 0 means uncomputed cost.
640 return {ElementCount::getFixed(1), 0, 0};
641 }
642};
643
644/// A class that represents two vectorization factors (initialized with 0 by
645/// default). One for fixed-width vectorization and one for scalable
646/// vectorization. This can be used by the vectorizer to choose from a range of
647/// fixed and/or scalable VFs in order to find the most cost-effective VF to
648/// vectorize with.
652
654 : FixedVF(ElementCount::getFixed(0)),
655 ScalableVF(ElementCount::getScalable(0)) {}
657 *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
658 }
662 assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
663 "Invalid scalable properties");
664 }
665
667
668 /// \return true if either fixed- or scalable VF is non-zero.
669 explicit operator bool() const { return FixedVF || ScalableVF; }
670};
671
672/// Holds state needed to make cost decisions before computing costs per-VF,
673/// including the maximum VFs.
675 /// \return True if maximizing vector bandwidth is enabled by the target or
676 /// user options, for the given register kind (scalable or fixed-width).
677 bool useMaxBandwidth(bool IsScalable) const;
678
679 /// \return the maximized element count based on the targets vector
680 /// registers and the loop trip-count, but limited to a maximum safe VF.
681 /// This is a helper function of computeFeasibleMaxVF.
682 ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
683 unsigned SmallestType,
684 unsigned WidestType,
685 ElementCount MaxSafeVF, unsigned UserIC,
686 bool FoldTailByMasking,
687 bool RequiresScalarEpilogue);
688
689 /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
690 /// that results in VF * UserIC <= MaxTripCount.
691 ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
692 unsigned UserIC, bool FoldTailByMasking,
693 bool RequiresScalarEpilogue) const;
694
695 /// Checks if scalable vectorization is supported and enabled. Caches the
696 /// result to avoid repeated debug dumps for repeated queries.
697 bool isScalableVectorizationAllowed();
698
699 /// \return the maximum legal scalable VF, based on the safe max number
700 /// of elements.
701 ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);
702
703 /// Initializes the value of vscale used for tuning the cost model. If
704 /// vscale_range.min == vscale_range.max then return vscale_range.max, else
705 /// return the value returned by the corresponding TTI method.
706 void initializeVScaleForTuning();
707
708 const VectorizeOptions &Opts;
709 const TargetTransformInfo &TTI;
710 const LoopVectorizationLegality *Legal;
711 const Loop *TheLoop;
712 const Function &F;
714 DemandedBits *DB;
716 const LoopVectorizeHints *Hints;
717
718 /// Cached result of isScalableVectorizationAllowed.
719 std::optional<bool> IsScalableVectorizationAllowed;
720
721 /// Used to store the value of vscale used for tuning the cost model. It is
722 /// initialized during object construction.
723 std::optional<unsigned> VScaleForTuning;
724
725 /// The highest VF possible for this loop, without using MaxBandwidth.
726 FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;
727
728 /// All element types found in the loop.
729 SmallPtrSet<Type *, 16> ElementTypesInLoop;
730
731 /// PHINodes of the reductions that should be expanded in-loop. Set by
732 /// collectInLoopReductions.
733 SmallPtrSet<PHINode *, 4> InLoopReductions;
734
735 /// Maximum safe number of elements to be processed per vector iteration,
736 /// which do not prevent store-load forwarding and are safe with regard to the
737 /// memory dependencies. Required for EVL-based vectorization, where this
738 /// value is used as the upper bound of the safe AVL. Set by
739 /// computeFeasibleMaxVF.
740 std::optional<unsigned> MaxSafeElements;
741
742 /// Map of scalar integer values to the smallest bitwidth they can be legally
743 /// represented as. The vector equivalents of these values should be truncated
744 /// to this type.
746
747public:
748 /// The kind of cost that we are calculating.
750
751 /// Whether this loop should be optimized for size based on function attribute
752 /// or profile information.
753 const bool OptForSize;
754
755 VFSelectionContext(const VectorizeOptions &Opts,
756 const TargetTransformInfo &TTI,
757 const LoopVectorizationLegality *Legal,
758 const Loop *TheLoop, const Function &F,
761 const LoopVectorizeHints *Hints, bool OptForSize)
762 : Opts(Opts), TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE),
763 DB(DB), ORE(ORE), Hints(Hints),
764 CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
766 initializeVScaleForTuning();
767 }
768
769 /// \return The vscale value used for tuning the cost model.
770 std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }
771
772 const VectorizeOptions &getOpts() const { return Opts; }
773
774 const TargetTransformInfo &getTTI() const { return TTI; }
775
776 PredicatedScalarEvolution &getPSE() const { return PSE; }
777
778 /// \return The loop being analyzed.
779 const Loop *getLoop() const { return TheLoop; }
780
781 /// \return The vectorization hints for the loop being analyzed.
782 const LoopVectorizeHints &getHints() const { return *Hints; }
783
784 /// Returns true if epilogue vectorization is considered profitable for a
785 /// main loop with vectorization factor \p VF and interleave count \p IC.
786 bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;
787
788 /// \return True if register pressure should be considered for the given VF.
790
791 /// \return True if scalable vectors are supported by the target or forced.
792 bool supportsScalableVectors() const;
793
794 /// Collect element types in the loop that need widening.
796 const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);
797
798 /// \return The size (in bits) of the smallest and widest types in the code
799 /// that need to be vectorized. We ignore values that remain scalar such as
800 /// 64 bit loop indices.
801 std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;
802
803 /// \return An upper bound for the vectorization factors for both
804 /// fixed and scalable vectorization, where the minimum-known number of
805 /// elements is a power-of-2 larger than zero. If scalable vectorization is
806 /// disabled or unsupported, then the scalable part will be equal to
807 /// ElementCount::getScalable(0). Also sets MaxSafeElements.
808 FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
809 ElementCount UserVF, unsigned UserIC,
810 bool FoldTailByMasking,
811 bool RequiresScalarEpilogue);
812
813 /// Return maximum safe number of elements to be processed per vector
814 /// iteration, which do not prevent store-load forwarding and are safe with
815 /// regard to the memory dependencies. Required for EVL-based VPlans to
816 /// correctly calculate AVL (application vector length) as min(remaining AVL,
817 /// MaxSafeElements). Set by computeFeasibleMaxVF.
818 /// TODO: need to consider adjusting cost model to use this value as a
819 /// vectorization factor for EVL-based vectorization.
820 std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }
821
822 /// Returns true if we should use strict in-order reductions for the given
823 /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
824 /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
825 /// of FP operations.
826 bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;
827
828 /// Returns true if the target machine supports a masked load (if \p IsLoad)
829 /// or masked store of scalar type \p ScalarTy with \p Alignment in address
830 /// space \p AddressSpace. The caller must ensure the access is consecutive or
831 /// part of an interleave group.
832 bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
833 unsigned AddressSpace) const;
834
835 /// Returns true if the target machine supports a gather (if \p IsLoad)
836 /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
837 /// factor \p VF.
838 bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
839 ElementCount VF) const;
840
841 /// Split reductions into those that happen in the loop, and those that
842 /// happen outside. In-loop reductions are collected into InLoopReductions.
844
845 /// Returns true if the Phi is part of an inloop reduction.
846 bool isInLoopReduction(PHINode *Phi) const {
847 return InLoopReductions.contains(Phi);
848 }
849
850 /// Returns the set of in-loop reduction PHIs.
852 return InLoopReductions;
853 }
854
855 /// Check whether vectorization would require runtime checks. When optimizing
856 /// for size, returning true here aborts vectorization.
858
859 /// Returns a scalable VF to use for outer-loop vectorization if the target
860 /// supports it and a fixed VF otherwise.
862
863 /// Compute smallest bitwidth each instruction can be represented with.
864 /// The vector equivalents of these instructions should be truncated to this
865 /// type.
867
868 /// \returns The smallest bitwidth each instruction can be represented with.
870 return MinBWs;
871 }
872};
873
874/// Planner drives the vectorization process after having passed
875/// Legality checks.
877 const VectorizeOptions &Opts;
878
879 /// The loop that we evaluate.
880 Loop *OrigLoop;
881
882 /// Loop Info analysis.
883 LoopInfo *LI;
884
885 /// The dominator tree.
886 DominatorTree *DT;
887
888 /// Target Library Info.
889 const TargetLibraryInfo *TLI;
890
891 /// Target Transform Info.
892 const TargetTransformInfo &TTI;
893
894 /// The legality analysis.
896
897 /// The profitability analysis. Cleared after making cost based decisions.
898 /// This instance should never be used in any function that takes an explicit
899 /// PlanCM reference, since that instance overrides this one.
900 std::unique_ptr<LoopVectorizationCostModel> CM;
901
902 /// VF selection state independent of cost-modeling decisions.
903 VFSelectionContext &Config;
904
906
908
909 /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
910 std::function<const BranchProbabilityInfo &()> GetBPI;
911
913
914 /// Profitable vector factors.
916
917 /// A builder used to construct the current plan.
918 VPBuilder Builder;
919
920 /// Computes the cost of \p Plan for vectorization factor \p VF, using
921 /// \p PlanCM as the cost model.
922 ///
923 /// The current implementation requires access to the
924 /// LoopVectorizationLegality to handle inductions and reductions, which is
925 /// why it is kept separate from the VPlan-only cost infrastructure.
926 ///
927 /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
928 /// been retired.
930 LoopVectorizationCostModel &PlanCM) const;
931
932 /// Precompute costs for certain instructions using the legacy cost model. The
933 /// function is used to bring up the VPlan-based cost model to initially avoid
934 /// taking different decisions due to inaccuracies in the legacy cost model.
935 InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
936 VPCostContext &CostCtx) const;
937
938public:
940 Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
942 std::unique_ptr<LoopVectorizationCostModel> CM,
945 std::function<const BranchProbabilityInfo &()> GetBPI);
946
948
949 /// Return the cost model. Must not be called after clearCostModel().
951 assert(CM && "Cost model has already been cleared");
952 return *CM;
953 }
954
955 /// Destroy the cost model.
956 void clearCostModel();
957
958 /// Return true if there is at least one VPlan for a vector VF
959 bool hasVectorPlan() const {
960 return any_of(
961 VPlans, [&](const VPlanPtr &Plan) { return !Plan->hasScalarVFOnly(); });
962 }
963
964 /// Returns true if there is at least one VPlan.
965 bool hasAPlan() const { return !VPlans.empty(); }
966
967 /// Build VPlans for the specified \p UserVF and \p UserIC if they are
968 /// non-zero or all applicable candidate VFs otherwise. If vectorization and
969 /// interleaving should be avoided up-front, no plans are generated.
970 void plan(ElementCount UserVF, unsigned UserIC);
971
972 /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
973 /// for each VF.
974 VPlan &getPlanFor(ElementCount VF) const;
975
976 /// Compute and return the most profitable vectorization factor and the
977 /// corresponding best VPlan. Also collect all profitable VFs in
978 /// ProfitableVFs.
979 std::pair<VectorizationFactor, VPlan *> computeBestVF();
980
981 /// \return The desired interleave count.
982 /// If interleave count has been specified by metadata it will be returned.
983 /// Otherwise, the interleave count is computed and returned. VF and LoopCost
984 /// are the selected vectorization factor and the cost of the selected VF.
985 unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
986 InstructionCost LoopCost);
987
988 /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
989 /// according to the best selected \p VF and \p UF.
990 ///
991 /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
992 /// fixed.
993 ///
994 /// Returns a mapping of SCEVs to their expanded IR values.
995 /// Note that this is a temporary workaround needed due to the current
996 /// epilogue handling.
998 None, ///< Not part of epilogue vectorization.
999 MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
1000 Epilogue ///< Vectorizing the epilogue loop.
1001 };
1003 executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
1005 EpilogueVectorizationKind EpilogueVecKind =
1007
1008#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1009 void printPlans(raw_ostream &O);
1010#endif
1011
1012 /// Look through the existing plans and return true if we have one with
1013 /// vectorization factor \p VF.
1015 return any_of(VPlans,
1016 [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
1017 }
1018
1019 /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
1020 /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
1021 /// returned value holds for the entire \p Range.
1022 static bool
1023 getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
1024 VFRange &Range);
1025
1026 /// \return A VPlan for the most profitable epilogue vectorization, with its
1027 /// VF narrowed to the chosen factor. The returned plan is a duplicate.
1028 /// Returns nullptr if epilogue vectorization is not supported or not
1029 /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
1030 /// epilogue lowering policy permits creating a scalar epilogue at all.
1031 std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
1032 ElementCount MainLoopVF,
1033 unsigned IC,
1034 bool ScalarEpilogueAllowed);
1035
1036 /// Emit remarks for recipes with invalid costs in the available VPlans.
1038
1039 /// Create a check to \p Plan to see if the vector loop should be executed
1040 /// based on its trip count.
1041 void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
1042 ElementCount MinProfitableTripCount) const;
1043
1044 /// Attach the runtime checks of \p RTChecks to \p Plan. \p VF and \p UF are
1045 /// used to compute the thresholds of difference checks.
1046 void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
1047 ElementCount VF, unsigned UF,
1048 bool HasBranchWeights) const;
1049
1050 /// Update loop metadata and profile info for both the scalar remainder loop
1051 /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
1052 /// loop on the vector loop and replaces vectorizer-specific metadata. The
1053 /// loop ID of the original loop \p OrigLoopID must be passed, together with
1054 /// the average trip count and invocation weight of the original loop (\p
1055 /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
1056 /// cannot be retrieved after the plan has been executed, as the original loop
1057 /// may have been removed. \p UnrollVectorizedLoop indicates whether the
1058 /// target wants the vector loop left eligible for runtime unrolling.
1060 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1061 bool VectorizingEpilogue, MDNode *OrigLoopID,
1062 std::optional<unsigned> OrigAverageTripCount,
1063 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1064 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);
1065
1066private:
1067 /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
1068 /// scalar transformations applied. Returns null if an initial VPlan cannot
1069 /// be built. \p PlanCM is the cost model to use for decisions made while
1070 /// building the plan.
1071 VPlanPtr tryToBuildVPlan1(LoopVectorizationCostModel &PlanCM);
1072
1073 /// Build a VPlan using VPRecipes according to the information gathered by
1074 /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
1075 /// conversion only. For inner loops, \p Range's largest included VF is
1076 /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
1077 /// can be built for the input range, set the largest included VF to the
1078 /// maximum VF for which no plan could be built. Each VPlan is built starting
1079 /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
1080 /// original scalar loop. \p PlanCM is the cost model used for legality
1081 /// and widening decisions while building the plan.
1082 VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range,
1084
1085 /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
1086 /// based on \p VPlan1 and according to the information gathered by Legal
1087 /// when it checked if it is legal to vectorize the loop. \p PlanCM is
1088 /// the cost model to build these VPlans.
1089 void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF,
1091
1092 /// Add ComputeReductionResult recipes to the middle block to compute the
1093 /// final reduction results. Add Select recipes to the latch block when
1094 /// folding tail, to feed ComputeReductionResult with the last or penultimate
1095 /// iteration values according to the header mask. \p PlanCM is the cost
1096 /// model used to build \p Plan.
1097 void addReductionResultComputation(VPlanPtr &Plan, ElementCount MinVF,
1099
1100 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1101 /// that of B.
1102 bool isMoreProfitable(const VectorizationFactor &A,
1103 const VectorizationFactor &B, bool HasTail,
1104 bool IsEpilogue = false) const;
1105
1106 /// Returns true if the per-lane cost of VectorizationFactor A is lower than
1107 /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
1108 bool isMoreProfitable(const VectorizationFactor &A,
1109 const VectorizationFactor &B,
1110 const unsigned MaxTripCount, bool HasTail,
1111 bool IsEpilogue = false) const;
1112
1113 /// Determines if we have the infrastructure to vectorize the loop and its
1114 /// epilogue, assuming the main loop is vectorized by \p MainPlan.
1115 bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
1116};
1117
1118/// A helper function that returns true if the given type is irregular. The
1119/// type is irregular if its allocated size doesn't equal the store size of an
1120/// element of the corresponding vector type.
1121inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
1122 // Determine if an array of N elements of type Ty is "bitcast compatible"
1123 // with a <N x Ty> vector.
1124 // This is only true if there is no padding between the array elements.
1125 return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
1126}
1127
1128} // namespace llvm
1129
1130#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: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...
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:1639
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:1690
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:1625
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1794
std::unique_ptr< VPlan > selectBestEpiloguePlan(VPlan &MainPlan, ElementCount MainLoopVF, unsigned IC, bool ScalarEpilogueAllowed)
void plan(ElementCount UserVF, unsigned UserIC)
Build VPlans for the specified UserVF and UserIC if they are non-zero or all applicable candidate VFs...
void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount) const
Create a check to Plan to see if the vector loop should be executed based on its trip count.
bool hasPlanWithVF(ElementCount VF) const
Look through the existing plans and return true if we have one with vectorization factor VF.
std::pair< VectorizationFactor, VPlan * > computeBestVF()
Compute and return the most profitable vectorization factor and the corresponding best VPlan.
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Root of the metadata hierarchy.
Definition Metadata.h:64
The optimization diagnostic interface.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an analyzed expression in the program.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
Holds state needed to make cost decisions before computing costs per-VF, including the maximum VFs.
PredicatedScalarEvolution & getPSE() const
const 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:4464
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4491
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4530
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 VPI in BB at InsertPt if BB is set.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags GEPFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
VPExpandSCEVRecipe * createExpandSCEV(const SCEV *Expr)
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Convert Current to Start + Current * Step.
VPBuilderBase(const VPInsertPoint &IP)
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
T * insert(T *R)
Insert R at the current insertion point. Returns R unchanged.
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Type *ResultTy, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPInstruction * createLogicalOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL)
VPInstruction * createVScale(Type *ResultTy, DebugLoc DL=DebugLoc::getUnknown())
Create a scalar llvm.vscale call.
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, std::optional< VPIRFlags > Flags=std::nullopt, const VPIRMetadata &Metadata={})
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.
void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLastActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPWidenLoadRecipe * createWidenLoad(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Load, loading from Addr with Mask (may be null).
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPBuilderBase()=default
VPWidenStoreRecipe * createWidenStore(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Create a recipe widening Store, storing StoredVal to Addr with Mask (may be null).
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPSingleDefRecipe * createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, bool Reverse, DebugLoc DL)
Create a vector pointer recipe for a consecutive memory access to Ptr with element type SourceElement...
VPInstruction * createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false})
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
VPWidenMemIntrinsicRecipe * createWidenMemIntrinsic(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL)
VPInstruction * createFirstActiveLane(ArrayRef< VPValue * > Masks, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilderBase(InserterTy Inserter)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPWidenPHIRecipe * createWidenPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createElementCount(Type *Ty, ElementCount EC)
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBuilderBase(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4245
Recipe to expand a SCEV expression.
Definition VPlan.h:4077
Class to record and manage LLVM IR flags.
Definition VPlan.h:690
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:1165
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1315
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1441
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1374
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:405
Helper class to create VPRecipies from IR instructions.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3447
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4306
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:613
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:2324
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2406
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1906
A recipe for widening vector memory intrinsics.
Definition VPlan.h:2083
A recipe for widened phis.
Definition VPlan.h:2784
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4876
const DataLayout & getDataLayout() const
Definition VPlan.h:5090
LLVMContext & getContext() const
Definition VPlan.h:5086
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:4993
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5077
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:5196
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr, DebugLoc DL={})
Reports an informative message: print Msg for debugging purposes as well as an optimization remark.
void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop, ElementCount VFWidth, unsigned IC)
Report successful vectorization of the loop.
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
VPBuilderBase<> VPBuilder
Definition VPlan.h: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 at It in VPBB.
void insertHelper(VPRecipeBase *R, VPBasicBlock *VPBB, VPBasicBlock::iterator It)
Struct to hold various analysis needed for cost computations.
A struct that represents some properties of the register usage of a loop.
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3864
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3969
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)