LLVM 21.0.0git
VPlan.h
Go to the documentation of this file.
1//===- VPlan.h - Represent A Vectorizer Plan --------------------*- C++ -*-===//
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 contains the declarations of the Vectorization Plan base classes:
11/// 1. VPBasicBlock and VPRegionBlock that inherit from a common pure virtual
12/// VPBlockBase, together implementing a Hierarchical CFG;
13/// 2. Pure virtual VPRecipeBase serving as the base class for recipes contained
14/// within VPBasicBlocks;
15/// 3. Pure virtual VPSingleDefRecipe serving as a base class for recipes that
16/// also inherit from VPValue.
17/// 4. VPInstruction, a concrete Recipe and VPUser modeling a single planned
18/// instruction;
19/// 5. The VPlan class holding a candidate for vectorization;
20/// These are documented in docs/VectorizationPlan.rst.
21//
22//===----------------------------------------------------------------------===//
23
24#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
25#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
26
27#include "VPlanAnalysis.h"
28#include "VPlanValue.h"
29#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/Twine.h"
34#include "llvm/ADT/ilist.h"
35#include "llvm/ADT/ilist_node.h"
38#include "llvm/IR/DebugLoc.h"
39#include "llvm/IR/FMF.h"
40#include "llvm/IR/Operator.h"
42#include <algorithm>
43#include <cassert>
44#include <cstddef>
45#include <string>
46
47namespace llvm {
48
49class BasicBlock;
50class DominatorTree;
51class InnerLoopVectorizer;
52class IRBuilderBase;
53struct VPTransformState;
54class raw_ostream;
55class RecurrenceDescriptor;
56class SCEV;
57class Type;
58class VPBasicBlock;
59class VPBuilder;
60class VPRegionBlock;
61class VPlan;
62class VPLane;
63class VPReplicateRecipe;
64class VPlanSlp;
65class Value;
66class LoopVectorizationCostModel;
67
68struct VPCostContext;
69
70namespace Intrinsic {
71typedef unsigned ID;
72}
73
74using VPlanPtr = std::unique_ptr<VPlan>;
75
76/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
77/// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
79 friend class VPBlockUtils;
80
81 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
82
83 /// An optional name for the block.
84 std::string Name;
85
86 /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if
87 /// it is a topmost VPBlockBase.
88 VPRegionBlock *Parent = nullptr;
89
90 /// List of predecessor blocks.
92
93 /// List of successor blocks.
95
96 /// VPlan containing the block. Can only be set on the entry block of the
97 /// plan.
98 VPlan *Plan = nullptr;
99
100 /// Add \p Successor as the last successor to this block.
101 void appendSuccessor(VPBlockBase *Successor) {
102 assert(Successor && "Cannot add nullptr successor!");
103 Successors.push_back(Successor);
104 }
105
106 /// Add \p Predecessor as the last predecessor to this block.
107 void appendPredecessor(VPBlockBase *Predecessor) {
108 assert(Predecessor && "Cannot add nullptr predecessor!");
109 Predecessors.push_back(Predecessor);
110 }
111
112 /// Remove \p Predecessor from the predecessors of this block.
113 void removePredecessor(VPBlockBase *Predecessor) {
114 auto Pos = find(Predecessors, Predecessor);
115 assert(Pos && "Predecessor does not exist");
116 Predecessors.erase(Pos);
117 }
118
119 /// Remove \p Successor from the successors of this block.
120 void removeSuccessor(VPBlockBase *Successor) {
121 auto Pos = find(Successors, Successor);
122 assert(Pos && "Successor does not exist");
123 Successors.erase(Pos);
124 }
125
126 /// This function replaces one predecessor with another, useful when
127 /// trying to replace an old block in the CFG with a new one.
128 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
129 auto I = find(Predecessors, Old);
130 assert(I != Predecessors.end());
131 assert(Old->getParent() == New->getParent() &&
132 "replaced predecessor must have the same parent");
133 *I = New;
134 }
135
136 /// This function replaces one successor with another, useful when
137 /// trying to replace an old block in the CFG with a new one.
138 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
139 auto I = find(Successors, Old);
140 assert(I != Successors.end());
141 assert(Old->getParent() == New->getParent() &&
142 "replaced successor must have the same parent");
143 *I = New;
144 }
145
146protected:
147 VPBlockBase(const unsigned char SC, const std::string &N)
148 : SubclassID(SC), Name(N) {}
149
150public:
151 /// An enumeration for keeping track of the concrete subclass of VPBlockBase
152 /// that are actually instantiated. Values of this enumeration are kept in the
153 /// SubclassID field of the VPBlockBase objects. They are used for concrete
154 /// type identification.
155 using VPBlockTy = enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC };
156
158
159 virtual ~VPBlockBase() = default;
160
161 const std::string &getName() const { return Name; }
162
163 void setName(const Twine &newName) { Name = newName.str(); }
164
165 /// \return an ID for the concrete type of this object.
166 /// This is used to implement the classof checks. This should not be used
167 /// for any other purpose, as the values may change as LLVM evolves.
168 unsigned getVPBlockID() const { return SubclassID; }
169
170 VPRegionBlock *getParent() { return Parent; }
171 const VPRegionBlock *getParent() const { return Parent; }
172
173 /// \return A pointer to the plan containing the current block.
174 VPlan *getPlan();
175 const VPlan *getPlan() const;
176
177 /// Sets the pointer of the plan containing the block. The block must be the
178 /// entry block into the VPlan.
179 void setPlan(VPlan *ParentPlan);
180
181 void setParent(VPRegionBlock *P) { Parent = P; }
182
183 /// \return the VPBasicBlock that is the entry of this VPBlockBase,
184 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
185 /// VPBlockBase is a VPBasicBlock, it is returned.
186 const VPBasicBlock *getEntryBasicBlock() const;
188
189 /// \return the VPBasicBlock that is the exiting this VPBlockBase,
190 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
191 /// VPBlockBase is a VPBasicBlock, it is returned.
192 const VPBasicBlock *getExitingBasicBlock() const;
194
195 const VPBlocksTy &getSuccessors() const { return Successors; }
196 VPBlocksTy &getSuccessors() { return Successors; }
197
200
201 const VPBlocksTy &getPredecessors() const { return Predecessors; }
202 VPBlocksTy &getPredecessors() { return Predecessors; }
203
204 /// \return the successor of this VPBlockBase if it has a single successor.
205 /// Otherwise return a null pointer.
207 return (Successors.size() == 1 ? *Successors.begin() : nullptr);
208 }
209
210 /// \return the predecessor of this VPBlockBase if it has a single
211 /// predecessor. Otherwise return a null pointer.
213 return (Predecessors.size() == 1 ? *Predecessors.begin() : nullptr);
214 }
215
216 size_t getNumSuccessors() const { return Successors.size(); }
217 size_t getNumPredecessors() const { return Predecessors.size(); }
218
219 /// An Enclosing Block of a block B is any block containing B, including B
220 /// itself. \return the closest enclosing block starting from "this", which
221 /// has successors. \return the root enclosing block if all enclosing blocks
222 /// have no successors.
224
225 /// \return the closest enclosing block starting from "this", which has
226 /// predecessors. \return the root enclosing block if all enclosing blocks
227 /// have no predecessors.
229
230 /// \return the successors either attached directly to this VPBlockBase or, if
231 /// this VPBlockBase is the exit block of a VPRegionBlock and has no
232 /// successors of its own, search recursively for the first enclosing
233 /// VPRegionBlock that has successors and return them. If no such
234 /// VPRegionBlock exists, return the (empty) successors of the topmost
235 /// VPBlockBase reached.
238 }
239
240 /// \return the hierarchical successor of this VPBlockBase if it has a single
241 /// hierarchical successor. Otherwise return a null pointer.
244 }
245
246 /// \return the predecessors either attached directly to this VPBlockBase or,
247 /// if this VPBlockBase is the entry block of a VPRegionBlock and has no
248 /// predecessors of its own, search recursively for the first enclosing
249 /// VPRegionBlock that has predecessors and return them. If no such
250 /// VPRegionBlock exists, return the (empty) predecessors of the topmost
251 /// VPBlockBase reached.
254 }
255
256 /// \return the hierarchical predecessor of this VPBlockBase if it has a
257 /// single hierarchical predecessor. Otherwise return a null pointer.
260 }
261
262 /// Set a given VPBlockBase \p Successor as the single successor of this
263 /// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor.
264 /// This VPBlockBase must have no successors.
266 assert(Successors.empty() && "Setting one successor when others exist.");
267 assert(Successor->getParent() == getParent() &&
268 "connected blocks must have the same parent");
269 appendSuccessor(Successor);
270 }
271
272 /// Set two given VPBlockBases \p IfTrue and \p IfFalse to be the two
273 /// successors of this VPBlockBase. This VPBlockBase is not added as
274 /// predecessor of \p IfTrue or \p IfFalse. This VPBlockBase must have no
275 /// successors.
276 void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse) {
277 assert(Successors.empty() && "Setting two successors when others exist.");
278 appendSuccessor(IfTrue);
279 appendSuccessor(IfFalse);
280 }
281
282 /// Set each VPBasicBlock in \p NewPreds as predecessor of this VPBlockBase.
283 /// This VPBlockBase must have no predecessors. This VPBlockBase is not added
284 /// as successor of any VPBasicBlock in \p NewPreds.
286 assert(Predecessors.empty() && "Block predecessors already set.");
287 for (auto *Pred : NewPreds)
288 appendPredecessor(Pred);
289 }
290
291 /// Set each VPBasicBlock in \p NewSuccss as successor of this VPBlockBase.
292 /// This VPBlockBase must have no successors. This VPBlockBase is not added
293 /// as predecessor of any VPBasicBlock in \p NewSuccs.
295 assert(Successors.empty() && "Block successors already set.");
296 for (auto *Succ : NewSuccs)
297 appendSuccessor(Succ);
298 }
299
300 /// Remove all the predecessor of this block.
301 void clearPredecessors() { Predecessors.clear(); }
302
303 /// Remove all the successors of this block.
304 void clearSuccessors() { Successors.clear(); }
305
306 /// Swap successors of the block. The block must have exactly 2 successors.
307 // TODO: This should be part of introducing conditional branch recipes rather
308 // than being independent.
310 assert(Successors.size() == 2 && "must have 2 successors to swap");
311 std::swap(Successors[0], Successors[1]);
312 }
313
314 /// The method which generates the output IR that correspond to this
315 /// VPBlockBase, thereby "executing" the VPlan.
316 virtual void execute(VPTransformState *State) = 0;
317
318 /// Return the cost of the block.
320
321 /// Return true if it is legal to hoist instructions into this block.
323 // There are currently no constraints that prevent an instruction to be
324 // hoisted into a VPBlockBase.
325 return true;
326 }
327
328#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
329 void printAsOperand(raw_ostream &OS, bool PrintType = false) const {
330 OS << getName();
331 }
332
333 /// Print plain-text dump of this VPBlockBase to \p O, prefixing all lines
334 /// with \p Indent. \p SlotTracker is used to print unnamed VPValue's using
335 /// consequtive numbers.
336 ///
337 /// Note that the numbering is applied to the whole VPlan, so printing
338 /// individual blocks is consistent with the whole VPlan printing.
339 virtual void print(raw_ostream &O, const Twine &Indent,
340 VPSlotTracker &SlotTracker) const = 0;
341
342 /// Print plain-text dump of this VPlan to \p O.
343 void print(raw_ostream &O) const;
344
345 /// Print the successors of this block to \p O, prefixing all lines with \p
346 /// Indent.
347 void printSuccessors(raw_ostream &O, const Twine &Indent) const;
348
349 /// Dump this VPBlockBase to dbgs().
350 LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
351#endif
352
353 /// Clone the current block and it's recipes without updating the operands of
354 /// the cloned recipes, including all blocks in the single-entry single-exit
355 /// region for VPRegionBlocks.
356 virtual VPBlockBase *clone() = 0;
357};
358
359/// VPRecipeBase is a base class modeling a sequence of one or more output IR
360/// instructions. VPRecipeBase owns the VPValues it defines through VPDef
361/// and is responsible for deleting its defined values. Single-value
362/// recipes must inherit from VPSingleDef instead of inheriting from both
363/// VPRecipeBase and VPValue separately.
364class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
365 public VPDef,
366 public VPUser {
367 friend VPBasicBlock;
368 friend class VPBlockUtils;
369
370 /// Each VPRecipe belongs to a single VPBasicBlock.
371 VPBasicBlock *Parent = nullptr;
372
373 /// The debug location for the recipe.
374 DebugLoc DL;
375
376public:
378 DebugLoc DL = {})
379 : VPDef(SC), VPUser(Operands), DL(DL) {}
380
381 template <typename IterT>
383 DebugLoc DL = {})
384 : VPDef(SC), VPUser(Operands), DL(DL) {}
385 virtual ~VPRecipeBase() = default;
386
387 /// Clone the current recipe.
388 virtual VPRecipeBase *clone() = 0;
389
390 /// \return the VPBasicBlock which this VPRecipe belongs to.
391 VPBasicBlock *getParent() { return Parent; }
392 const VPBasicBlock *getParent() const { return Parent; }
393
394 /// The method which generates the output IR instructions that correspond to
395 /// this VPRecipe, thereby "executing" the VPlan.
396 virtual void execute(VPTransformState &State) = 0;
397
398 /// Return the cost of this recipe, taking into account if the cost
399 /// computation should be skipped and the ForceTargetInstructionCost flag.
400 /// Also takes care of printing the cost for debugging.
402
403 /// Insert an unlinked recipe into a basic block immediately before
404 /// the specified recipe.
405 void insertBefore(VPRecipeBase *InsertPos);
406 /// Insert an unlinked recipe into \p BB immediately before the insertion
407 /// point \p IP;
409
410 /// Insert an unlinked Recipe into a basic block immediately after
411 /// the specified Recipe.
412 void insertAfter(VPRecipeBase *InsertPos);
413
414 /// Unlink this recipe from its current VPBasicBlock and insert it into
415 /// the VPBasicBlock that MovePos lives in, right after MovePos.
416 void moveAfter(VPRecipeBase *MovePos);
417
418 /// Unlink this recipe and insert into BB before I.
419 ///
420 /// \pre I is a valid iterator into BB.
422
423 /// This method unlinks 'this' from the containing basic block, but does not
424 /// delete it.
425 void removeFromParent();
426
427 /// This method unlinks 'this' from the containing basic block and deletes it.
428 ///
429 /// \returns an iterator pointing to the element after the erased one
431
432 /// Method to support type inquiry through isa, cast, and dyn_cast.
433 static inline bool classof(const VPDef *D) {
434 // All VPDefs are also VPRecipeBases.
435 return true;
436 }
437
438 static inline bool classof(const VPUser *U) { return true; }
439
440 /// Returns true if the recipe may have side-effects.
441 bool mayHaveSideEffects() const;
442
443 /// Returns true for PHI-like recipes.
444 bool isPhi() const {
445 return getVPDefID() >= VPFirstPHISC && getVPDefID() <= VPLastPHISC;
446 }
447
448 /// Returns true if the recipe may read from memory.
449 bool mayReadFromMemory() const;
450
451 /// Returns true if the recipe may write to memory.
452 bool mayWriteToMemory() const;
453
454 /// Returns true if the recipe may read from or write to memory.
455 bool mayReadOrWriteMemory() const {
457 }
458
459 /// Returns the debug location of the recipe.
460 DebugLoc getDebugLoc() const { return DL; }
461
462protected:
463 /// Compute the cost of this recipe either using a recipe's specialized
464 /// implementation or using the legacy cost model and the underlying
465 /// instructions.
467 VPCostContext &Ctx) const;
468};
469
470// Helper macro to define common classof implementations for recipes.
471#define VP_CLASSOF_IMPL(VPDefID) \
472 static inline bool classof(const VPDef *D) { \
473 return D->getVPDefID() == VPDefID; \
474 } \
475 static inline bool classof(const VPValue *V) { \
476 auto *R = V->getDefiningRecipe(); \
477 return R && R->getVPDefID() == VPDefID; \
478 } \
479 static inline bool classof(const VPUser *U) { \
480 auto *R = dyn_cast<VPRecipeBase>(U); \
481 return R && R->getVPDefID() == VPDefID; \
482 } \
483 static inline bool classof(const VPRecipeBase *R) { \
484 return R->getVPDefID() == VPDefID; \
485 } \
486 static inline bool classof(const VPSingleDefRecipe *R) { \
487 return R->getVPDefID() == VPDefID; \
488 }
489
490/// VPSingleDef is a base class for recipes for modeling a sequence of one or
491/// more output IR that define a single result VPValue.
492/// Note that VPRecipeBase must be inherited from before VPValue.
493class VPSingleDefRecipe : public VPRecipeBase, public VPValue {
494public:
495 template <typename IterT>
496 VPSingleDefRecipe(const unsigned char SC, IterT Operands, DebugLoc DL = {})
497 : VPRecipeBase(SC, Operands, DL), VPValue(this) {}
498
499 VPSingleDefRecipe(const unsigned char SC, ArrayRef<VPValue *> Operands,
500 DebugLoc DL = {})
501 : VPRecipeBase(SC, Operands, DL), VPValue(this) {}
502
503 template <typename IterT>
504 VPSingleDefRecipe(const unsigned char SC, IterT Operands, Value *UV,
505 DebugLoc DL = {})
506 : VPRecipeBase(SC, Operands, DL), VPValue(this, UV) {}
507
508 static inline bool classof(const VPRecipeBase *R) {
509 switch (R->getVPDefID()) {
510 case VPRecipeBase::VPDerivedIVSC:
511 case VPRecipeBase::VPEVLBasedIVPHISC:
512 case VPRecipeBase::VPExpandSCEVSC:
513 case VPRecipeBase::VPInstructionSC:
514 case VPRecipeBase::VPReductionEVLSC:
515 case VPRecipeBase::VPReductionSC:
516 case VPRecipeBase::VPReplicateSC:
517 case VPRecipeBase::VPScalarIVStepsSC:
518 case VPRecipeBase::VPVectorPointerSC:
519 case VPRecipeBase::VPReverseVectorPointerSC:
520 case VPRecipeBase::VPWidenCallSC:
521 case VPRecipeBase::VPWidenCanonicalIVSC:
522 case VPRecipeBase::VPWidenCastSC:
523 case VPRecipeBase::VPWidenGEPSC:
524 case VPRecipeBase::VPWidenIntrinsicSC:
525 case VPRecipeBase::VPWidenSC:
526 case VPRecipeBase::VPWidenEVLSC:
527 case VPRecipeBase::VPWidenSelectSC:
528 case VPRecipeBase::VPBlendSC:
529 case VPRecipeBase::VPPredInstPHISC:
530 case VPRecipeBase::VPCanonicalIVPHISC:
531 case VPRecipeBase::VPActiveLaneMaskPHISC:
532 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
533 case VPRecipeBase::VPWidenPHISC:
534 case VPRecipeBase::VPWidenIntOrFpInductionSC:
535 case VPRecipeBase::VPWidenPointerInductionSC:
536 case VPRecipeBase::VPReductionPHISC:
537 case VPRecipeBase::VPScalarCastSC:
538 case VPRecipeBase::VPPartialReductionSC:
539 return true;
540 case VPRecipeBase::VPBranchOnMaskSC:
541 case VPRecipeBase::VPInterleaveSC:
542 case VPRecipeBase::VPIRInstructionSC:
543 case VPRecipeBase::VPWidenLoadEVLSC:
544 case VPRecipeBase::VPWidenLoadSC:
545 case VPRecipeBase::VPWidenStoreEVLSC:
546 case VPRecipeBase::VPWidenStoreSC:
547 case VPRecipeBase::VPHistogramSC:
548 // TODO: Widened stores don't define a value, but widened loads do. Split
549 // the recipes to be able to make widened loads VPSingleDefRecipes.
550 return false;
551 }
552 llvm_unreachable("Unhandled VPDefID");
553 }
554
555 static inline bool classof(const VPUser *U) {
556 auto *R = dyn_cast<VPRecipeBase>(U);
557 return R && classof(R);
558 }
559
560 virtual VPSingleDefRecipe *clone() override = 0;
561
562 /// Returns the underlying instruction.
564 return cast<Instruction>(getUnderlyingValue());
565 }
567 return cast<Instruction>(getUnderlyingValue());
568 }
569
570#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
571 /// Print this VPSingleDefRecipe to dbgs() (for debugging).
572 LLVM_DUMP_METHOD void dump() const;
573#endif
574};
575
576/// Class to record LLVM IR flag for a recipe along with it.
578 enum class OperationType : unsigned char {
579 Cmp,
580 OverflowingBinOp,
581 DisjointOp,
582 PossiblyExactOp,
583 GEPOp,
584 FPMathOp,
585 NonNegOp,
586 Other
587 };
588
589public:
590 struct WrapFlagsTy {
591 char HasNUW : 1;
592 char HasNSW : 1;
593
595 };
596
598 char IsDisjoint : 1;
600 };
601
602private:
603 struct ExactFlagsTy {
604 char IsExact : 1;
605 };
606 struct NonNegFlagsTy {
607 char NonNeg : 1;
608 };
609 struct FastMathFlagsTy {
610 char AllowReassoc : 1;
611 char NoNaNs : 1;
612 char NoInfs : 1;
613 char NoSignedZeros : 1;
614 char AllowReciprocal : 1;
615 char AllowContract : 1;
616 char ApproxFunc : 1;
617
618 FastMathFlagsTy(const FastMathFlags &FMF);
619 };
620
621 OperationType OpType;
622
623 union {
627 ExactFlagsTy ExactFlags;
629 NonNegFlagsTy NonNegFlags;
630 FastMathFlagsTy FMFs;
631 unsigned AllFlags;
632 };
633
634protected:
636 OpType = Other.OpType;
637 AllFlags = Other.AllFlags;
638 }
639
640public:
641 template <typename IterT>
642 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, DebugLoc DL = {})
643 : VPSingleDefRecipe(SC, Operands, DL) {
644 OpType = OperationType::Other;
645 AllFlags = 0;
646 }
647
648 template <typename IterT>
649 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, Instruction &I)
651 if (auto *Op = dyn_cast<CmpInst>(&I)) {
652 OpType = OperationType::Cmp;
653 CmpPredicate = Op->getPredicate();
654 } else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
655 OpType = OperationType::DisjointOp;
656 DisjointFlags.IsDisjoint = Op->isDisjoint();
657 } else if (auto *Op = dyn_cast<OverflowingBinaryOperator>(&I)) {
658 OpType = OperationType::OverflowingBinOp;
659 WrapFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
660 } else if (auto *Op = dyn_cast<PossiblyExactOperator>(&I)) {
661 OpType = OperationType::PossiblyExactOp;
662 ExactFlags.IsExact = Op->isExact();
663 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
664 OpType = OperationType::GEPOp;
665 GEPFlags = GEP->getNoWrapFlags();
666 } else if (auto *PNNI = dyn_cast<PossiblyNonNegInst>(&I)) {
667 OpType = OperationType::NonNegOp;
668 NonNegFlags.NonNeg = PNNI->hasNonNeg();
669 } else if (auto *Op = dyn_cast<FPMathOperator>(&I)) {
670 OpType = OperationType::FPMathOp;
671 FMFs = Op->getFastMathFlags();
672 } else {
673 OpType = OperationType::Other;
674 AllFlags = 0;
675 }
676 }
677
678 template <typename IterT>
679 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
680 CmpInst::Predicate Pred, DebugLoc DL = {})
681 : VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::Cmp),
682 CmpPredicate(Pred) {}
683
684 template <typename IterT>
685 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
687 : VPSingleDefRecipe(SC, Operands, DL),
688 OpType(OperationType::OverflowingBinOp), WrapFlags(WrapFlags) {}
689
690 template <typename IterT>
691 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
692 FastMathFlags FMFs, DebugLoc DL = {})
693 : VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::FPMathOp),
694 FMFs(FMFs) {}
695
696 template <typename IterT>
697 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
699 : VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::DisjointOp),
701
702protected:
703 template <typename IterT>
704 VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
706 : VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::GEPOp),
708
709public:
710 static inline bool classof(const VPRecipeBase *R) {
711 return R->getVPDefID() == VPRecipeBase::VPInstructionSC ||
712 R->getVPDefID() == VPRecipeBase::VPWidenSC ||
713 R->getVPDefID() == VPRecipeBase::VPWidenEVLSC ||
714 R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
715 R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
716 R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
717 R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
718 R->getVPDefID() == VPRecipeBase::VPReverseVectorPointerSC ||
719 R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;
720 }
721
722 static inline bool classof(const VPUser *U) {
723 auto *R = dyn_cast<VPRecipeBase>(U);
724 return R && classof(R);
725 }
726
727 /// Drop all poison-generating flags.
729 // NOTE: This needs to be kept in-sync with
730 // Instruction::dropPoisonGeneratingFlags.
731 switch (OpType) {
732 case OperationType::OverflowingBinOp:
733 WrapFlags.HasNUW = false;
734 WrapFlags.HasNSW = false;
735 break;
736 case OperationType::DisjointOp:
738 break;
739 case OperationType::PossiblyExactOp:
740 ExactFlags.IsExact = false;
741 break;
742 case OperationType::GEPOp:
744 break;
745 case OperationType::FPMathOp:
746 FMFs.NoNaNs = false;
747 FMFs.NoInfs = false;
748 break;
749 case OperationType::NonNegOp:
750 NonNegFlags.NonNeg = false;
751 break;
752 case OperationType::Cmp:
753 case OperationType::Other:
754 break;
755 }
756 }
757
758 /// Set the IR flags for \p I.
759 void setFlags(Instruction *I) const {
760 switch (OpType) {
761 case OperationType::OverflowingBinOp:
762 I->setHasNoUnsignedWrap(WrapFlags.HasNUW);
763 I->setHasNoSignedWrap(WrapFlags.HasNSW);
764 break;
765 case OperationType::DisjointOp:
766 cast<PossiblyDisjointInst>(I)->setIsDisjoint(DisjointFlags.IsDisjoint);
767 break;
768 case OperationType::PossiblyExactOp:
769 I->setIsExact(ExactFlags.IsExact);
770 break;
771 case OperationType::GEPOp:
772 cast<GetElementPtrInst>(I)->setNoWrapFlags(GEPFlags);
773 break;
774 case OperationType::FPMathOp:
775 I->setHasAllowReassoc(FMFs.AllowReassoc);
776 I->setHasNoNaNs(FMFs.NoNaNs);
777 I->setHasNoInfs(FMFs.NoInfs);
778 I->setHasNoSignedZeros(FMFs.NoSignedZeros);
779 I->setHasAllowReciprocal(FMFs.AllowReciprocal);
780 I->setHasAllowContract(FMFs.AllowContract);
781 I->setHasApproxFunc(FMFs.ApproxFunc);
782 break;
783 case OperationType::NonNegOp:
784 I->setNonNeg(NonNegFlags.NonNeg);
785 break;
786 case OperationType::Cmp:
787 case OperationType::Other:
788 break;
789 }
790 }
791
793 assert(OpType == OperationType::Cmp &&
794 "recipe doesn't have a compare predicate");
795 return CmpPredicate;
796 }
797
799
800 /// Returns true if the recipe has fast-math flags.
801 bool hasFastMathFlags() const { return OpType == OperationType::FPMathOp; }
802
804
805 bool hasNoUnsignedWrap() const {
806 assert(OpType == OperationType::OverflowingBinOp &&
807 "recipe doesn't have a NUW flag");
808 return WrapFlags.HasNUW;
809 }
810
811 bool hasNoSignedWrap() const {
812 assert(OpType == OperationType::OverflowingBinOp &&
813 "recipe doesn't have a NSW flag");
814 return WrapFlags.HasNSW;
815 }
816
817 bool isDisjoint() const {
818 assert(OpType == OperationType::DisjointOp &&
819 "recipe cannot have a disjoing flag");
821 }
822
823#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
824 void printFlags(raw_ostream &O) const;
825#endif
826};
827
828/// Helper to access the operand that contains the unroll part for this recipe
829/// after unrolling.
830template <unsigned PartOpIdx> class VPUnrollPartAccessor {
831protected:
832 /// Return the VPValue operand containing the unroll part or null if there is
833 /// no such operand.
835
836 /// Return the unroll part.
837 unsigned getUnrollPart(VPUser &U) const;
838};
839
840/// This is a concrete Recipe that models a single VPlan-level instruction.
841/// While as any Recipe it may generate a sequence of IR instructions when
842/// executed, these instructions would always form a single-def expression as
843/// the VPInstruction is also a single def-use vertex.
845 public VPUnrollPartAccessor<1> {
846 friend class VPlanSlp;
847
848public:
849 /// VPlan opcodes, extending LLVM IR with idiomatics instructions.
850 enum {
852 Instruction::OtherOpsEnd + 1, // Combines the incoming and previous
853 // values of a first-order recurrence.
859 /// Creates a scalar phi in a leaf VPBB with a single predecessor in VPlan.
860 /// The first operand is the incoming value from the predecessor in VPlan,
861 /// the second operand is the incoming value for all other predecessors
862 /// (which are currently not modeled in VPlan).
865 // Increment the canonical IV separately for each unrolled part.
870 // Takes the VPValue to extract from as first operand and the lane or part
871 // to extract as second operand, counting from the end starting with 1 for
872 // last. The second operand must be a positive constant and <= VF.
874 LogicalAnd, // Non-poison propagating logical And.
875 // Add an offset in bytes (second operand) to a base pointer (first
876 // operand). Only generates scalar values (either for the first lane only or
877 // for all lanes, depending on its uses).
879 // Returns a scalar boolean value, which is true if any lane of its (only
880 // boolean) vector operand is true.
882 // Extracts the first active lane of a vector, where the first operand is
883 // the predicate, and the second operand is the vector to extract.
885 };
886
887private:
888 typedef unsigned char OpcodeTy;
889 OpcodeTy Opcode;
890
891 /// An optional name that can be used for the generated IR instruction.
892 const std::string Name;
893
894 /// Returns true if this VPInstruction generates scalar values for all lanes.
895 /// Most VPInstructions generate a single value per part, either vector or
896 /// scalar. VPReplicateRecipe takes care of generating multiple (scalar)
897 /// values per all lanes, stemming from an original ingredient. This method
898 /// identifies the (rare) cases of VPInstructions that do so as well, w/o an
899 /// underlying ingredient.
900 bool doesGeneratePerAllLanes() const;
901
902 /// Returns true if we can generate a scalar for the first lane only if
903 /// needed.
904 bool canGenerateScalarForFirstLane() const;
905
906 /// Utility methods serving execute(): generates a single vector instance of
907 /// the modeled instruction. \returns the generated value. . In some cases an
908 /// existing value is returned rather than a generated one.
909 Value *generate(VPTransformState &State);
910
911 /// Utility methods serving execute(): generates a scalar single instance of
912 /// the modeled instruction for a given lane. \returns the scalar generated
913 /// value for lane \p Lane.
914 Value *generatePerLane(VPTransformState &State, const VPLane &Lane);
915
916#if !defined(NDEBUG)
917 /// Return true if the VPInstruction is a floating point math operation, i.e.
918 /// has fast-math flags.
919 bool isFPMathOp() const;
920#endif
921
922public:
924 const Twine &Name = "")
925 : VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, DL),
926 Opcode(Opcode), Name(Name.str()) {}
927
928 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
929 DebugLoc DL = {}, const Twine &Name = "")
931
932 VPInstruction(unsigned Opcode, CmpInst::Predicate Pred, VPValue *A,
933 VPValue *B, DebugLoc DL = {}, const Twine &Name = "");
934
935 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
936 WrapFlagsTy WrapFlags, DebugLoc DL = {}, const Twine &Name = "")
937 : VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, WrapFlags, DL),
938 Opcode(Opcode), Name(Name.str()) {}
939
940 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
941 DisjointFlagsTy DisjointFlag, DebugLoc DL = {},
942 const Twine &Name = "")
943 : VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, DisjointFlag, DL),
944 Opcode(Opcode), Name(Name.str()) {
945 assert(Opcode == Instruction::Or && "only OR opcodes can be disjoint");
946 }
947
949 DebugLoc DL = {}, const Twine &Name = "")
950 : VPRecipeWithIRFlags(VPDef::VPInstructionSC,
951 ArrayRef<VPValue *>({Ptr, Offset}), Flags, DL),
952 Opcode(VPInstruction::PtrAdd), Name(Name.str()) {}
953
954 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands,
955 FastMathFlags FMFs, DebugLoc DL = {}, const Twine &Name = "");
956
957 VP_CLASSOF_IMPL(VPDef::VPInstructionSC)
958
959 VPInstruction *clone() override {
961 auto *New = new VPInstruction(Opcode, Operands, getDebugLoc(), Name);
962 New->transferFlags(*this);
963 return New;
964 }
965
966 unsigned getOpcode() const { return Opcode; }
967
968 /// Generate the instruction.
969 /// TODO: We currently execute only per-part unless a specific instance is
970 /// provided.
971 void execute(VPTransformState &State) override;
972
973 /// Return the cost of this VPInstruction.
975 VPCostContext &Ctx) const override {
976 // TODO: Compute accurate cost after retiring the legacy cost model.
977 return 0;
978 }
979
980#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
981 /// Print the VPInstruction to \p O.
982 void print(raw_ostream &O, const Twine &Indent,
983 VPSlotTracker &SlotTracker) const override;
984
985 /// Print the VPInstruction to dbgs() (for debugging).
986 LLVM_DUMP_METHOD void dump() const;
987#endif
988
989 bool hasResult() const {
990 // CallInst may or may not have a result, depending on the called function.
991 // Conservatively return calls have results for now.
992 switch (getOpcode()) {
993 case Instruction::Ret:
994 case Instruction::Br:
995 case Instruction::Store:
996 case Instruction::Switch:
997 case Instruction::IndirectBr:
998 case Instruction::Resume:
999 case Instruction::CatchRet:
1000 case Instruction::Unreachable:
1001 case Instruction::Fence:
1002 case Instruction::AtomicRMW:
1005 return false;
1006 default:
1007 return true;
1008 }
1009 }
1010
1011 /// Returns true if the underlying opcode may read from or write to memory.
1012 bool opcodeMayReadOrWriteFromMemory() const;
1013
1014 /// Returns true if the recipe only uses the first lane of operand \p Op.
1015 bool onlyFirstLaneUsed(const VPValue *Op) const override;
1016
1017 /// Returns true if the recipe only uses the first part of operand \p Op.
1018 bool onlyFirstPartUsed(const VPValue *Op) const override;
1019
1020 /// Returns true if this VPInstruction produces a scalar value from a vector,
1021 /// e.g. by performing a reduction or extracting a lane.
1022 bool isVectorToScalar() const;
1023
1024 /// Returns true if this VPInstruction's operands are single scalars and the
1025 /// result is also a single scalar.
1026 bool isSingleScalar() const;
1027
1028 /// Returns the symbolic name assigned to the VPInstruction.
1029 StringRef getName() const { return Name; }
1030};
1031
1032/// A recipe to wrap on original IR instruction not to be modified during
1033/// execution, execept for PHIs. For PHIs, a single VPValue operand is allowed,
1034/// and it is used to add a new incoming value for the single predecessor VPBB.
1035/// Expect PHIs, VPIRInstructions cannot have any operands.
1037 Instruction &I;
1038
1039public:
1041 : VPRecipeBase(VPDef::VPIRInstructionSC, ArrayRef<VPValue *>()), I(I) {}
1042
1043 ~VPIRInstruction() override = default;
1044
1045 VP_CLASSOF_IMPL(VPDef::VPIRInstructionSC)
1046
1048 auto *R = new VPIRInstruction(I);
1049 for (auto *Op : operands())
1050 R->addOperand(Op);
1051 return R;
1052 }
1053
1054 void execute(VPTransformState &State) override;
1055
1056 /// Return the cost of this VPIRInstruction.
1058 VPCostContext &Ctx) const override;
1059
1060 Instruction &getInstruction() const { return I; }
1061
1062#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1063 /// Print the recipe.
1064 void print(raw_ostream &O, const Twine &Indent,
1065 VPSlotTracker &SlotTracker) const override;
1066#endif
1067
1068 bool usesScalars(const VPValue *Op) const override {
1070 "Op must be an operand of the recipe");
1071 return true;
1072 }
1073
1074 bool onlyFirstPartUsed(const VPValue *Op) const override {
1076 "Op must be an operand of the recipe");
1077 return true;
1078 }
1079
1080 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1082 "Op must be an operand of the recipe");
1083 return true;
1084 }
1085
1086 /// Update the recipes single operand to the last lane of the operand using \p
1087 /// Builder. Must only be used for single operand VPIRInstructions wrapping a
1088 /// PHINode.
1089 void extractLastLaneOfOperand(VPBuilder &Builder);
1090};
1091
1092/// VPWidenRecipe is a recipe for producing a widened instruction using the
1093/// opcode and operands of the recipe. This recipe covers most of the
1094/// traditional vectorization cases where each recipe transforms into a
1095/// vectorized version of itself.
1097 unsigned Opcode;
1098
1099protected:
1100 template <typename IterT>
1101 VPWidenRecipe(unsigned VPDefOpcode, Instruction &I,
1103 : VPRecipeWithIRFlags(VPDefOpcode, Operands, I), Opcode(I.getOpcode()) {}
1104
1105public:
1106 template <typename IterT>
1108 : VPWidenRecipe(VPDef::VPWidenSC, I, Operands) {}
1109
1110 ~VPWidenRecipe() override = default;
1111
1112 VPWidenRecipe *clone() override {
1113 auto *R = new VPWidenRecipe(*getUnderlyingInstr(), operands());
1114 R->transferFlags(*this);
1115 return R;
1116 }
1117
1118 static inline bool classof(const VPRecipeBase *R) {
1119 return R->getVPDefID() == VPRecipeBase::VPWidenSC ||
1120 R->getVPDefID() == VPRecipeBase::VPWidenEVLSC;
1121 }
1122
1123 static inline bool classof(const VPUser *U) {
1124 auto *R = dyn_cast<VPRecipeBase>(U);
1125 return R && classof(R);
1126 }
1127
1128 /// Produce a widened instruction using the opcode and operands of the recipe,
1129 /// processing State.VF elements.
1130 void execute(VPTransformState &State) override;
1131
1132 /// Return the cost of this VPWidenRecipe.
1134 VPCostContext &Ctx) const override;
1135
1136 unsigned getOpcode() const { return Opcode; }
1137
1138#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1139 /// Print the recipe.
1140 void print(raw_ostream &O, const Twine &Indent,
1141 VPSlotTracker &SlotTracker) const override;
1142#endif
1143};
1144
1145/// A recipe for widening operations with vector-predication intrinsics with
1146/// explicit vector length (EVL).
1149
1150public:
1151 template <typename IterT>
1153 : VPWidenRecipe(VPDef::VPWidenEVLSC, I, Operands) {
1154 addOperand(&EVL);
1155 }
1157 : VPWidenEVLRecipe(*W.getUnderlyingInstr(), W.operands(), EVL) {
1158 transferFlags(W);
1159 }
1160
1161 ~VPWidenEVLRecipe() override = default;
1162
1163 VPWidenRecipe *clone() override final {
1164 llvm_unreachable("VPWidenEVLRecipe cannot be cloned");
1165 return nullptr;
1166 }
1167
1168 VP_CLASSOF_IMPL(VPDef::VPWidenEVLSC);
1169
1171 const VPValue *getEVL() const { return getOperand(getNumOperands() - 1); }
1172
1173 /// Produce a vp-intrinsic using the opcode and operands of the recipe,
1174 /// processing EVL elements.
1175 void execute(VPTransformState &State) override final;
1176
1177 /// Returns true if the recipe only uses the first lane of operand \p Op.
1178 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1180 "Op must be an operand of the recipe");
1181 // EVL in that recipe is always the last operand, thus any use before means
1182 // the VPValue should be vectorized.
1183 return getEVL() == Op;
1184 }
1185
1186#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1187 /// Print the recipe.
1188 void print(raw_ostream &O, const Twine &Indent,
1189 VPSlotTracker &SlotTracker) const override final;
1190#endif
1191};
1192
1193/// VPWidenCastRecipe is a recipe to create vector cast instructions.
1195 /// Cast instruction opcode.
1196 Instruction::CastOps Opcode;
1197
1198 /// Result type for the cast.
1199 Type *ResultTy;
1200
1201public:
1203 CastInst &UI)
1204 : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, UI), Opcode(Opcode),
1205 ResultTy(ResultTy) {
1206 assert(UI.getOpcode() == Opcode &&
1207 "opcode of underlying cast doesn't match");
1208 }
1209
1211 : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op), Opcode(Opcode),
1212 ResultTy(ResultTy) {}
1213
1214 ~VPWidenCastRecipe() override = default;
1215
1217 if (auto *UV = getUnderlyingValue())
1218 return new VPWidenCastRecipe(Opcode, getOperand(0), ResultTy,
1219 *cast<CastInst>(UV));
1220
1221 return new VPWidenCastRecipe(Opcode, getOperand(0), ResultTy);
1222 }
1223
1224 VP_CLASSOF_IMPL(VPDef::VPWidenCastSC)
1225
1226 /// Produce widened copies of the cast.
1227 void execute(VPTransformState &State) override;
1228
1229 /// Return the cost of this VPWidenCastRecipe.
1231 VPCostContext &Ctx) const override;
1232
1233#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1234 /// Print the recipe.
1235 void print(raw_ostream &O, const Twine &Indent,
1236 VPSlotTracker &SlotTracker) const override;
1237#endif
1238
1239 Instruction::CastOps getOpcode() const { return Opcode; }
1240
1241 /// Returns the result type of the cast.
1242 Type *getResultType() const { return ResultTy; }
1243};
1244
1245/// VPScalarCastRecipe is a recipe to create scalar cast instructions.
1247 Instruction::CastOps Opcode;
1248
1249 Type *ResultTy;
1250
1251 Value *generate(VPTransformState &State);
1252
1253public:
1255 DebugLoc DL)
1256 : VPSingleDefRecipe(VPDef::VPScalarCastSC, {Op}, DL), Opcode(Opcode),
1257 ResultTy(ResultTy) {}
1258
1259 ~VPScalarCastRecipe() override = default;
1260
1262 return new VPScalarCastRecipe(Opcode, getOperand(0), ResultTy,
1263 getDebugLoc());
1264 }
1265
1266 VP_CLASSOF_IMPL(VPDef::VPScalarCastSC)
1267
1268 void execute(VPTransformState &State) override;
1269
1270 /// Return the cost of this VPScalarCastRecipe.
1272 VPCostContext &Ctx) const override {
1273 // TODO: Compute accurate cost after retiring the legacy cost model.
1274 return 0;
1275 }
1276
1277#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1278 void print(raw_ostream &O, const Twine &Indent,
1279 VPSlotTracker &SlotTracker) const override;
1280#endif
1281
1282 /// Returns the result type of the cast.
1283 Type *getResultType() const { return ResultTy; }
1284
1285 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1286 // At the moment, only uniform codegen is implemented.
1288 "Op must be an operand of the recipe");
1289 return true;
1290 }
1291};
1292
1293/// A recipe for widening vector intrinsics.
1295 /// ID of the vector intrinsic to widen.
1296 Intrinsic::ID VectorIntrinsicID;
1297
1298 /// Scalar return type of the intrinsic.
1299 Type *ResultTy;
1300
1301 /// True if the intrinsic may read from memory.
1302 bool MayReadFromMemory;
1303
1304 /// True if the intrinsic may read write to memory.
1305 bool MayWriteToMemory;
1306
1307 /// True if the intrinsic may have side-effects.
1308 bool MayHaveSideEffects;
1309
1310public:
1312 ArrayRef<VPValue *> CallArguments, Type *Ty,
1313 DebugLoc DL = {})
1314 : VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, CI),
1315 VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
1316 MayReadFromMemory(CI.mayReadFromMemory()),
1317 MayWriteToMemory(CI.mayWriteToMemory()),
1318 MayHaveSideEffects(CI.mayHaveSideEffects()) {}
1319
1321 ArrayRef<VPValue *> CallArguments, Type *Ty,
1322 DebugLoc DL = {})
1323 : VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, DL),
1324 VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
1325 LLVMContext &Ctx = Ty->getContext();
1326 AttributeList Attrs = Intrinsic::getAttributes(Ctx, VectorIntrinsicID);
1327 MemoryEffects ME = Attrs.getMemoryEffects();
1328 MayReadFromMemory = ME.onlyWritesMemory();
1329 MayWriteToMemory = ME.onlyReadsMemory();
1330 MayHaveSideEffects = MayWriteToMemory ||
1331 !Attrs.hasFnAttr(Attribute::NoUnwind) ||
1332 !Attrs.hasFnAttr(Attribute::WillReturn);
1333 }
1334
1336 std::initializer_list<VPValue *> CallArguments,
1337 Type *Ty, DebugLoc DL = {})
1338 : VPWidenIntrinsicRecipe(VectorIntrinsicID,
1339 ArrayRef<VPValue *>(CallArguments), Ty, DL) {}
1340
1341 ~VPWidenIntrinsicRecipe() override = default;
1342
1344 return new VPWidenIntrinsicRecipe(*cast<CallInst>(getUnderlyingValue()),
1345 VectorIntrinsicID, {op_begin(), op_end()},
1346 ResultTy, getDebugLoc());
1347 }
1348
1349 VP_CLASSOF_IMPL(VPDef::VPWidenIntrinsicSC)
1350
1351 /// Produce a widened version of the vector intrinsic.
1352 void execute(VPTransformState &State) override;
1353
1354 /// Return the cost of this vector intrinsic.
1356 VPCostContext &Ctx) const override;
1357
1358 /// Return the ID of the intrinsic.
1359 Intrinsic::ID getVectorIntrinsicID() const { return VectorIntrinsicID; }
1360
1361 /// Return the scalar return type of the intrinsic.
1362 Type *getResultType() const { return ResultTy; }
1363
1364 /// Return to name of the intrinsic as string.
1366
1367 /// Returns true if the intrinsic may read from memory.
1368 bool mayReadFromMemory() const { return MayReadFromMemory; }
1369
1370 /// Returns true if the intrinsic may write to memory.
1371 bool mayWriteToMemory() const { return MayWriteToMemory; }
1372
1373 /// Returns true if the intrinsic may have side-effects.
1374 bool mayHaveSideEffects() const { return MayHaveSideEffects; }
1375
1376#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1377 /// Print the recipe.
1378 void print(raw_ostream &O, const Twine &Indent,
1379 VPSlotTracker &SlotTracker) const override;
1380#endif
1381
1382 bool onlyFirstLaneUsed(const VPValue *Op) const override;
1383};
1384
1385/// A recipe for widening Call instructions using library calls.
1387 /// Variant stores a pointer to the chosen function. There is a 1:1 mapping
1388 /// between a given VF and the chosen vectorized variant, so there will be a
1389 /// different VPlan for each VF with a valid variant.
1390 Function *Variant;
1391
1392public:
1394 ArrayRef<VPValue *> CallArguments, DebugLoc DL = {})
1395 : VPRecipeWithIRFlags(VPDef::VPWidenCallSC, CallArguments,
1396 *cast<Instruction>(UV)),
1397 Variant(Variant) {
1398 assert(
1399 isa<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue()) &&
1400 "last operand must be the called function");
1401 }
1402
1403 ~VPWidenCallRecipe() override = default;
1404
1406 return new VPWidenCallRecipe(getUnderlyingValue(), Variant,
1407 {op_begin(), op_end()}, getDebugLoc());
1408 }
1409
1410 VP_CLASSOF_IMPL(VPDef::VPWidenCallSC)
1411
1412 /// Produce a widened version of the call instruction.
1413 void execute(VPTransformState &State) override;
1414
1415 /// Return the cost of this VPWidenCallRecipe.
1417 VPCostContext &Ctx) const override;
1418
1420 return cast<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue());
1421 }
1422
1424 return make_range(op_begin(), op_begin() + getNumOperands() - 1);
1425 }
1427 return make_range(op_begin(), op_begin() + getNumOperands() - 1);
1428 }
1429
1430#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1431 /// Print the recipe.
1432 void print(raw_ostream &O, const Twine &Indent,
1433 VPSlotTracker &SlotTracker) const override;
1434#endif
1435};
1436
1437/// A recipe representing a sequence of load -> update -> store as part of
1438/// a histogram operation. This means there may be aliasing between vector
1439/// lanes, which is handled by the llvm.experimental.vector.histogram family
1440/// of intrinsics. The only update operations currently supported are
1441/// 'add' and 'sub' where the other term is loop-invariant.
1443 /// Opcode of the update operation, currently either add or sub.
1444 unsigned Opcode;
1445
1446public:
1447 template <typename IterT>
1448 VPHistogramRecipe(unsigned Opcode, iterator_range<IterT> Operands,
1449 DebugLoc DL = {})
1450 : VPRecipeBase(VPDef::VPHistogramSC, Operands, DL), Opcode(Opcode) {}
1451
1452 ~VPHistogramRecipe() override = default;
1453
1455 return new VPHistogramRecipe(Opcode, operands(), getDebugLoc());
1456 }
1457
1458 VP_CLASSOF_IMPL(VPDef::VPHistogramSC);
1459
1460 /// Produce a vectorized histogram operation.
1461 void execute(VPTransformState &State) override;
1462
1463 /// Return the cost of this VPHistogramRecipe.
1465 VPCostContext &Ctx) const override;
1466
1467 unsigned getOpcode() const { return Opcode; }
1468
1469 /// Return the mask operand if one was provided, or a null pointer if all
1470 /// lanes should be executed unconditionally.
1471 VPValue *getMask() const {
1472 return getNumOperands() == 3 ? getOperand(2) : nullptr;
1473 }
1474
1475#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1476 /// Print the recipe
1477 void print(raw_ostream &O, const Twine &Indent,
1478 VPSlotTracker &SlotTracker) const override;
1479#endif
1480};
1481
1482/// A recipe for widening select instructions.
1484 template <typename IterT>
1486 : VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I) {}
1487
1488 ~VPWidenSelectRecipe() override = default;
1489
1491 return new VPWidenSelectRecipe(*cast<SelectInst>(getUnderlyingInstr()),
1492 operands());
1493 }
1494
1495 VP_CLASSOF_IMPL(VPDef::VPWidenSelectSC)
1496
1497 /// Produce a widened version of the select instruction.
1498 void execute(VPTransformState &State) override;
1499
1500 /// Return the cost of this VPWidenSelectRecipe.
1502 VPCostContext &Ctx) const override;
1503
1504#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1505 /// Print the recipe.
1506 void print(raw_ostream &O, const Twine &Indent,
1507 VPSlotTracker &SlotTracker) const override;
1508#endif
1509
1510 VPValue *getCond() const {
1511 return getOperand(0);
1512 }
1513
1514 bool isInvariantCond() const {
1516 }
1517};
1518
1519/// A recipe for handling GEP instructions.
1521 bool isPointerLoopInvariant() const {
1523 }
1524
1525 bool isIndexLoopInvariant(unsigned I) const {
1527 }
1528
1529 bool areAllOperandsInvariant() const {
1530 return all_of(operands(), [](VPValue *Op) {
1531 return Op->isDefinedOutsideLoopRegions();
1532 });
1533 }
1534
1535public:
1536 template <typename IterT>
1538 : VPRecipeWithIRFlags(VPDef::VPWidenGEPSC, Operands, *GEP) {}
1539
1540 ~VPWidenGEPRecipe() override = default;
1541
1543 return new VPWidenGEPRecipe(cast<GetElementPtrInst>(getUnderlyingInstr()),
1544 operands());
1545 }
1546
1547 VP_CLASSOF_IMPL(VPDef::VPWidenGEPSC)
1548
1549 /// Generate the gep nodes.
1550 void execute(VPTransformState &State) override;
1551
1552 /// Return the cost of this VPWidenGEPRecipe.
1554 VPCostContext &Ctx) const override {
1555 // TODO: Compute accurate cost after retiring the legacy cost model.
1556 return 0;
1557 }
1558
1559#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1560 /// Print the recipe.
1561 void print(raw_ostream &O, const Twine &Indent,
1562 VPSlotTracker &SlotTracker) const override;
1563#endif
1564};
1565
1566/// A recipe to compute the pointers for widened memory accesses of IndexTy
1567/// in reverse order.
1569 public VPUnrollPartAccessor<2> {
1570 Type *IndexedTy;
1571
1572public:
1575 : VPRecipeWithIRFlags(VPDef::VPReverseVectorPointerSC,
1576 ArrayRef<VPValue *>({Ptr, VF}), GEPFlags, DL),
1577 IndexedTy(IndexedTy) {}
1578
1579 VP_CLASSOF_IMPL(VPDef::VPReverseVectorPointerSC)
1580
1582 const VPValue *getVFValue() const { return getOperand(1); }
1583
1584 void execute(VPTransformState &State) override;
1585
1586 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1588 "Op must be an operand of the recipe");
1589 return true;
1590 }
1591
1592 /// Return the cost of this VPVectorPointerRecipe.
1594 VPCostContext &Ctx) const override {
1595 // TODO: Compute accurate cost after retiring the legacy cost model.
1596 return 0;
1597 }
1598
1599 /// Returns true if the recipe only uses the first part of operand \p Op.
1600 bool onlyFirstPartUsed(const VPValue *Op) const override {
1602 "Op must be an operand of the recipe");
1603 assert(getNumOperands() <= 2 && "must have at most two operands");
1604 return true;
1605 }
1606
1609 IndexedTy, getGEPNoWrapFlags(),
1610 getDebugLoc());
1611 }
1612
1613#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1614 /// Print the recipe.
1615 void print(raw_ostream &O, const Twine &Indent,
1616 VPSlotTracker &SlotTracker) const override;
1617#endif
1618};
1619
1620/// A recipe to compute the pointers for widened memory accesses of IndexTy.
1622 public VPUnrollPartAccessor<1> {
1623 Type *IndexedTy;
1624
1625public:
1627 DebugLoc DL)
1628 : VPRecipeWithIRFlags(VPDef::VPVectorPointerSC, ArrayRef<VPValue *>(Ptr),
1629 GEPFlags, DL),
1630 IndexedTy(IndexedTy) {}
1631
1632 VP_CLASSOF_IMPL(VPDef::VPVectorPointerSC)
1633
1634 void execute(VPTransformState &State) override;
1635
1636 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1638 "Op must be an operand of the recipe");
1639 return true;
1640 }
1641
1642 /// Returns true if the recipe only uses the first part of operand \p Op.
1643 bool onlyFirstPartUsed(const VPValue *Op) const override {
1645 "Op must be an operand of the recipe");
1646 assert(getNumOperands() <= 2 && "must have at most two operands");
1647 return true;
1648 }
1649
1651 return new VPVectorPointerRecipe(getOperand(0), IndexedTy,
1653 }
1654
1655 /// Return the cost of this VPHeaderPHIRecipe.
1657 VPCostContext &Ctx) const override {
1658 // TODO: Compute accurate cost after retiring the legacy cost model.
1659 return 0;
1660 }
1661
1662#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1663 /// Print the recipe.
1664 void print(raw_ostream &O, const Twine &Indent,
1665 VPSlotTracker &SlotTracker) const override;
1666#endif
1667};
1668
1669/// A pure virtual base class for all recipes modeling header phis, including
1670/// phis for first order recurrences, pointer inductions and reductions. The
1671/// start value is the first operand of the recipe and the incoming value from
1672/// the backedge is the second operand.
1673///
1674/// Inductions are modeled using the following sub-classes:
1675/// * VPCanonicalIVPHIRecipe: Canonical scalar induction of the vector loop,
1676/// starting at a specified value (zero for the main vector loop, the resume
1677/// value for the epilogue vector loop) and stepping by 1. The induction
1678/// controls exiting of the vector loop by comparing against the vector trip
1679/// count. Produces a single scalar PHI for the induction value per
1680/// iteration.
1681/// * VPWidenIntOrFpInductionRecipe: Generates vector values for integer and
1682/// floating point inductions with arbitrary start and step values. Produces
1683/// a vector PHI per-part.
1684/// * VPDerivedIVRecipe: Converts the canonical IV value to the corresponding
1685/// value of an IV with different start and step values. Produces a single
1686/// scalar value per iteration
1687/// * VPScalarIVStepsRecipe: Generates scalar values per-lane based on a
1688/// canonical or derived induction.
1689/// * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
1690/// pointer induction. Produces either a vector PHI per-part or scalar values
1691/// per-lane based on the canonical induction.
1693protected:
1694 VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr,
1695 VPValue *Start = nullptr, DebugLoc DL = {})
1696 : VPSingleDefRecipe(VPDefID, ArrayRef<VPValue *>(), UnderlyingInstr, DL) {
1697 if (Start)
1698 addOperand(Start);
1699 }
1700
1701public:
1702 ~VPHeaderPHIRecipe() override = default;
1703
1704 /// Method to support type inquiry through isa, cast, and dyn_cast.
1705 static inline bool classof(const VPRecipeBase *B) {
1706 return B->getVPDefID() >= VPDef::VPFirstHeaderPHISC &&
1707 B->getVPDefID() <= VPDef::VPLastHeaderPHISC;
1708 }
1709 static inline bool classof(const VPValue *V) {
1710 auto *B = V->getDefiningRecipe();
1711 return B && B->getVPDefID() >= VPRecipeBase::VPFirstHeaderPHISC &&
1712 B->getVPDefID() <= VPRecipeBase::VPLastHeaderPHISC;
1713 }
1714
1715 /// Generate the phi nodes.
1716 void execute(VPTransformState &State) override = 0;
1717
1718 /// Return the cost of this header phi recipe.
1720 VPCostContext &Ctx) const override;
1721
1722#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1723 /// Print the recipe.
1724 void print(raw_ostream &O, const Twine &Indent,
1725 VPSlotTracker &SlotTracker) const override = 0;
1726#endif
1727
1728 /// Returns the start value of the phi, if one is set.
1730 return getNumOperands() == 0 ? nullptr : getOperand(0);
1731 }
1733 return getNumOperands() == 0 ? nullptr : getOperand(0);
1734 }
1735
1736 /// Update the start value of the recipe.
1738
1739 /// Returns the incoming value from the loop backedge.
1741 return getOperand(1);
1742 }
1743
1744 /// Returns the backedge value as a recipe. The backedge value is guaranteed
1745 /// to be a recipe.
1748 }
1749};
1750
1751/// Base class for widened induction (VPWidenIntOrFpInductionRecipe and
1752/// VPWidenPointerInductionRecipe), providing shared functionality, including
1753/// retrieving the step value, induction descriptor and original phi node.
1755 const InductionDescriptor &IndDesc;
1756
1757public:
1758 VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start,
1759 VPValue *Step, const InductionDescriptor &IndDesc,
1760 DebugLoc DL)
1761 : VPHeaderPHIRecipe(Kind, IV, Start, DL), IndDesc(IndDesc) {
1762 addOperand(Step);
1763 }
1764
1765 static inline bool classof(const VPRecipeBase *R) {
1766 return R->getVPDefID() == VPDef::VPWidenIntOrFpInductionSC ||
1767 R->getVPDefID() == VPDef::VPWidenPointerInductionSC;
1768 }
1769
1770 static inline bool classof(const VPValue *V) {
1771 auto *R = V->getDefiningRecipe();
1772 return R && classof(R);
1773 }
1774
1775 static inline bool classof(const VPHeaderPHIRecipe *R) {
1776 return classof(static_cast<const VPRecipeBase *>(R));
1777 }
1778
1779 virtual void execute(VPTransformState &State) override = 0;
1780
1781 /// Returns the step value of the induction.
1783 const VPValue *getStepValue() const { return getOperand(1); }
1784
1785 PHINode *getPHINode() const { return cast<PHINode>(getUnderlyingValue()); }
1786
1787 /// Returns the induction descriptor for the recipe.
1788 const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
1789
1791 // TODO: All operands of base recipe must exist and be at same index in
1792 // derived recipe.
1794 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
1795 }
1796
1798 // TODO: All operands of base recipe must exist and be at same index in
1799 // derived recipe.
1801 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
1802 }
1803};
1804
1805/// A recipe for handling phi nodes of integer and floating-point inductions,
1806/// producing their vector values.
1808 TruncInst *Trunc;
1809
1810public:
1812 VPValue *VF, const InductionDescriptor &IndDesc,
1813 DebugLoc DL)
1814 : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
1815 Step, IndDesc, DL),
1816 Trunc(nullptr) {
1817 addOperand(VF);
1818 }
1819
1821 VPValue *VF, const InductionDescriptor &IndDesc,
1822 TruncInst *Trunc, DebugLoc DL)
1823 : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
1824 Step, IndDesc, DL),
1825 Trunc(Trunc) {
1826 addOperand(VF);
1827 }
1828
1830
1835 }
1836
1837 VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)
1838
1839 /// Generate the vectorized and scalarized versions of the phi node as
1840 /// needed by their users.
1841 void execute(VPTransformState &State) override;
1842
1843#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1844 /// Print the recipe.
1845 void print(raw_ostream &O, const Twine &Indent,
1846 VPSlotTracker &SlotTracker) const override;
1847#endif
1848
1850 const VPValue *getVFValue() const { return getOperand(2); }
1851
1853 // If the recipe has been unrolled (4 operands), return the VPValue for the
1854 // induction increment.
1855 return getNumOperands() == 5 ? getOperand(3) : nullptr;
1856 }
1857
1858 /// Returns the first defined value as TruncInst, if it is one or nullptr
1859 /// otherwise.
1860 TruncInst *getTruncInst() { return Trunc; }
1861 const TruncInst *getTruncInst() const { return Trunc; }
1862
1863 /// Returns true if the induction is canonical, i.e. starting at 0 and
1864 /// incremented by UF * VF (= the original IV is incremented by 1) and has the
1865 /// same type as the canonical induction.
1866 bool isCanonical() const;
1867
1868 /// Returns the scalar type of the induction.
1870 return Trunc ? Trunc->getType() : getPHINode()->getType();
1871 }
1872
1873 /// Returns the VPValue representing the value of this induction at
1874 /// the last unrolled part, if it exists. Returns itself if unrolling did not
1875 /// take place.
1877 return getNumOperands() == 5 ? getOperand(4) : this;
1878 }
1879};
1880
1882 public VPUnrollPartAccessor<3> {
1883 bool IsScalarAfterVectorization;
1884
1885public:
1886 /// Create a new VPWidenPointerInductionRecipe for \p Phi with start value \p
1887 /// Start.
1889 const InductionDescriptor &IndDesc,
1890 bool IsScalarAfterVectorization, DebugLoc DL)
1891 : VPWidenInductionRecipe(VPDef::VPWidenPointerInductionSC, Phi, Start,
1892 Step, IndDesc, DL),
1893 IsScalarAfterVectorization(IsScalarAfterVectorization) {}
1894
1896
1899 cast<PHINode>(getUnderlyingInstr()), getOperand(0), getOperand(1),
1900 getInductionDescriptor(), IsScalarAfterVectorization, getDebugLoc());
1901 }
1902
1903 VP_CLASSOF_IMPL(VPDef::VPWidenPointerInductionSC)
1904
1905 /// Generate vector values for the pointer induction.
1906 void execute(VPTransformState &State) override;
1907
1908 /// Returns true if only scalar values will be generated.
1909 bool onlyScalarsGenerated(bool IsScalable);
1910
1911 /// Returns the VPValue representing the value of this induction at
1912 /// the first unrolled part, if it exists. Returns itself if unrolling did not
1913 /// take place.
1915 return getUnrollPart(*this) == 0 ? this : getOperand(2);
1916 }
1917
1918#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1919 /// Print the recipe.
1920 void print(raw_ostream &O, const Twine &Indent,
1921 VPSlotTracker &SlotTracker) const override;
1922#endif
1923};
1924
1925/// Recipe to generate a scalar PHI. Used to generate code for recipes that
1926/// produce scalar header phis, including VPCanonicalIVPHIRecipe and
1927/// VPEVLBasedIVPHIRecipe.
1929 std::string Name;
1930
1931public:
1932 VPScalarPHIRecipe(VPValue *Start, VPValue *BackedgeValue, DebugLoc DL,
1933 StringRef Name)
1934 : VPHeaderPHIRecipe(VPDef::VPScalarPHISC, nullptr, Start, DL),
1935 Name(Name.str()) {
1936 addOperand(BackedgeValue);
1937 }
1938
1939 ~VPScalarPHIRecipe() override = default;
1940
1942 llvm_unreachable("cloning not implemented yet");
1943 }
1944
1945 VP_CLASSOF_IMPL(VPDef::VPScalarPHISC)
1946
1947 /// Generate the phi/select nodes.
1948 void execute(VPTransformState &State) override;
1949
1950 /// Returns true if the recipe only uses the first lane of operand \p Op.
1951 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1953 "Op must be an operand of the recipe");
1954 return true;
1955 }
1956
1957#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1958 /// Print the recipe.
1959 void print(raw_ostream &O, const Twine &Indent,
1960 VPSlotTracker &SlotTracker) const override;
1961#endif
1962};
1963
1964/// A recipe for handling phis that are widened in the vector loop.
1965/// In the VPlan native path, all incoming VPValues & VPBasicBlock pairs are
1966/// managed in the recipe directly.
1968 /// List of incoming blocks. Only used in the VPlan native path.
1969 SmallVector<VPBasicBlock *, 2> IncomingBlocks;
1970
1971public:
1972 /// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
1973 /// debug location \p DL.
1974 VPWidenPHIRecipe(PHINode *Phi, VPValue *Start = nullptr, DebugLoc DL = {})
1975 : VPSingleDefRecipe(VPDef::VPWidenPHISC, ArrayRef<VPValue *>(), Phi, DL) {
1976 if (Start)
1977 addOperand(Start);
1978 }
1979
1981 llvm_unreachable("cloning not implemented yet");
1982 }
1983
1984 ~VPWidenPHIRecipe() override = default;
1985
1986 VP_CLASSOF_IMPL(VPDef::VPWidenPHISC)
1987
1988 /// Generate the phi/select nodes.
1989 void execute(VPTransformState &State) override;
1990
1991#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1992 /// Print the recipe.
1993 void print(raw_ostream &O, const Twine &Indent,
1994 VPSlotTracker &SlotTracker) const override;
1995#endif
1996
1997 /// Adds a pair (\p IncomingV, \p IncomingBlock) to the phi.
1998 void addIncoming(VPValue *IncomingV, VPBasicBlock *IncomingBlock) {
1999 addOperand(IncomingV);
2000 IncomingBlocks.push_back(IncomingBlock);
2001 }
2002
2003 /// Returns the \p I th incoming VPBasicBlock.
2004 VPBasicBlock *getIncomingBlock(unsigned I) { return IncomingBlocks[I]; }
2005
2006 /// Returns the \p I th incoming VPValue.
2007 VPValue *getIncomingValue(unsigned I) { return getOperand(I); }
2008};
2009
2010/// A recipe for handling first-order recurrence phis. The start value is the
2011/// first operand of the recipe and the incoming value from the backedge is the
2012/// second operand.
2015 : VPHeaderPHIRecipe(VPDef::VPFirstOrderRecurrencePHISC, Phi, &Start) {}
2016
2017 VP_CLASSOF_IMPL(VPDef::VPFirstOrderRecurrencePHISC)
2018
2020 return R->getVPDefID() == VPDef::VPFirstOrderRecurrencePHISC;
2021 }
2022
2025 cast<PHINode>(getUnderlyingInstr()), *getOperand(0));
2026 }
2027
2028 void execute(VPTransformState &State) override;
2029
2030 /// Return the cost of this first-order recurrence phi recipe.
2032 VPCostContext &Ctx) const override;
2033
2034#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2035 /// Print the recipe.
2036 void print(raw_ostream &O, const Twine &Indent,
2037 VPSlotTracker &SlotTracker) const override;
2038#endif
2039};
2040
2041/// A recipe for handling reduction phis. The start value is the first operand
2042/// of the recipe and the incoming value from the backedge is the second
2043/// operand.
2045 public VPUnrollPartAccessor<2> {
2046 /// Descriptor for the reduction.
2047 const RecurrenceDescriptor &RdxDesc;
2048
2049 /// The phi is part of an in-loop reduction.
2050 bool IsInLoop;
2051
2052 /// The phi is part of an ordered reduction. Requires IsInLoop to be true.
2053 bool IsOrdered;
2054
2055 /// When expanding the reduction PHI, the plan's VF element count is divided
2056 /// by this factor to form the reduction phi's VF.
2057 unsigned VFScaleFactor = 1;
2058
2059public:
2060 /// Create a new VPReductionPHIRecipe for the reduction \p Phi described by \p
2061 /// RdxDesc.
2063 VPValue &Start, bool IsInLoop = false,
2064 bool IsOrdered = false, unsigned VFScaleFactor = 1)
2065 : VPHeaderPHIRecipe(VPDef::VPReductionPHISC, Phi, &Start),
2066 RdxDesc(RdxDesc), IsInLoop(IsInLoop), IsOrdered(IsOrdered),
2067 VFScaleFactor(VFScaleFactor) {
2068 assert((!IsOrdered || IsInLoop) && "IsOrdered requires IsInLoop");
2069 }
2070
2071 ~VPReductionPHIRecipe() override = default;
2072
2074 auto *R = new VPReductionPHIRecipe(cast<PHINode>(getUnderlyingInstr()),
2075 RdxDesc, *getOperand(0), IsInLoop,
2076 IsOrdered, VFScaleFactor);
2077 R->addOperand(getBackedgeValue());
2078 return R;
2079 }
2080
2081 VP_CLASSOF_IMPL(VPDef::VPReductionPHISC)
2082
2084 return R->getVPDefID() == VPDef::VPReductionPHISC;
2085 }
2086
2087 /// Generate the phi/select nodes.
2088 void execute(VPTransformState &State) override;
2089
2090#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2091 /// Print the recipe.
2092 void print(raw_ostream &O, const Twine &Indent,
2093 VPSlotTracker &SlotTracker) const override;
2094#endif
2095
2097 return RdxDesc;
2098 }
2099
2100 /// Returns true, if the phi is part of an ordered reduction.
2101 bool isOrdered() const { return IsOrdered; }
2102
2103 /// Returns true, if the phi is part of an in-loop reduction.
2104 bool isInLoop() const { return IsInLoop; }
2105};
2106
2107/// A recipe for forming partial reductions. In the loop, an accumulator and
2108/// vector operand are added together and passed to the next iteration as the
2109/// next accumulator. After the loop body, the accumulator is reduced to a
2110/// scalar value.
2112 unsigned Opcode;
2113
2114public:
2116 VPValue *Op1)
2117 : VPPartialReductionRecipe(ReductionInst->getOpcode(), Op0, Op1,
2118 ReductionInst) {}
2119 VPPartialReductionRecipe(unsigned Opcode, VPValue *Op0, VPValue *Op1,
2120 Instruction *ReductionInst = nullptr)
2121 : VPSingleDefRecipe(VPDef::VPPartialReductionSC,
2122 ArrayRef<VPValue *>({Op0, Op1}), ReductionInst),
2123 Opcode(Opcode) {
2124 [[maybe_unused]] auto *AccumulatorRecipe =
2126 assert((isa<VPReductionPHIRecipe>(AccumulatorRecipe) ||
2127 isa<VPPartialReductionRecipe>(AccumulatorRecipe)) &&
2128 "Unexpected operand order for partial reduction recipe");
2129 }
2130 ~VPPartialReductionRecipe() override = default;
2131
2133 return new VPPartialReductionRecipe(Opcode, getOperand(0), getOperand(1),
2135 }
2136
2137 VP_CLASSOF_IMPL(VPDef::VPPartialReductionSC)
2138
2139 /// Generate the reduction in the loop.
2140 void execute(VPTransformState &State) override;
2141
2142 /// Return the cost of this VPPartialReductionRecipe.
2144 VPCostContext &Ctx) const override;
2145
2146 /// Get the binary op's opcode.
2147 unsigned getOpcode() const { return Opcode; }
2148
2149#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2150 /// Print the recipe.
2151 void print(raw_ostream &O, const Twine &Indent,
2152 VPSlotTracker &SlotTracker) const override;
2153#endif
2154};
2155
2156/// A recipe for vectorizing a phi-node as a sequence of mask-based select
2157/// instructions.
2159public:
2160 /// The blend operation is a User of the incoming values and of their
2161 /// respective masks, ordered [I0, M0, I1, M1, I2, M2, ...]. Note that M0 can
2162 /// be omitted (implied by passing an odd number of operands) in which case
2163 /// all other incoming values are merged into it.
2165 : VPSingleDefRecipe(VPDef::VPBlendSC, Operands, Phi, Phi->getDebugLoc()) {
2166 assert(Operands.size() > 0 && "Expected at least one operand!");
2167 }
2168
2169 VPBlendRecipe *clone() override {
2171 return new VPBlendRecipe(cast<PHINode>(getUnderlyingValue()), Ops);
2172 }
2173
2174 VP_CLASSOF_IMPL(VPDef::VPBlendSC)
2175
2176 /// A normalized blend is one that has an odd number of operands, whereby the
2177 /// first operand does not have an associated mask.
2178 bool isNormalized() const { return getNumOperands() % 2; }
2179
2180 /// Return the number of incoming values, taking into account when normalized
2181 /// the first incoming value will have no mask.
2182 unsigned getNumIncomingValues() const {
2183 return (getNumOperands() + isNormalized()) / 2;
2184 }
2185
2186 /// Return incoming value number \p Idx.
2187 VPValue *getIncomingValue(unsigned Idx) const {
2188 return Idx == 0 ? getOperand(0) : getOperand(Idx * 2 - isNormalized());
2189 }
2190
2191 /// Return mask number \p Idx.
2192 VPValue *getMask(unsigned Idx) const {
2193 assert((Idx > 0 || !isNormalized()) && "First index has no mask!");
2194 return Idx == 0 ? getOperand(1) : getOperand(Idx * 2 + !isNormalized());
2195 }
2196
2197 /// Generate the phi/select nodes.
2198 void execute(VPTransformState &State) override;
2199
2200 /// Return the cost of this VPWidenMemoryRecipe.
2202 VPCostContext &Ctx) const override;
2203
2204#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2205 /// Print the recipe.
2206 void print(raw_ostream &O, const Twine &Indent,
2207 VPSlotTracker &SlotTracker) const override;
2208#endif
2209
2210 /// Returns true if the recipe only uses the first lane of operand \p Op.
2211 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2213 "Op must be an operand of the recipe");
2214 // Recursing through Blend recipes only, must terminate at header phi's the
2215 // latest.
2216 return all_of(users(),
2217 [this](VPUser *U) { return U->onlyFirstLaneUsed(this); });
2218 }
2219};
2220
2221/// VPInterleaveRecipe is a recipe for transforming an interleave group of load
2222/// or stores into one wide load/store and shuffles. The first operand of a
2223/// VPInterleave recipe is the address, followed by the stored values, followed
2224/// by an optional mask.
2227
2228 /// Indicates if the interleave group is in a conditional block and requires a
2229 /// mask.
2230 bool HasMask = false;
2231
2232 /// Indicates if gaps between members of the group need to be masked out or if
2233 /// unusued gaps can be loaded speculatively.
2234 bool NeedsMaskForGaps = false;
2235
2236public:
2238 ArrayRef<VPValue *> StoredValues, VPValue *Mask,
2239 bool NeedsMaskForGaps)
2240 : VPRecipeBase(VPDef::VPInterleaveSC, {Addr}), IG(IG),
2241 NeedsMaskForGaps(NeedsMaskForGaps) {
2242 for (unsigned i = 0; i < IG->getFactor(); ++i)
2243 if (Instruction *I = IG->getMember(i)) {
2244 if (I->getType()->isVoidTy())
2245 continue;
2246 new VPValue(I, this);
2247 }
2248
2249 for (auto *SV : StoredValues)
2250 addOperand(SV);
2251 if (Mask) {
2252 HasMask = true;
2253 addOperand(Mask);
2254 }
2255 }
2256 ~VPInterleaveRecipe() override = default;
2257
2259 return new VPInterleaveRecipe(IG, getAddr(), getStoredValues(), getMask(),
2260 NeedsMaskForGaps);
2261 }
2262
2263 VP_CLASSOF_IMPL(VPDef::VPInterleaveSC)
2264
2265 /// Return the address accessed by this recipe.
2266 VPValue *getAddr() const {
2267 return getOperand(0); // Address is the 1st, mandatory operand.
2268 }
2269
2270 /// Return the mask used by this recipe. Note that a full mask is represented
2271 /// by a nullptr.
2272 VPValue *getMask() const {
2273 // Mask is optional and therefore the last, currently 2nd operand.
2274 return HasMask ? getOperand(getNumOperands() - 1) : nullptr;
2275 }
2276
2277 /// Return the VPValues stored by this interleave group. If it is a load
2278 /// interleave group, return an empty ArrayRef.
2280 // The first operand is the address, followed by the stored values, followed
2281 // by an optional mask.
2284 }
2285
2286 /// Generate the wide load or store, and shuffles.
2287 void execute(VPTransformState &State) override;
2288
2289 /// Return the cost of this VPInterleaveRecipe.
2291 VPCostContext &Ctx) const override;
2292
2293#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2294 /// Print the recipe.
2295 void print(raw_ostream &O, const Twine &Indent,
2296 VPSlotTracker &SlotTracker) const override;
2297#endif
2298
2300
2301 /// Returns the number of stored operands of this interleave group. Returns 0
2302 /// for load interleave groups.
2303 unsigned getNumStoreOperands() const {
2304 return getNumOperands() - (HasMask ? 2 : 1);
2305 }
2306
2307 /// The recipe only uses the first lane of the address.
2308 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2310 "Op must be an operand of the recipe");
2311 return Op == getAddr() && !llvm::is_contained(getStoredValues(), Op);
2312 }
2313
2314 Instruction *getInsertPos() const { return IG->getInsertPos(); }
2315};
2316
2317/// A recipe to represent inloop reduction operations, performing a reduction on
2318/// a vector operand into a scalar value, and adding the result to a chain.
2319/// The Operands are {ChainOp, VecOp, [Condition]}.
2321 /// The recurrence decriptor for the reduction in question.
2322 const RecurrenceDescriptor &RdxDesc;
2323 bool IsOrdered;
2324 /// Whether the reduction is conditional.
2325 bool IsConditional = false;
2326
2327protected:
2328 VPReductionRecipe(const unsigned char SC, const RecurrenceDescriptor &R,
2330 VPValue *CondOp, bool IsOrdered, DebugLoc DL)
2331 : VPSingleDefRecipe(SC, Operands, I, DL), RdxDesc(R),
2332 IsOrdered(IsOrdered) {
2333 if (CondOp) {
2334 IsConditional = true;
2335 addOperand(CondOp);
2336 }
2337 }
2338
2339public:
2341 VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp,
2342 bool IsOrdered, DebugLoc DL = {})
2343 : VPReductionRecipe(VPDef::VPReductionSC, R, I,
2344 ArrayRef<VPValue *>({ChainOp, VecOp}), CondOp,
2345 IsOrdered, DL) {}
2346
2347 ~VPReductionRecipe() override = default;
2348
2350 return new VPReductionRecipe(RdxDesc, getUnderlyingInstr(), getChainOp(),
2351 getVecOp(), getCondOp(), IsOrdered,
2352 getDebugLoc());
2353 }
2354
2355 static inline bool classof(const VPRecipeBase *R) {
2356 return R->getVPDefID() == VPRecipeBase::VPReductionSC ||
2357 R->getVPDefID() == VPRecipeBase::VPReductionEVLSC;
2358 }
2359
2360 static inline bool classof(const VPUser *U) {
2361 auto *R = dyn_cast<VPRecipeBase>(U);
2362 return R && classof(R);
2363 }
2364
2365 /// Generate the reduction in the loop.
2366 void execute(VPTransformState &State) override;
2367
2368 /// Return the cost of VPReductionRecipe.
2370 VPCostContext &Ctx) const override;
2371
2372#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2373 /// Print the recipe.
2374 void print(raw_ostream &O, const Twine &Indent,
2375 VPSlotTracker &SlotTracker) const override;
2376#endif
2377
2378 /// Return the recurrence decriptor for the in-loop reduction.
2380 return RdxDesc;
2381 }
2382 /// Return true if the in-loop reduction is ordered.
2383 bool isOrdered() const { return IsOrdered; };
2384 /// Return true if the in-loop reduction is conditional.
2385 bool isConditional() const { return IsConditional; };
2386 /// The VPValue of the scalar Chain being accumulated.
2387 VPValue *getChainOp() const { return getOperand(0); }
2388 /// The VPValue of the vector value to be reduced.
2389 VPValue *getVecOp() const { return getOperand(1); }
2390 /// The VPValue of the condition for the block.
2392 return isConditional() ? getOperand(getNumOperands() - 1) : nullptr;
2393 }
2394};
2395
2396/// A recipe to represent inloop reduction operations with vector-predication
2397/// intrinsics, performing a reduction on a vector operand with the explicit
2398/// vector length (EVL) into a scalar value, and adding the result to a chain.
2399/// The Operands are {ChainOp, VecOp, EVL, [Condition]}.
2401public:
2404 VPDef::VPReductionEVLSC, R.getRecurrenceDescriptor(),
2406 ArrayRef<VPValue *>({R.getChainOp(), R.getVecOp(), &EVL}), CondOp,
2407 R.isOrdered(), R.getDebugLoc()) {}
2408
2409 ~VPReductionEVLRecipe() override = default;
2410
2412 llvm_unreachable("cloning not implemented yet");
2413 }
2414
2415 VP_CLASSOF_IMPL(VPDef::VPReductionEVLSC)
2416
2417 /// Generate the reduction in the loop
2418 void execute(VPTransformState &State) override;
2419
2420#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2421 /// Print the recipe.
2422 void print(raw_ostream &O, const Twine &Indent,
2423 VPSlotTracker &SlotTracker) const override;
2424#endif
2425
2426 /// The VPValue of the explicit vector length.
2427 VPValue *getEVL() const { return getOperand(2); }
2428
2429 /// Returns true if the recipe only uses the first lane of operand \p Op.
2430 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2432 "Op must be an operand of the recipe");
2433 return Op == getEVL();
2434 }
2435};
2436
2437/// VPReplicateRecipe replicates a given instruction producing multiple scalar
2438/// copies of the original scalar type, one per lane, instead of producing a
2439/// single copy of widened type for all lanes. If the instruction is known to be
2440/// uniform only one copy, per lane zero, will be generated.
2442 /// Indicator if only a single replica per lane is needed.
2443 bool IsUniform;
2444
2445 /// Indicator if the replicas are also predicated.
2446 bool IsPredicated;
2447
2448public:
2449 template <typename IterT>
2451 bool IsUniform, VPValue *Mask = nullptr)
2452 : VPRecipeWithIRFlags(VPDef::VPReplicateSC, Operands, *I),
2453 IsUniform(IsUniform), IsPredicated(Mask) {
2454 if (Mask)
2455 addOperand(Mask);
2456 }
2457
2458 ~VPReplicateRecipe() override = default;
2459
2461 auto *Copy =
2462 new VPReplicateRecipe(getUnderlyingInstr(), operands(), IsUniform,
2463 isPredicated() ? getMask() : nullptr);
2464 Copy->transferFlags(*this);
2465 return Copy;
2466 }
2467
2468 VP_CLASSOF_IMPL(VPDef::VPReplicateSC)
2469
2470 /// Generate replicas of the desired Ingredient. Replicas will be generated
2471 /// for all parts and lanes unless a specific part and lane are specified in
2472 /// the \p State.
2473 void execute(VPTransformState &State) override;
2474
2475 /// Return the cost of this VPReplicateRecipe.
2477 VPCostContext &Ctx) const override;
2478
2479#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2480 /// Print the recipe.
2481 void print(raw_ostream &O, const Twine &Indent,
2482 VPSlotTracker &SlotTracker) const override;
2483#endif
2484
2485 bool isUniform() const { return IsUniform; }
2486
2487 bool isPredicated() const { return IsPredicated; }
2488
2489 /// Returns true if the recipe only uses the first lane of operand \p Op.
2490 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2492 "Op must be an operand of the recipe");
2493 return isUniform();
2494 }
2495
2496 /// Returns true if the recipe uses scalars of operand \p Op.
2497 bool usesScalars(const VPValue *Op) const override {
2499 "Op must be an operand of the recipe");
2500 return true;
2501 }
2502
2503 /// Returns true if the recipe is used by a widened recipe via an intervening
2504 /// VPPredInstPHIRecipe. In this case, the scalar values should also be packed
2505 /// in a vector.
2506 bool shouldPack() const;
2507
2508 /// Return the mask of a predicated VPReplicateRecipe.
2510 assert(isPredicated() && "Trying to get the mask of a unpredicated recipe");
2511 return getOperand(getNumOperands() - 1);
2512 }
2513
2514 unsigned getOpcode() const { return getUnderlyingInstr()->getOpcode(); }
2515};
2516
2517/// A recipe for generating conditional branches on the bits of a mask.
2519public:
2521 : VPRecipeBase(VPDef::VPBranchOnMaskSC, {}) {
2522 if (BlockInMask) // nullptr means all-one mask.
2523 addOperand(BlockInMask);
2524 }
2525
2527 return new VPBranchOnMaskRecipe(getOperand(0));
2528 }
2529
2530 VP_CLASSOF_IMPL(VPDef::VPBranchOnMaskSC)
2531
2532 /// Generate the extraction of the appropriate bit from the block mask and the
2533 /// conditional branch.
2534 void execute(VPTransformState &State) override;
2535
2536 /// Return the cost of this VPBranchOnMaskRecipe.
2538 VPCostContext &Ctx) const override;
2539
2540#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2541 /// Print the recipe.
2542 void print(raw_ostream &O, const Twine &Indent,
2543 VPSlotTracker &SlotTracker) const override {
2544 O << Indent << "BRANCH-ON-MASK ";
2545 if (VPValue *Mask = getMask())
2546 Mask->printAsOperand(O, SlotTracker);
2547 else
2548 O << " All-One";
2549 }
2550#endif
2551
2552 /// Return the mask used by this recipe. Note that a full mask is represented
2553 /// by a nullptr.
2554 VPValue *getMask() const {
2555 assert(getNumOperands() <= 1 && "should have either 0 or 1 operands");
2556 // Mask is optional.
2557 return getNumOperands() == 1 ? getOperand(0) : nullptr;
2558 }
2559
2560 /// Returns true if the recipe uses scalars of operand \p Op.
2561 bool usesScalars(const VPValue *Op) const override {
2563 "Op must be an operand of the recipe");
2564 return true;
2565 }
2566};
2567
2568/// VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when
2569/// control converges back from a Branch-on-Mask. The phi nodes are needed in
2570/// order to merge values that are set under such a branch and feed their uses.
2571/// The phi nodes can be scalar or vector depending on the users of the value.
2572/// This recipe works in concert with VPBranchOnMaskRecipe.
2574public:
2575 /// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
2576 /// nodes after merging back from a Branch-on-Mask.
2578 : VPSingleDefRecipe(VPDef::VPPredInstPHISC, PredV, DL) {}
2579 ~VPPredInstPHIRecipe() override = default;
2580
2582 return new VPPredInstPHIRecipe(getOperand(0), getDebugLoc());
2583 }
2584
2585 VP_CLASSOF_IMPL(VPDef::VPPredInstPHISC)
2586
2587 /// Generates phi nodes for live-outs (from a replicate region) as needed to
2588 /// retain SSA form.
2589 void execute(VPTransformState &State) override;
2590
2591 /// Return the cost of this VPPredInstPHIRecipe.
2593 VPCostContext &Ctx) const override {
2594 // TODO: Compute accurate cost after retiring the legacy cost model.
2595 return 0;
2596 }
2597
2598#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2599 /// Print the recipe.
2600 void print(raw_ostream &O, const Twine &Indent,
2601 VPSlotTracker &SlotTracker) const override;
2602#endif
2603
2604 /// Returns true if the recipe uses scalars of operand \p Op.
2605 bool usesScalars(const VPValue *Op) const override {
2607 "Op must be an operand of the recipe");
2608 return true;
2609 }
2610};
2611
2612/// A common base class for widening memory operations. An optional mask can be
2613/// provided as the last operand.
2615protected:
2617
2618 /// Whether the accessed addresses are consecutive.
2620
2621 /// Whether the consecutive accessed addresses are in reverse order.
2623
2624 /// Whether the memory access is masked.
2625 bool IsMasked = false;
2626
2627 void setMask(VPValue *Mask) {
2628 assert(!IsMasked && "cannot re-set mask");
2629 if (!Mask)
2630 return;
2631 addOperand(Mask);
2632 IsMasked = true;
2633 }
2634
2635 VPWidenMemoryRecipe(const char unsigned SC, Instruction &I,
2636 std::initializer_list<VPValue *> Operands,
2637 bool Consecutive, bool Reverse, DebugLoc DL)
2639 Reverse(Reverse) {
2640 assert((Consecutive || !Reverse) && "Reverse implies consecutive");
2641 }
2642
2643public:
2645 llvm_unreachable("cloning not supported");
2646 }
2647
2648 static inline bool classof(const VPRecipeBase *R) {
2649 return R->getVPDefID() == VPRecipeBase::VPWidenLoadSC ||
2650 R->getVPDefID() == VPRecipeBase::VPWidenStoreSC ||
2651 R->getVPDefID() == VPRecipeBase::VPWidenLoadEVLSC ||
2652 R->getVPDefID() == VPRecipeBase::VPWidenStoreEVLSC;
2653 }
2654
2655 static inline bool classof(const VPUser *U) {
2656 auto *R = dyn_cast<VPRecipeBase>(U);
2657 return R && classof(R);
2658 }
2659
2660 /// Return whether the loaded-from / stored-to addresses are consecutive.
2661 bool isConsecutive() const { return Consecutive; }
2662
2663 /// Return whether the consecutive loaded/stored addresses are in reverse
2664 /// order.
2665 bool isReverse() const { return Reverse; }
2666
2667 /// Return the address accessed by this recipe.
2668 VPValue *getAddr() const { return getOperand(0); }
2669
2670 /// Returns true if the recipe is masked.
2671 bool isMasked() const { return IsMasked; }
2672
2673 /// Return the mask used by this recipe. Note that a full mask is represented
2674 /// by a nullptr.
2675 VPValue *getMask() const {
2676 // Mask is optional and therefore the last operand.
2677 return isMasked() ? getOperand(getNumOperands() - 1) : nullptr;
2678 }
2679
2680 /// Generate the wide load/store.
2681 void execute(VPTransformState &State) override {
2682 llvm_unreachable("VPWidenMemoryRecipe should not be instantiated.");
2683 }
2684
2685 /// Return the cost of this VPWidenMemoryRecipe.
2687 VPCostContext &Ctx) const override;
2688
2690};
2691
2692/// A recipe for widening load operations, using the address to load from and an
2693/// optional mask.
2694struct VPWidenLoadRecipe final : public VPWidenMemoryRecipe, public VPValue {
2696 bool Consecutive, bool Reverse, DebugLoc DL)
2697 : VPWidenMemoryRecipe(VPDef::VPWidenLoadSC, Load, {Addr}, Consecutive,
2698 Reverse, DL),
2699 VPValue(this, &Load) {
2700 setMask(Mask);
2701 }
2702
2704 return new VPWidenLoadRecipe(cast<LoadInst>(Ingredient), getAddr(),
2706 getDebugLoc());
2707 }
2708
2709 VP_CLASSOF_IMPL(VPDef::VPWidenLoadSC);
2710
2711 /// Generate a wide load or gather.
2712 void execute(VPTransformState &State) override;
2713
2714#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2715 /// Print the recipe.
2716 void print(raw_ostream &O, const Twine &Indent,
2717 VPSlotTracker &SlotTracker) const override;
2718#endif
2719
2720 /// Returns true if the recipe only uses the first lane of operand \p Op.
2721 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2723 "Op must be an operand of the recipe");
2724 // Widened, consecutive loads operations only demand the first lane of
2725 // their address.
2726 return Op == getAddr() && isConsecutive();
2727 }
2728};
2729
2730/// A recipe for widening load operations with vector-predication intrinsics,
2731/// using the address to load from, the explicit vector length and an optional
2732/// mask.
2733struct VPWidenLoadEVLRecipe final : public VPWidenMemoryRecipe, public VPValue {
2735 : VPWidenMemoryRecipe(VPDef::VPWidenLoadEVLSC, L.getIngredient(),
2736 {L.getAddr(), &EVL}, L.isConsecutive(),
2737 L.isReverse(), L.getDebugLoc()),
2738 VPValue(this, &getIngredient()) {
2739 setMask(Mask);
2740 }
2741
2742 VP_CLASSOF_IMPL(VPDef::VPWidenLoadEVLSC)
2743
2744 /// Return the EVL operand.
2745 VPValue *getEVL() const { return getOperand(1); }
2746
2747 /// Generate the wide load or gather.
2748 void execute(VPTransformState &State) override;
2749
2750 /// Return the cost of this VPWidenLoadEVLRecipe.
2752 VPCostContext &Ctx) const override;
2753
2754#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2755 /// Print the recipe.
2756 void print(raw_ostream &O, const Twine &Indent,
2757 VPSlotTracker &SlotTracker) const override;
2758#endif
2759
2760 /// Returns true if the recipe only uses the first lane of operand \p Op.
2761 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2763 "Op must be an operand of the recipe");
2764 // Widened loads only demand the first lane of EVL and consecutive loads
2765 // only demand the first lane of their address.
2766 return Op == getEVL() || (Op == getAddr() && isConsecutive());
2767 }
2768};
2769
2770/// A recipe for widening store operations, using the stored value, the address
2771/// to store to and an optional mask.
2774 VPValue *Mask, bool Consecutive, bool Reverse, DebugLoc DL)
2775 : VPWidenMemoryRecipe(VPDef::VPWidenStoreSC, Store, {Addr, StoredVal},
2777 setMask(Mask);
2778 }
2779
2781 return new VPWidenStoreRecipe(cast<StoreInst>(Ingredient), getAddr(),
2783 Reverse, getDebugLoc());
2784 }
2785
2786 VP_CLASSOF_IMPL(VPDef::VPWidenStoreSC);
2787
2788 /// Return the value stored by this recipe.
2789 VPValue *getStoredValue() const { return getOperand(1); }
2790
2791 /// Generate a wide store or scatter.
2792 void execute(VPTransformState &State) override;
2793
2794#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2795 /// Print the recipe.
2796 void print(raw_ostream &O, const Twine &Indent,
2797 VPSlotTracker &SlotTracker) const override;
2798#endif
2799
2800 /// Returns true if the recipe only uses the first lane of operand \p Op.
2801 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2803 "Op must be an operand of the recipe");
2804 // Widened, consecutive stores only demand the first lane of their address,
2805 // unless the same operand is also stored.
2806 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
2807 }
2808};
2809
2810/// A recipe for widening store operations with vector-predication intrinsics,
2811/// using the value to store, the address to store to, the explicit vector
2812/// length and an optional mask.
2815 : VPWidenMemoryRecipe(VPDef::VPWidenStoreEVLSC, S.getIngredient(),
2816 {S.getAddr(), S.getStoredValue(), &EVL},
2817 S.isConsecutive(), S.isReverse(), S.getDebugLoc()) {
2818 setMask(Mask);
2819 }
2820
2821 VP_CLASSOF_IMPL(VPDef::VPWidenStoreEVLSC)
2822
2823 /// Return the address accessed by this recipe.
2824 VPValue *getStoredValue() const { return getOperand(1); }
2825
2826 /// Return the EVL operand.
2827 VPValue *getEVL() const { return getOperand(2); }
2828
2829 /// Generate the wide store or scatter.
2830 void execute(VPTransformState &State) override;
2831
2832 /// Return the cost of this VPWidenStoreEVLRecipe.
2834 VPCostContext &Ctx) const override;
2835
2836#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2837 /// Print the recipe.
2838 void print(raw_ostream &O, const Twine &Indent,
2839 VPSlotTracker &SlotTracker) const override;
2840#endif
2841
2842 /// Returns true if the recipe only uses the first lane of operand \p Op.
2843 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2845 "Op must be an operand of the recipe");
2846 if (Op == getEVL()) {
2847 assert(getStoredValue() != Op && "unexpected store of EVL");
2848 return true;
2849 }
2850 // Widened, consecutive memory operations only demand the first lane of
2851 // their address, unless the same operand is also stored. That latter can
2852 // happen with opaque pointers.
2853 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
2854 }
2855};
2856
2857/// Recipe to expand a SCEV expression.
2859 const SCEV *Expr;
2860 ScalarEvolution &SE;
2861
2862public:
2864 : VPSingleDefRecipe(VPDef::VPExpandSCEVSC, {}), Expr(Expr), SE(SE) {}
2865
2866 ~VPExpandSCEVRecipe() override = default;
2867
2869 return new VPExpandSCEVRecipe(Expr, SE);
2870 }
2871
2872 VP_CLASSOF_IMPL(VPDef::VPExpandSCEVSC)
2873
2874 /// Generate a canonical vector induction variable of the vector loop, with
2875 void execute(VPTransformState &State) override;
2876
2877 /// Return the cost of this VPExpandSCEVRecipe.
2879 VPCostContext &Ctx) const override {
2880 // TODO: Compute accurate cost after retiring the legacy cost model.
2881 return 0;
2882 }
2883
2884#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2885 /// Print the recipe.
2886 void print(raw_ostream &O, const Twine &Indent,
2887 VPSlotTracker &SlotTracker) const override;
2888#endif
2889
2890 const SCEV *getSCEV() const { return Expr; }
2891};
2892
2893/// Canonical scalar induction phi of the vector loop. Starting at the specified
2894/// start value (either 0 or the resume value when vectorizing the epilogue
2895/// loop). VPWidenCanonicalIVRecipe represents the vector version of the
2896/// canonical induction variable.
2898public:
2900 : VPHeaderPHIRecipe(VPDef::VPCanonicalIVPHISC, nullptr, StartV, DL) {}
2901
2902 ~VPCanonicalIVPHIRecipe() override = default;
2903
2905 auto *R = new VPCanonicalIVPHIRecipe(getOperand(0), getDebugLoc());
2906 R->addOperand(getBackedgeValue());
2907 return R;
2908 }
2909
2910 VP_CLASSOF_IMPL(VPDef::VPCanonicalIVPHISC)
2911
2913 return D->getVPDefID() == VPDef::VPCanonicalIVPHISC;
2914 }
2915
2916 void execute(VPTransformState &State) override {
2918 "cannot execute this recipe, should be replaced by VPScalarPHIRecipe");
2919 }
2920
2921#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2922 /// Print the recipe.
2923 void print(raw_ostream &O, const Twine &Indent,
2924 VPSlotTracker &SlotTracker) const override;
2925#endif
2926
2927 /// Returns the scalar type of the induction.
2929 return getStartValue()->getLiveInIRValue()->getType();
2930 }
2931
2932 /// Returns true if the recipe only uses the first lane of operand \p Op.
2933 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2935 "Op must be an operand of the recipe");
2936 return true;
2937 }
2938
2939 /// Returns true if the recipe only uses the first part of operand \p Op.
2940 bool onlyFirstPartUsed(const VPValue *Op) const override {
2942 "Op must be an operand of the recipe");
2943 return true;
2944 }
2945
2946 /// Return the cost of this VPCanonicalIVPHIRecipe.
2948 VPCostContext &Ctx) const override {
2949 // For now, match the behavior of the legacy cost model.
2950 return 0;
2951 }
2952};
2953
2954/// A recipe for generating the active lane mask for the vector loop that is
2955/// used to predicate the vector operations.
2956/// TODO: It would be good to use the existing VPWidenPHIRecipe instead and
2957/// remove VPActiveLaneMaskPHIRecipe.
2959public:
2961 : VPHeaderPHIRecipe(VPDef::VPActiveLaneMaskPHISC, nullptr, StartMask,
2962 DL) {}
2963
2964 ~VPActiveLaneMaskPHIRecipe() override = default;
2965
2968 if (getNumOperands() == 2)
2969 R->addOperand(getOperand(1));
2970 return R;
2971 }
2972
2973 VP_CLASSOF_IMPL(VPDef::VPActiveLaneMaskPHISC)
2974
2976 return D->getVPDefID() == VPDef::VPActiveLaneMaskPHISC;
2977 }
2978
2979 /// Generate the active lane mask phi of the vector loop.
2980 void execute(VPTransformState &State) override;
2981
2982#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2983 /// Print the recipe.
2984 void print(raw_ostream &O, const Twine &Indent,
2985 VPSlotTracker &SlotTracker) const override;
2986#endif
2987};
2988
2989/// A recipe for generating the phi node for the current index of elements,
2990/// adjusted in accordance with EVL value. It starts at the start value of the
2991/// canonical induction and gets incremented by EVL in each iteration of the
2992/// vector loop.
2994public:
2996 : VPHeaderPHIRecipe(VPDef::VPEVLBasedIVPHISC, nullptr, StartIV, DL) {}
2997
2998 ~VPEVLBasedIVPHIRecipe() override = default;
2999
3001 llvm_unreachable("cloning not implemented yet");
3002 }
3003
3004 VP_CLASSOF_IMPL(VPDef::VPEVLBasedIVPHISC)
3005
3007 return D->getVPDefID() == VPDef::VPEVLBasedIVPHISC;
3008 }
3009
3010 void execute(VPTransformState &State) override {
3012 "cannot execute this recipe, should be replaced by VPScalarPHIRecipe");
3013 }
3014
3015 /// Return the cost of this VPEVLBasedIVPHIRecipe.
3017 VPCostContext &Ctx) const override {
3018 // For now, match the behavior of the legacy cost model.
3019 return 0;
3020 }
3021
3022 /// Returns true if the recipe only uses the first lane of operand \p Op.
3023 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3025 "Op must be an operand of the recipe");
3026 return true;
3027 }
3028
3029#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3030 /// Print the recipe.
3031 void print(raw_ostream &O, const Twine &Indent,
3032 VPSlotTracker &SlotTracker) const override;
3033#endif
3034};
3035
3036/// A Recipe for widening the canonical induction variable of the vector loop.
3038 public VPUnrollPartAccessor<1> {
3039public:
3041 : VPSingleDefRecipe(VPDef::VPWidenCanonicalIVSC, {CanonicalIV}) {}
3042
3043 ~VPWidenCanonicalIVRecipe() override = default;
3044
3046 return new VPWidenCanonicalIVRecipe(
3047 cast<VPCanonicalIVPHIRecipe>(getOperand(0)));
3048 }
3049
3050 VP_CLASSOF_IMPL(VPDef::VPWidenCanonicalIVSC)
3051
3052 /// Generate a canonical vector induction variable of the vector loop, with
3053 /// start = {<Part*VF, Part*VF+1, ..., Part*VF+VF-1> for 0 <= Part < UF}, and
3054 /// step = <VF*UF, VF*UF, ..., VF*UF>.
3055 void execute(VPTransformState &State) override;
3056
3057 /// Return the cost of this VPWidenCanonicalIVPHIRecipe.
3059 VPCostContext &Ctx) const override {
3060 // TODO: Compute accurate cost after retiring the legacy cost model.
3061 return 0;
3062 }
3063
3064#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3065 /// Print the recipe.
3066 void print(raw_ostream &O, const Twine &Indent,
3067 VPSlotTracker &SlotTracker) const override;
3068#endif
3069};
3070
3071/// A recipe for converting the input value \p IV value to the corresponding
3072/// value of an IV with different start and step values, using Start + IV *
3073/// Step.
3075 /// Kind of the induction.
3077 /// If not nullptr, the floating point induction binary operator. Must be set
3078 /// for floating point inductions.
3079 const FPMathOperator *FPBinOp;
3080
3081 /// Name to use for the generated IR instruction for the derived IV.
3082 std::string Name;
3083
3084public:
3086 VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step,
3087 const Twine &Name = "")
3089 IndDesc.getKind(),
3090 dyn_cast_or_null<FPMathOperator>(IndDesc.getInductionBinOp()),
3091 Start, CanonicalIV, Step, Name) {}
3092
3094 const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV,
3095 VPValue *Step, const Twine &Name = "")
3096 : VPSingleDefRecipe(VPDef::VPDerivedIVSC, {Start, IV, Step}), Kind(Kind),
3097 FPBinOp(FPBinOp), Name(Name.str()) {}
3098
3099 ~VPDerivedIVRecipe() override = default;
3100
3102 return new VPDerivedIVRecipe(Kind, FPBinOp, getStartValue(), getOperand(1),
3103 getStepValue());
3104 }
3105
3106 VP_CLASSOF_IMPL(VPDef::VPDerivedIVSC)
3107
3108 /// Generate the transformed value of the induction at offset StartValue (1.
3109 /// operand) + IV (2. operand) * StepValue (3, operand).
3110 void execute(VPTransformState &State) override;
3111
3112 /// Return the cost of this VPDerivedIVRecipe.
3114 VPCostContext &Ctx) const override {
3115 // TODO: Compute accurate cost after retiring the legacy cost model.
3116 return 0;
3117 }
3118
3119#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3120 /// Print the recipe.
3121 void print(raw_ostream &O, const Twine &Indent,
3122 VPSlotTracker &SlotTracker) const override;
3123#endif
3124
3126 return getStartValue()->getLiveInIRValue()->getType();
3127 }
3128
3129 VPValue *getStartValue() const { return getOperand(0); }
3130 VPValue *getStepValue() const { return getOperand(2); }
3131
3132 /// Returns true if the recipe only uses the first lane of operand \p Op.
3133 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3135 "Op must be an operand of the recipe");
3136 return true;
3137 }
3138};
3139
3140/// A recipe for handling phi nodes of integer and floating-point inductions,
3141/// producing their scalar values.
3143 public VPUnrollPartAccessor<2> {
3144 Instruction::BinaryOps InductionOpcode;
3145
3146public:
3149 : VPRecipeWithIRFlags(VPDef::VPScalarIVStepsSC,
3150 ArrayRef<VPValue *>({IV, Step}), FMFs),
3151 InductionOpcode(Opcode) {}
3152
3154 VPValue *Step)
3156 IV, Step, IndDesc.getInductionOpcode(),
3157 dyn_cast_or_null<FPMathOperator>(IndDesc.getInductionBinOp())
3158 ? IndDesc.getInductionBinOp()->getFastMathFlags()
3159 : FastMathFlags()) {}
3160
3161 ~VPScalarIVStepsRecipe() override = default;
3162
3164 return new VPScalarIVStepsRecipe(
3165 getOperand(0), getOperand(1), InductionOpcode,
3167 }
3168
3169 VP_CLASSOF_IMPL(VPDef::VPScalarIVStepsSC)
3170
3171 /// Generate the scalarized versions of the phi node as needed by their users.
3172 void execute(VPTransformState &State) override;
3173
3174 /// Return the cost of this VPScalarIVStepsRecipe.
3176 VPCostContext &Ctx) const override {
3177 // TODO: Compute accurate cost after retiring the legacy cost model.
3178 return 0;
3179 }
3180
3181#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3182 /// Print the recipe.
3183 void print(raw_ostream &O, const Twine &Indent,
3184 VPSlotTracker &SlotTracker) const override;
3185#endif
3186
3187 VPValue *getStepValue() const { return getOperand(1); }
3188
3189 /// Returns true if the recipe only uses the first lane of operand \p Op.
3190 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3192 "Op must be an operand of the recipe");
3193 return true;
3194 }
3195};
3196
3197/// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
3198/// holds a sequence of zero or more VPRecipe's each representing a sequence of
3199/// output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
3201 friend class VPlan;
3202
3203 /// Use VPlan::createVPBasicBlock to create VPBasicBlocks.
3204 VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr)
3205 : VPBlockBase(VPBasicBlockSC, Name.str()) {
3206 if (Recipe)
3207 appendRecipe(Recipe);
3208 }
3209
3210public:
3212
3213protected:
3214 /// The VPRecipes held in the order of output instructions to generate.
3216
3217 VPBasicBlock(const unsigned char BlockSC, const Twine &Name = "")
3218 : VPBlockBase(BlockSC, Name.str()) {}
3219
3220public:
3221 ~VPBasicBlock() override {
3222 while (!Recipes.empty())
3223 Recipes.pop_back();
3224 }
3225
3226 /// Instruction iterators...
3231
3232 //===--------------------------------------------------------------------===//
3233 /// Recipe iterator methods
3234 ///
3235 inline iterator begin() { return Recipes.begin(); }
3236 inline const_iterator begin() const { return Recipes.begin(); }
3237 inline iterator end() { return Recipes.end(); }
3238 inline const_iterator end() const { return Recipes.end(); }
3239
3240 inline reverse_iterator rbegin() { return Recipes.rbegin(); }
3241 inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); }
3242 inline reverse_iterator rend() { return Recipes.rend(); }
3243 inline const_reverse_iterator rend() const { return Recipes.rend(); }
3244
3245 inline size_t size() const { return Recipes.size(); }
3246 inline bool empty() const { return Recipes.empty(); }
3247 inline const VPRecipeBase &front() const { return Recipes.front(); }
3248 inline VPRecipeBase &front() { return Recipes.front(); }
3249 inline const VPRecipeBase &back() const { return Recipes.back(); }
3250 inline VPRecipeBase &back() { return Recipes.back(); }
3251
3252 /// Returns a reference to the list of recipes.
3254
3255 /// Returns a pointer to a member of the recipe list.
3257 return &VPBasicBlock::Recipes;
3258 }
3259
3260 /// Method to support type inquiry through isa, cast, and dyn_cast.
3261 static inline bool classof(const VPBlockBase *V) {
3262 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
3263 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3264 }
3265
3266 void insert(VPRecipeBase *Recipe, iterator InsertPt) {
3267 assert(Recipe && "No recipe to append.");
3268 assert(!Recipe->Parent && "Recipe already in VPlan");
3269 Recipe->Parent = this;
3270 Recipes.insert(InsertPt, Recipe);
3271 }
3272
3273 /// Augment the existing recipes of a VPBasicBlock with an additional
3274 /// \p Recipe as the last recipe.
3275 void appendRecipe(VPRecipeBase *Recipe) { insert(Recipe, end()); }
3276
3277 /// The method which generates the output IR instructions that correspond to
3278 /// this VPBasicBlock, thereby "executing" the VPlan.
3279 void execute(VPTransformState *State) override;
3280
3281 /// Return the cost of this VPBasicBlock.
3283
3284 /// Return the position of the first non-phi node recipe in the block.
3286
3287 /// Returns an iterator range over the PHI-like recipes in the block.
3289 return make_range(begin(), getFirstNonPhi());
3290 }
3291
3292 /// Split current block at \p SplitAt by inserting a new block between the
3293 /// current block and its successors and moving all recipes starting at
3294 /// SplitAt to the new block. Returns the new block.
3295 VPBasicBlock *splitAt(iterator SplitAt);
3296
3299
3300#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3301 /// Print this VPBsicBlock to \p O, prefixing all lines with \p Indent. \p
3302 /// SlotTracker is used to print unnamed VPValue's using consequtive numbers.
3303 ///
3304 /// Note that the numbering is applied to the whole VPlan, so printing
3305 /// individual blocks is consistent with the whole VPlan printing.
3306 void print(raw_ostream &O, const Twine &Indent,
3307 VPSlotTracker &SlotTracker) const override;
3308 using VPBlockBase::print; // Get the print(raw_stream &O) version.
3309#endif
3310
3311 /// If the block has multiple successors, return the branch recipe terminating
3312 /// the block. If there are no or only a single successor, return nullptr;
3314 const VPRecipeBase *getTerminator() const;
3315
3316 /// Returns true if the block is exiting it's parent region.
3317 bool isExiting() const;
3318
3319 /// Clone the current block and it's recipes, without updating the operands of
3320 /// the cloned recipes.
3321 VPBasicBlock *clone() override;
3322
3323protected:
3324 /// Execute the recipes in the IR basic block \p BB.
3325 void executeRecipes(VPTransformState *State, BasicBlock *BB);
3326
3327 /// Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block
3328 /// generated for this VPBB.
3330
3331private:
3332 /// Create an IR BasicBlock to hold the output instructions generated by this
3333 /// VPBasicBlock, and return it. Update the CFGState accordingly.
3334 BasicBlock *createEmptyBasicBlock(VPTransformState &State);
3335};
3336
3337/// A special type of VPBasicBlock that wraps an existing IR basic block.
3338/// Recipes of the block get added before the first non-phi instruction in the
3339/// wrapped block.
3340/// Note: At the moment, VPIRBasicBlock can only be used to wrap VPlan's
3341/// preheader block.
3343 friend class VPlan;
3344
3345 BasicBlock *IRBB;
3346
3347 /// Use VPlan::createVPIRBasicBlock to create VPIRBasicBlocks.
3349 : VPBasicBlock(VPIRBasicBlockSC,
3350 (Twine("ir-bb<") + IRBB->getName() + Twine(">")).str()),
3351 IRBB(IRBB) {}
3352
3353public:
3354 ~VPIRBasicBlock() override {}
3355
3356 static inline bool classof(const VPBlockBase *V) {
3357 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3358 }
3359
3360 /// The method which generates the output IR instructions that correspond to
3361 /// this VPBasicBlock, thereby "executing" the VPlan.
3362 void execute(VPTransformState *State) override;
3363
3364 VPIRBasicBlock *clone() override;
3365
3366 BasicBlock *getIRBasicBlock() const { return IRBB; }
3367};
3368
3369/// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
3370/// which form a Single-Entry-Single-Exiting subgraph of the output IR CFG.
3371/// A VPRegionBlock may indicate that its contents are to be replicated several
3372/// times. This is designed to support predicated scalarization, in which a
3373/// scalar if-then code structure needs to be generated VF * UF times. Having
3374/// this replication indicator helps to keep a single model for multiple
3375/// candidate VF's. The actual replication takes place only once the desired VF
3376/// and UF have been determined.
3378 friend class VPlan;
3379
3380 /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
3381 VPBlockBase *Entry;
3382
3383 /// Hold the Single Exiting block of the SESE region modelled by the
3384 /// VPRegionBlock.
3385 VPBlockBase *Exiting;
3386
3387 /// An indicator whether this region is to generate multiple replicated
3388 /// instances of output IR corresponding to its VPBlockBases.
3389 bool IsReplicator;
3390
3391 /// Use VPlan::createVPRegionBlock to create VPRegionBlocks.
3392 VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting,
3393 const std::string &Name = "", bool IsReplicator = false)
3394 : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exiting(Exiting),
3395 IsReplicator(IsReplicator) {
3396 assert(Entry->getPredecessors().empty() && "Entry block has predecessors.");
3397 assert(Exiting->getSuccessors().empty() && "Exit block has successors.");
3398 Entry->setParent(this);
3399 Exiting->setParent(this);
3400 }
3401 VPRegionBlock(const std::string &Name = "", bool IsReplicator = false)
3402 : VPBlockBase(VPRegionBlockSC, Name), Entry(nullptr), Exiting(nullptr),
3403 IsReplicator(IsReplicator) {}
3404
3405public:
3406 ~VPRegionBlock() override {}
3407
3408 /// Method to support type inquiry through isa, cast, and dyn_cast.
3409 static inline bool classof(const VPBlockBase *V) {
3410 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
3411 }
3412
3413 const VPBlockBase *getEntry() const { return Entry; }
3414 VPBlockBase *getEntry() { return Entry; }
3415
3416 /// Set \p EntryBlock as the entry VPBlockBase of this VPRegionBlock. \p
3417 /// EntryBlock must have no predecessors.
3418 void setEntry(VPBlockBase *EntryBlock) {
3419 assert(EntryBlock->getPredecessors().empty() &&
3420 "Entry block cannot have predecessors.");
3421 Entry = EntryBlock;
3422 EntryBlock->setParent(this);
3423 }
3424
3425 const VPBlockBase *getExiting() const { return Exiting; }
3426 VPBlockBase *getExiting() { return Exiting; }
3427
3428 /// Set \p ExitingBlock as the exiting VPBlockBase of this VPRegionBlock. \p
3429 /// ExitingBlock must have no successors.
3430 void setExiting(VPBlockBase *ExitingBlock) {
3431 assert(ExitingBlock->getSuccessors().empty() &&
3432 "Exit block cannot have successors.");
3433 Exiting = ExitingBlock;
3434 ExitingBlock->setParent(this);
3435 }
3436
3437 /// Returns the pre-header VPBasicBlock of the loop region.
3439 assert(!isReplicator() && "should only get pre-header of loop regions");
3441 }
3442
3443 /// An indicator whether this region is to generate multiple replicated
3444 /// instances of output IR corresponding to its VPBlockBases.
3445 bool isReplicator() const { return IsReplicator; }
3446
3447 /// The method which generates the output IR instructions that correspond to
3448 /// this VPRegionBlock, thereby "executing" the VPlan.
3449 void execute(VPTransformState *State) override;
3450
3451 // Return the cost of this region.
3453
3454#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3455 /// Print this VPRegionBlock to \p O (recursively), prefixing all lines with
3456 /// \p Indent. \p SlotTracker is used to print unnamed VPValue's using
3457 /// consequtive numbers.
3458 ///
3459 /// Note that the numbering is applied to the whole VPlan, so printing
3460 /// individual regions is consistent with the whole VPlan printing.
3461 void print(raw_ostream &O, const Twine &Indent,
3462 VPSlotTracker &SlotTracker) const override;
3463 using VPBlockBase::print; // Get the print(raw_stream &O) version.
3464#endif
3465
3466 /// Clone all blocks in the single-entry single-exit region of the block and
3467 /// their recipes without updating the operands of the cloned recipes.
3468 VPRegionBlock *clone() override;
3469};
3470
3471/// VPlan models a candidate for vectorization, encoding various decisions take
3472/// to produce efficient output IR, including which branches, basic-blocks and
3473/// output IR instructions to generate, and their cost. VPlan holds a
3474/// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry
3475/// VPBasicBlock.
3476class VPlan {
3477 friend class VPlanPrinter;
3478 friend class VPSlotTracker;
3479
3480 /// VPBasicBlock corresponding to the original preheader. Used to place
3481 /// VPExpandSCEV recipes for expressions used during skeleton creation and the
3482 /// rest of VPlan execution.
3483 /// When this VPlan is used for the epilogue vector loop, the entry will be
3484 /// replaced by a new entry block created during skeleton creation.
3485 VPBasicBlock *Entry;
3486
3487 /// VPIRBasicBlock wrapping the header of the original scalar loop.
3488 VPIRBasicBlock *ScalarHeader;
3489
3490 /// Holds the VFs applicable to this VPlan.
3492
3493 /// Holds the UFs applicable to this VPlan. If empty, the VPlan is valid for
3494 /// any UF.
3496
3497 /// Holds the name of the VPlan, for printing.
3498 std::string Name;
3499
3500 /// Represents the trip count of the original loop, for folding
3501 /// the tail.
3502 VPValue *TripCount = nullptr;
3503
3504 /// Represents the backedge taken count of the original loop, for folding
3505 /// the tail. It equals TripCount - 1.
3506 VPValue *BackedgeTakenCount = nullptr;
3507
3508 /// Represents the vector trip count.
3509 VPValue VectorTripCount;
3510
3511 /// Represents the vectorization factor of the loop.
3512 VPValue VF;
3513
3514 /// Represents the loop-invariant VF * UF of the vector loop region.
3515 VPValue VFxUF;
3516
3517 /// Holds a mapping between Values and their corresponding VPValue inside
3518 /// VPlan.
3519 Value2VPValueTy Value2VPValue;
3520
3521 /// Contains all the external definitions created for this VPlan. External
3522 /// definitions are VPValues that hold a pointer to their underlying IR.
3523 SmallVector<VPValue *, 16> VPLiveInsToFree;
3524
3525 /// Mapping from SCEVs to the VPValues representing their expansions.
3526 /// NOTE: This mapping is temporary and will be removed once all users have
3527 /// been modeled in VPlan directly.
3528 DenseMap<const SCEV *, VPValue *> SCEVToExpansion;
3529
3530 /// Blocks allocated and owned by the VPlan. They will be deleted once the
3531 /// VPlan is destroyed.
3532 SmallVector<VPBlockBase *> CreatedBlocks;
3533
3534 /// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
3535 /// wrapping the original header of the scalar loop.
3536 VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader)
3537 : Entry(Entry), ScalarHeader(ScalarHeader) {
3538 Entry->setPlan(this);
3539 assert(ScalarHeader->getNumSuccessors() == 0 &&
3540 "scalar header must be a leaf node");
3541 }
3542
3543public:
3544 /// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the
3545 /// original preheader and scalar header of \p L, to be used as entry and
3546 /// scalar header blocks of the new VPlan.
3547 VPlan(Loop *L);
3548
3549 /// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock
3550 /// wrapping \p ScalarHeaderBB and a trip count of \p TC.
3551 VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC) {
3552 setEntry(createVPBasicBlock("preheader"));
3553 ScalarHeader = createVPIRBasicBlock(ScalarHeaderBB);
3554 TripCount = TC;
3555 }
3556
3557 ~VPlan();
3558
3560 Entry = VPBB;
3561 VPBB->setPlan(this);
3562 }
3563
3564 /// Create initial VPlan, having an "entry" VPBasicBlock (wrapping
3565 /// original scalar pre-header) which contains SCEV expansions that need
3566 /// to happen before the CFG is modified (when executing a VPlan for the
3567 /// epilogue vector loop, the original entry needs to be replaced by a new
3568 /// one); a VPBasicBlock for the vector pre-header, followed by a region for
3569 /// the vector loop, followed by the middle VPBasicBlock. If a check is needed
3570 /// to guard executing the scalar epilogue loop, it will be added to the
3571 /// middle block, together with VPBasicBlocks for the scalar preheader and
3572 /// exit blocks. \p InductionTy is the type of the canonical induction and
3573 /// used for related values, like the trip count expression.
3574 static VPlanPtr createInitialVPlan(Type *InductionTy,
3576 bool RequiresScalarEpilogueCheck,
3577 bool TailFolded, Loop *TheLoop);
3578
3579 /// Prepare the plan for execution, setting up the required live-in values.
3580 void prepareToExecute(Value *TripCount, Value *VectorTripCount,
3581 VPTransformState &State);
3582
3583 /// Generate the IR code for this VPlan.
3584 void execute(VPTransformState *State);
3585
3586 /// Return the cost of this plan.
3588
3589 VPBasicBlock *getEntry() { return Entry; }
3590 const VPBasicBlock *getEntry() const { return Entry; }
3591
3592 /// Returns the preheader of the vector loop region, if one exists, or null
3593 /// otherwise.
3595 VPRegionBlock *VectorRegion = getVectorLoopRegion();
3596 return VectorRegion
3597 ? cast<VPBasicBlock>(VectorRegion->getSinglePredecessor())
3598 : nullptr;
3599 }
3600
3601 /// Returns the VPRegionBlock of the vector loop.
3603 const VPRegionBlock *getVectorLoopRegion() const;
3604
3605 /// Returns the 'middle' block of the plan, that is the block that selects
3606 /// whether to execute the scalar tail loop or the exit block from the loop
3607 /// latch.
3609 return cast<VPBasicBlock>(getScalarPreheader()->getPredecessors().front());
3610 }
3612 return cast<VPBasicBlock>(getScalarPreheader()->getPredecessors().front());
3613 }
3614
3615 /// Return the VPBasicBlock for the preheader of the scalar loop.
3617 return cast<VPBasicBlock>(getScalarHeader()->getSinglePredecessor());
3618 }
3619
3620 /// Return the VPIRBasicBlock wrapping the header of the scalar loop.
3621 VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; }
3622
3623 /// Return an iterator range over the VPIRBasicBlock wrapping the exit blocks
3624 /// of the VPlan, that is leaf nodes except the scalar header. Defined in
3625 /// VPlanHCFG, as the definition of the type needs access to the definitions
3626 /// of VPBlockShallowTraversalWrapper.
3627 auto getExitBlocks();
3628
3629 /// Returns true if \p VPBB is an exit block.
3630 bool isExitBlock(VPBlockBase *VPBB);
3631
3632 /// The trip count of the original loop.
3634 assert(TripCount && "trip count needs to be set before accessing it");
3635 return TripCount;
3636 }
3637
3638 /// Resets the trip count for the VPlan. The caller must make sure all uses of
3639 /// the original trip count have been replaced.
3640 void resetTripCount(VPValue *NewTripCount) {
3641 assert(TripCount && NewTripCount && TripCount->getNumUsers() == 0 &&
3642 "TripCount always must be set");
3643 TripCount = NewTripCount;
3644 }
3645
3646 /// The backedge taken count of the original loop.
3648 if (!BackedgeTakenCount)
3649 BackedgeTakenCount = new VPValue();
3650 return BackedgeTakenCount;
3651 }
3652
3653 /// The vector trip count.
3654 VPValue &getVectorTripCount() { return VectorTripCount; }
3655
3656 /// Returns the VF of the vector loop region.
3657 VPValue &getVF() { return VF; };
3658
3659 /// Returns VF * UF of the vector loop region.
3660 VPValue &getVFxUF() { return VFxUF; }
3661
3662 void addVF(ElementCount VF) { VFs.insert(VF); }
3663
3665 assert(hasVF(VF) && "Cannot set VF not already in plan");
3666 VFs.clear();
3667 VFs.insert(VF);
3668 }
3669
3670 bool hasVF(ElementCount VF) { return VFs.count(VF); }
3672 return any_of(VFs, [](ElementCount VF) { return VF.isScalable(); });
3673 }
3674
3675 /// Returns an iterator range over all VFs of the plan.
3678 return {VFs.begin(), VFs.end()};
3679 }
3680
3681 bool hasScalarVFOnly() const { return VFs.size() == 1 && VFs[0].isScalar(); }
3682
3683 bool hasUF(unsigned UF) const { return UFs.empty() || UFs.contains(UF); }
3684
3685 unsigned getUF() const {
3686 assert(UFs.size() == 1 && "Expected a single UF");
3687 return UFs[0];
3688 }
3689
3690 void setUF(unsigned UF) {
3691 assert(hasUF(UF) && "Cannot set the UF not already in plan");
3692 UFs.clear();
3693 UFs.insert(UF);
3694 }
3695
3696 /// Return a string with the name of the plan and the applicable VFs and UFs.
3697 std::string getName() const;
3698
3699 void setName(const Twine &newName) { Name = newName.str(); }
3700
3701 /// Gets the live-in VPValue for \p V or adds a new live-in (if none exists
3702 /// yet) for \p V.
3704 assert(V && "Trying to get or add the VPValue of a null Value");
3705 if (!Value2VPValue.count(V)) {
3706 VPValue *VPV = new VPValue(V);
3707 VPLiveInsToFree.push_back(VPV);
3708 assert(VPV->isLiveIn() && "VPV must be a live-in.");
3709 assert(!Value2VPValue.count(V) && "Value already exists in VPlan");
3710 Value2VPValue[V] = VPV;
3711 }
3712
3713 assert(Value2VPValue.count(V) && "Value does not exist in VPlan");
3714 assert(Value2VPValue[V]->isLiveIn() &&
3715 "Only live-ins should be in mapping");
3716 return Value2VPValue[V];
3717 }
3718
3719 /// Return the live-in VPValue for \p V, if there is one or nullptr otherwise.
3720 VPValue *getLiveIn(Value *V) const { return Value2VPValue.lookup(V); }
3721
3722#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3723 /// Print the live-ins of this VPlan to \p O.
3724 void printLiveIns(raw_ostream &O) const;
3725
3726 /// Print this VPlan to \p O.
3727 void print(raw_ostream &O) const;
3728
3729 /// Print this VPlan in DOT format to \p O.
3730 void printDOT(raw_ostream &O) const;
3731
3732 /// Dump the plan to stderr (for debugging).
3733 LLVM_DUMP_METHOD void dump() const;
3734#endif
3735
3736 /// Returns the canonical induction recipe of the vector loop.
3739 if (EntryVPBB->empty()) {
3740 // VPlan native path.
3741 EntryVPBB = cast<VPBasicBlock>(EntryVPBB->getSingleSuccessor());
3742 }
3743 return cast<VPCanonicalIVPHIRecipe>(&*EntryVPBB->begin());
3744 }
3745
3746 VPValue *getSCEVExpansion(const SCEV *S) const {
3747 return SCEVToExpansion.lookup(S);
3748 }
3749
3750 void addSCEVExpansion(const SCEV *S, VPValue *V) {
3751 assert(!SCEVToExpansion.contains(S) && "SCEV already expanded");
3752 SCEVToExpansion[S] = V;
3753 }
3754
3755 /// Clone the current VPlan, update all VPValues of the new VPlan and cloned
3756 /// recipes to refer to the clones, and return it.
3757 VPlan *duplicate();
3758
3759 /// Create a new VPBasicBlock with \p Name and containing \p Recipe if
3760 /// present. The returned block is owned by the VPlan and deleted once the
3761 /// VPlan is destroyed.
3763 VPRecipeBase *Recipe = nullptr) {
3764 auto *VPB = new VPBasicBlock(Name, Recipe);
3765 CreatedBlocks.push_back(VPB);
3766 return VPB;
3767 }
3768
3769 /// Create a new VPRegionBlock with \p Entry, \p Exiting and \p Name. If \p
3770 /// IsReplicator is true, the region is a replicate region. The returned block
3771 /// is owned by the VPlan and deleted once the VPlan is destroyed.
3773 const std::string &Name = "",
3774 bool IsReplicator = false) {
3775 auto *VPB = new VPRegionBlock(Entry, Exiting, Name, IsReplicator);
3776 CreatedBlocks.push_back(VPB);
3777 return VPB;
3778 }
3779
3780 /// Create a new VPRegionBlock with \p Name and entry and exiting blocks set
3781 /// to nullptr. If \p IsReplicator is true, the region is a replicate region.
3782 /// The returned block is owned by the VPlan and deleted once the VPlan is
3783 /// destroyed.
3784 VPRegionBlock *createVPRegionBlock(const std::string &Name = "",
3785 bool IsReplicator = false) {
3786 auto *VPB = new VPRegionBlock(Name, IsReplicator);
3787 CreatedBlocks.push_back(VPB);
3788 return VPB;
3789 }
3790
3791 /// Create a VPIRBasicBlock wrapping \p IRBB, but do not create
3792 /// VPIRInstructions wrapping the instructions in t\p IRBB. The returned
3793 /// block is owned by the VPlan and deleted once the VPlan is destroyed.
3795
3796 /// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
3797 /// instructions in \p IRBB, except its terminator which is managed by the
3798 /// successors of the block in VPlan. The returned block is owned by the VPlan
3799 /// and deleted once the VPlan is destroyed.
3801};
3802
3803#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3805 const Value *V;
3806
3807 VPlanIngredient(const Value *V) : V(V) {}
3808
3809 void print(raw_ostream &O) const;
3810};
3811
3813 I.print(OS);
3814 return OS;
3815}
3816
3818 Plan.print(OS);
3819 return OS;
3820}
3821#endif
3822
3823} // end namespace llvm
3824
3825#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
aarch64 promote const
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
always inline
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
RelocType Type
Definition: COFFYAML.cpp:410
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:622
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
uint64_t Addr
std::string Name
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1315
Hexagon Common GEP
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements the SmallBitVector class.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains the declarations of the entities induced by Vectorization Plans,...
#define VP_CLASSOF_IMPL(VPDefID)
Definition: VPlan.h:471
static const uint32_t IV[8]
Definition: blake3_impl.h:78
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:198
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:444
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition: InstrTypes.h:608
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:673
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Definition: CmpPredicate.h:22
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:194
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:152
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:147
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition: Operator.h:205
Convenience struct for specifying and reasoning about fast-math flags.
Definition: FMF.h:20
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:933
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:310
The group of interleaved loads/stores sharing the same stride and close to each other.
Definition: VectorUtils.h:488
uint32_t getFactor() const
Definition: VectorUtils.h:504
InstTy * getMember(uint32_t Index) const
Get the member with the given index Index.
Definition: VectorUtils.h:558
InstTy * getInsertPos() const
Definition: VectorUtils.h:574
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
An instruction for reading from memory.
Definition: Instructions.h:176
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:39
bool onlyWritesMemory() const
Whether this function only (at most) writes memory.
Definition: ModRef.h:198
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition: ModRef.h:195
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.
Definition: IVDescriptors.h:77
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:98
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:113
void clear()
Completely clear the SetVector.
Definition: SetVector.h:273
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:264
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:93
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Definition: SetVector.h:254
This class provides computation of slot numbers for LLVM Assembly writing.
Definition: AsmWriter.cpp:698
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
iterator erase(const_iterator CI)
Definition: SmallVector.h:737
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
An instruction for storing to memory.
Definition: Instructions.h:292
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
Definition: VPlan.h:2958
void execute(VPTransformState &State) override
Generate the active lane mask phi of the vector loop.
VPActiveLaneMaskPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2966
static bool classof(const VPHeaderPHIRecipe *D)
Definition: VPlan.h:2975
VPActiveLaneMaskPHIRecipe(VPValue *StartMask, DebugLoc DL)
Definition: VPlan.h:2960
~VPActiveLaneMaskPHIRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:3200
RecipeListTy::const_iterator const_iterator
Definition: VPlan.h:3228
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition: VPlan.h:3275
RecipeListTy::const_reverse_iterator const_reverse_iterator
Definition: VPlan.h:3230
RecipeListTy::iterator iterator
Instruction iterators...
Definition: VPlan.h:3227
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition: VPlan.cpp:482
RecipeListTy & getRecipeList()
Returns a reference to the list of recipes.
Definition: VPlan.h:3253
VPBasicBlock(const unsigned char BlockSC, const Twine &Name="")
Definition: VPlan.h:3217
iterator end()
Definition: VPlan.h:3237
iterator begin()
Recipe iterator methods.
Definition: VPlan.h:3235
RecipeListTy::reverse_iterator reverse_iterator
Definition: VPlan.h:3229
VPBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition: VPlan.cpp:526
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition: VPlan.h:3288
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of this VPBasicBlock.
Definition: VPlan.cpp:772
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition: VPlan.cpp:210
void connectToPredecessors(VPTransformState &State)
Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block generated for this VPBB.
Definition: VPlan.cpp:416
~VPBasicBlock() override
Definition: VPlan.h:3221
VPRegionBlock * getEnclosingLoopRegion()
Definition: VPlan.cpp:575
const_reverse_iterator rbegin() const
Definition: VPlan.h:3241
reverse_iterator rend()
Definition: VPlan.h:3242
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition: VPlan.cpp:545
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition: VPlan.h:3215
void executeRecipes(VPTransformState *State, BasicBlock *BB)
Execute the recipes in the IR basic block BB.
Definition: VPlan.cpp:533
VPRecipeBase & back()
Definition: VPlan.h:3250
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPBsicBlock to O, prefixing all lines with Indent.
Definition: VPlan.cpp:645
const VPRecipeBase & front() const
Definition: VPlan.h:3247
const_iterator begin() const
Definition: VPlan.h:3236
VPRecipeBase & front()
Definition: VPlan.h:3248
bool isExiting() const
Returns true if the block is exiting it's parent region.
Definition: VPlan.cpp:623
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition: VPlan.cpp:611
const VPRecipeBase & back() const
Definition: VPlan.h:3249
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition: VPlan.h:3266
bool empty() const
Definition: VPlan.h:3246
const_iterator end() const
Definition: VPlan.h:3238
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:3261
static RecipeListTy VPBasicBlock::* getSublistAccess(VPRecipeBase *)
Returns a pointer to a member of the recipe list.
Definition: VPlan.h:3256
reverse_iterator rbegin()
Definition: VPlan.h:3240
size_t size() const
Definition: VPlan.h:3245
const_reverse_iterator rend() const
Definition: VPlan.h:3243
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition: VPlan.h:2158
VPBlendRecipe(PHINode *Phi, ArrayRef< VPValue * > Operands)
The blend operation is a User of the incoming values and of their respective masks,...
Definition: VPlan.h:2164
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenMemoryRecipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2211
VPValue * getIncomingValue(unsigned Idx) const
Return incoming value number Idx.
Definition: VPlan.h:2187
VPValue * getMask(unsigned Idx) const
Return mask number Idx.
Definition: VPlan.h:2192
unsigned getNumIncomingValues() const
Return the number of incoming values, taking into account when normalized the first incoming value wi...
Definition: VPlan.h:2182
VPBlendRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2169
void execute(VPTransformState &State) override
Generate the phi/select nodes.
bool isNormalized() const
A normalized blend is one that has an odd number of operands, whereby the first operand does not have...
Definition: VPlan.h:2178
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:78
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition: VPlan.h:294
VPRegionBlock * getParent()
Definition: VPlan.h:170
VPBlocksTy & getPredecessors()
Definition: VPlan.h:202
iterator_range< VPBlockBase ** > predecessors()
Definition: VPlan.h:199
const VPBasicBlock * getExitingBasicBlock() const
Definition: VPlan.cpp:180
LLVM_DUMP_METHOD void dump() const
Dump this VPBlockBase to dbgs().
Definition: VPlan.h:350
void setName(const Twine &newName)
Definition: VPlan.h:163
size_t getNumSuccessors() const
Definition: VPlan.h:216
iterator_range< VPBlockBase ** > successors()
Definition: VPlan.h:198
virtual void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Print plain-text dump of this VPBlockBase to O, prefixing all lines with Indent.
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
Definition: VPlan.h:309
void printSuccessors(raw_ostream &O, const Twine &Indent) const
Print the successors of this block to O, prefixing all lines with Indent.
Definition: VPlan.cpp:633
bool isLegalToHoistInto()
Return true if it is legal to hoist instructions into this block.
Definition: VPlan.h:322
virtual ~VPBlockBase()=default
const VPBlocksTy & getHierarchicalPredecessors()
Definition: VPlan.h:252
size_t getNumPredecessors() const
Definition: VPlan.h:217
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition: VPlan.h:285
VPBlockBase * getEnclosingBlockWithPredecessors()
Definition: VPlan.cpp:202
const VPBlocksTy & getPredecessors() const
Definition: VPlan.h:201
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC } VPBlockTy
An enumeration for keeping track of the concrete subclass of VPBlockBase that are actually instantiat...
Definition: VPlan.h:155
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
VPlan * getPlan()
Definition: VPlan.cpp:155
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
Definition: VPlan.cpp:174
const VPRegionBlock * getParent() const
Definition: VPlan.h:171
const std::string & getName() const
Definition: VPlan.h:161
void clearSuccessors()
Remove all the successors of this block.
Definition: VPlan.h:304
VPBlockBase * getSingleHierarchicalSuccessor()
Definition: VPlan.h:242
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition: VPlan.h:276
VPBlockBase * getSinglePredecessor() const
Definition: VPlan.h:212
virtual void execute(VPTransformState *State)=0
The method which generates the output IR that correspond to this VPBlockBase, thereby "executing" the...
const VPBlocksTy & getHierarchicalSuccessors()
Definition: VPlan.h:236
void clearPredecessors()
Remove all the predecessor of this block.
Definition: VPlan.h:301
unsigned getVPBlockID() const
Definition: VPlan.h:168
void printAsOperand(raw_ostream &OS, bool PrintType=false) const
Definition: VPlan.h:329
VPBlockBase(const unsigned char SC, const std::string &N)
Definition: VPlan.h:147
VPBlocksTy & getSuccessors()
Definition: VPlan.h:196
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
Definition: VPlan.cpp:194
const VPBasicBlock * getEntryBasicBlock() const
Definition: VPlan.cpp:160
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
Definition: VPlan.h:265
void setParent(VPRegionBlock *P)
Definition: VPlan.h:181
VPBlockBase * getSingleHierarchicalPredecessor()
Definition: VPlan.h:258
VPBlockBase * getSingleSuccessor() const
Definition: VPlan.h:206
const VPBlocksTy & getSuccessors() const
Definition: VPlan.h:195
Class that provides utilities for VPBlockBases in VPlan.
Definition: VPlanUtils.h:79
A recipe for generating conditional branches on the bits of a mask.
Definition: VPlan.h:2518
VPValue * getMask() const
Return the mask used by this recipe.
Definition: VPlan.h:2554
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPBranchOnMaskRecipe.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Definition: VPlan.h:2542
VPBranchOnMaskRecipe(VPValue *BlockInMask)
Definition: VPlan.h:2520
VPBranchOnMaskRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2526
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2561
void execute(VPTransformState &State) override
Generate the extraction of the appropriate bit from the block mask and the conditional branch.
VPlan-based builder utility analogous to IRBuilder.
Canonical scalar induction phi of the vector loop.
Definition: VPlan.h:2897
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition: VPlan.h:2940
~VPCanonicalIVPHIRecipe() override=default
static bool classof(const VPHeaderPHIRecipe *D)
Definition: VPlan.h:2912
VPCanonicalIVPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2904
VPCanonicalIVPHIRecipe(VPValue *StartV, DebugLoc DL)
Definition: VPlan.h:2899
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2933
Type * getScalarType() const
Returns the scalar type of the induction.
Definition: VPlan.h:2928
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition: VPlan.h:2916
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPCanonicalIVPHIRecipe.
Definition: VPlan.h:2947
This class augments a recipe with a set of VPValues defined by the recipe.
Definition: VPlanValue.h:298
unsigned getVPDefID() const
Definition: VPlanValue.h:426
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition: VPlan.h:3074
void execute(VPTransformState &State) override
Generate the transformed value of the induction at offset StartValue (1.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPDerivedIVRecipe.
Definition: VPlan.h:3113
VPValue * getStepValue() const
Definition: VPlan.h:3130
Type * getScalarType() const
Definition: VPlan.h:3125
VPDerivedIVRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3101
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV, VPValue *Step, const Twine &Name="")
Definition: VPlan.h:3093
~VPDerivedIVRecipe() override=default
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3133
VPValue * getStartValue() const
Definition: VPlan.h:3129
VPDerivedIVRecipe(const InductionDescriptor &IndDesc, VPValue *Start, VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step, const Twine &Name="")
Definition: VPlan.h:3085
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
Definition: VPlan.h:2993
static bool classof(const VPHeaderPHIRecipe *D)
Definition: VPlan.h:3006
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPEVLBasedIVPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3000
~VPEVLBasedIVPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition: VPlan.h:3010
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPEVLBasedIVPHIRecipe.
Definition: VPlan.h:3016
VPEVLBasedIVPHIRecipe(VPValue *StartIV, DebugLoc DL)
Definition: VPlan.h:2995
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3023
Recipe to expand a SCEV expression.
Definition: VPlan.h:2858
VPExpandSCEVRecipe(const SCEV *Expr, ScalarEvolution &SE)
Definition: VPlan.h:2863
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPExpandSCEVRecipe.
Definition: VPlan.h:2878
const SCEV * getSCEV() const
Definition: VPlan.h:2890
void execute(VPTransformState &State) override
Generate a canonical vector induction variable of the vector loop, with.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPExpandSCEVRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2868
~VPExpandSCEVRecipe() override=default
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition: VPlan.h:1692
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this header phi recipe.
static bool classof(const VPValue *V)
Definition: VPlan.h:1709
VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr, VPValue *Start=nullptr, DebugLoc DL={})
Definition: VPlan.h:1694
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override=0
Print the recipe.
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition: VPlan.h:1740
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition: VPlan.h:1729
void setStartValue(VPValue *V)
Update the start value of the recipe.
Definition: VPlan.h:1737
VPValue * getStartValue() const
Definition: VPlan.h:1732
static bool classof(const VPRecipeBase *B)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:1705
void execute(VPTransformState &State) override=0
Generate the phi nodes.
virtual VPRecipeBase & getBackedgeRecipe()
Returns the backedge value as a recipe.
Definition: VPlan.h:1746
~VPHeaderPHIRecipe() override=default
A recipe representing a sequence of load -> update -> store as part of a histogram operation.
Definition: VPlan.h:1442
void execute(VPTransformState &State) override
Produce a vectorized histogram operation.
VP_CLASSOF_IMPL(VPDef::VPHistogramSC)
VPHistogramRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1454
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHistogramRecipe.
VPHistogramRecipe(unsigned Opcode, iterator_range< IterT > Operands, DebugLoc DL={})
Definition: VPlan.h:1448
VPValue * getMask() const
Return the mask operand if one was provided, or a null pointer if all lanes should be executed uncond...
Definition: VPlan.h:1471
unsigned getOpcode() const
Definition: VPlan.h:1467
~VPHistogramRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition: VPlan.h:3342
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition: VPlan.cpp:453
BasicBlock * getIRBasicBlock() const
Definition: VPlan.h:3366
~VPIRBasicBlock() override
Definition: VPlan.h:3354
static bool classof(const VPBlockBase *V)
Definition: VPlan.h:3356
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition: VPlan.cpp:475
A recipe to wrap on original IR instruction not to be modified during execution, execept for PHIs.
Definition: VPlan.h:1036
Instruction & getInstruction() const
Definition: VPlan.h:1060
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first part of operand Op.
Definition: VPlan.h:1074
~VPIRInstruction() override=default
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1080
VPIRInstruction * clone() override
Clone the current recipe.
Definition: VPlan.h:1047
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPIRInstruction.
void extractLastLaneOfOperand(VPBuilder &Builder)
Update the recipes single operand to the last lane of the operand using Builder.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool usesScalars(const VPValue *Op) const override
Returns true if the VPUser uses scalars of operand Op.
Definition: VPlan.h:1068
VPIRInstruction(Instruction &I)
Definition: VPlan.h:1040
This is a concrete Recipe that models a single VPlan-level instruction.
Definition: VPlan.h:845
VPInstruction(VPValue *Ptr, VPValue *Offset, GEPNoWrapFlags Flags, DebugLoc DL={}, const Twine &Name="")
Definition: VPlan.h:948
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
Definition: VPlan.h:923
VPInstruction * clone() override
Clone the current recipe.
Definition: VPlan.h:959
@ ResumePhi
Creates a scalar phi in a leaf VPBB with a single predecessor in VPlan.
Definition: VPlan.h:863
@ FirstOrderRecurrenceSplice
Definition: VPlan.h:851
@ CanonicalIVIncrementForPart
Definition: VPlan.h:866
@ ComputeReductionResult
Definition: VPlan.h:869
@ CalculateTripCountMinusVF
Definition: VPlan.h:864
bool hasResult() const
Definition: VPlan.h:989
bool opcodeMayReadOrWriteFromMemory() const
Returns true if the underlying opcode may read from or write to memory.
LLVM_DUMP_METHOD void dump() const
Print the VPInstruction to dbgs() (for debugging).
StringRef getName() const
Returns the symbolic name assigned to the VPInstruction.
Definition: VPlan.h:1029
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInstruction.
Definition: VPlan.h:974
unsigned getOpcode() const
Definition: VPlan.h:966
VPInstruction(unsigned Opcode, std::initializer_list< VPValue * > Operands, WrapFlagsTy WrapFlags, DebugLoc DL={}, const Twine &Name="")
Definition: VPlan.h:935
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
VPInstruction(unsigned Opcode, std::initializer_list< VPValue * > Operands, DebugLoc DL={}, const Twine &Name="")
Definition: VPlan.h:928
VPInstruction(unsigned Opcode, std::initializer_list< VPValue * > Operands, DisjointFlagsTy DisjointFlag, DebugLoc DL={}, const Twine &Name="")
Definition: VPlan.h:940
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the VPInstruction to O.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
bool isSingleScalar() const
Returns true if this VPInstruction's operands are single scalars and the result is also a single scal...
void execute(VPTransformState &State) override
Generate the instruction.
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
Definition: VPlan.h:2225
bool onlyFirstLaneUsed(const VPValue *Op) const override
The recipe only uses the first lane of the address.
Definition: VPlan.h:2308
~VPInterleaveRecipe() override=default
VPValue * getAddr() const
Return the address accessed by this recipe.
Definition: VPlan.h:2266
VPInterleaveRecipe(const InterleaveGroup< Instruction > *IG, VPValue *Addr, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps)
Definition: VPlan.h:2237
VPValue * getMask() const
Return the mask used by this recipe.
Definition: VPlan.h:2272
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPInterleaveRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2258
void execute(VPTransformState &State) override
Generate the wide load or store, and shuffles.
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
Definition: VPlan.h:2279
Instruction * getInsertPos() const
Definition: VPlan.h:2314
const InterleaveGroup< Instruction > * getInterleaveGroup()
Definition: VPlan.h:2299
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInterleaveRecipe.
unsigned getNumStoreOperands() const
Returns the number of stored operands of this interleave group.
Definition: VPlan.h:2303
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
Definition: VPlanHelpers.h:116
A recipe for forming partial reductions.
Definition: VPlan.h:2111
~VPPartialReductionRecipe() override=default
void execute(VPTransformState &State) override
Generate the reduction in the loop.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPartialReductionRecipe.
unsigned getOpcode() const
Get the binary op's opcode.
Definition: VPlan.h:2147
VPPartialReductionRecipe(unsigned Opcode, VPValue *Op0, VPValue *Op1, Instruction *ReductionInst=nullptr)
Definition: VPlan.h:2119
VPPartialReductionRecipe(Instruction *ReductionInst, VPValue *Op0, VPValue *Op1)
Definition: VPlan.h:2115
VPPartialReductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2132
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition: VPlan.h:2573
~VPPredInstPHIRecipe() override=default
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2605
void execute(VPTransformState &State) override
Generates phi nodes for live-outs (from a replicate region) as needed to retain SSA form.
VPPredInstPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2581
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPredInstPHIRecipe.
Definition: VPlan.h:2592
VPPredInstPHIRecipe(VPValue *PredV, DebugLoc DL)
Construct a VPPredInstPHIRecipe given PredInst whose value needs a phi nodes after merging back from ...
Definition: VPlan.h:2577
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition: VPlan.h:366
bool mayReadFromMemory() const
Returns true if the recipe may read from memory.
bool mayReadOrWriteMemory() const
Returns true if the recipe may read from or write to memory.
Definition: VPlan.h:455
bool mayHaveSideEffects() const
Returns true if the recipe may have side-effects.
bool mayWriteToMemory() const
Returns true if the recipe may write to memory.
virtual InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const
Compute the cost of this recipe either using a recipe's specialized implementation or using the legac...
virtual ~VPRecipeBase()=default
VPBasicBlock * getParent()
Definition: VPlan.h:391
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition: VPlan.h:460
virtual void execute(VPTransformState &State)=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
void moveBefore(VPBasicBlock &BB, iplist< VPRecipeBase >::iterator I)
Unlink this recipe and insert into BB before I.
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
static bool classof(const VPDef *D)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:433
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
VPRecipeBase(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL={})
Definition: VPlan.h:377
virtual VPRecipeBase * clone()=0
Clone the current recipe.
const VPBasicBlock * getParent() const
Definition: VPlan.h:392
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this recipe, taking into account if the cost computation should be skipped and the...
static bool classof(const VPUser *U)
Definition: VPlan.h:438
VPRecipeBase(const unsigned char SC, iterator_range< IterT > Operands, DebugLoc DL={})
Definition: VPlan.h:382
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
bool isPhi() const
Returns true for PHI-like recipes.
Definition: VPlan.h:444
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
Class to record LLVM IR flag for a recipe along with it.
Definition: VPlan.h:577
ExactFlagsTy ExactFlags
Definition: VPlan.h:627
FastMathFlagsTy FMFs
Definition: VPlan.h:630
NonNegFlagsTy NonNegFlags
Definition: VPlan.h:629
CmpInst::Predicate CmpPredicate
Definition: VPlan.h:624
GEPNoWrapFlags getGEPNoWrapFlags() const
Definition: VPlan.h:798
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, CmpInst::Predicate Pred, DebugLoc DL={})
Definition: VPlan.h:679
void setFlags(Instruction *I) const
Set the IR flags for I.
Definition: VPlan.h:759
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, GEPNoWrapFlags GEPFlags, DebugLoc DL={})
Definition: VPlan.h:704
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:710
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, FastMathFlags FMFs, DebugLoc DL={})
Definition: VPlan.h:691
void dropPoisonGeneratingFlags()
Drop all poison-generating flags.
Definition: VPlan.h:728
bool hasFastMathFlags() const
Returns true if the recipe has fast-math flags.
Definition: VPlan.h:801
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, Instruction &I)
Definition: VPlan.h:649
DisjointFlagsTy DisjointFlags
Definition: VPlan.h:626
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, WrapFlagsTy WrapFlags, DebugLoc DL={})
Definition: VPlan.h:685
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, DisjointFlagsTy DisjointFlags, DebugLoc DL={})
Definition: VPlan.h:697
GEPNoWrapFlags GEPFlags
Definition: VPlan.h:628
void transferFlags(VPRecipeWithIRFlags &Other)
Definition: VPlan.h:635
WrapFlagsTy WrapFlags
Definition: VPlan.h:625
bool hasNoUnsignedWrap() const
Definition: VPlan.h:805
bool isDisjoint() const
Definition: VPlan.h:817
void printFlags(raw_ostream &O) const
CmpInst::Predicate getPredicate() const
Definition: VPlan.h:792
bool hasNoSignedWrap() const
Definition: VPlan.h:811
static bool classof(const VPUser *U)
Definition: VPlan.h:722
FastMathFlags getFastMathFlags() const
VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, DebugLoc DL={})
Definition: VPlan.h:642
A recipe to represent inloop reduction operations with vector-predication intrinsics,...
Definition: VPlan.h:2400
void execute(VPTransformState &State) override
Generate the reduction in the loop.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2430
VPValue * getEVL() const
The VPValue of the explicit vector length.
Definition: VPlan.h:2427
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp)
Definition: VPlan.h:2402
VPReductionEVLRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2411
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPReductionEVLRecipe() override=default
A recipe for handling reduction phis.
Definition: VPlan.h:2045
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
Definition: VPlan.h:2101
VPReductionPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2073
~VPReductionPHIRecipe() override=default
VPReductionPHIRecipe(PHINode *Phi, const RecurrenceDescriptor &RdxDesc, VPValue &Start, bool IsInLoop=false, bool IsOrdered=false, unsigned VFScaleFactor=1)
Create a new VPReductionPHIRecipe for the reduction Phi described by RdxDesc.
Definition: VPlan.h:2062
bool isInLoop() const
Returns true, if the phi is part of an in-loop reduction.
Definition: VPlan.h:2104
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi/select nodes.
static bool classof(const VPHeaderPHIRecipe *R)
Definition: VPlan.h:2083
const RecurrenceDescriptor & getRecurrenceDescriptor() const
Definition: VPlan.h:2096
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
Definition: VPlan.h:2320
bool isConditional() const
Return true if the in-loop reduction is conditional.
Definition: VPlan.h:2385
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:2355
VPReductionRecipe(const RecurrenceDescriptor &R, Instruction *I, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, bool IsOrdered, DebugLoc DL={})
Definition: VPlan.h:2340
VPReductionRecipe(const unsigned char SC, const RecurrenceDescriptor &R, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, bool IsOrdered, DebugLoc DL)
Definition: VPlan.h:2328
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of VPReductionRecipe.
VPValue * getVecOp() const
The VPValue of the vector value to be reduced.
Definition: VPlan.h:2389
const RecurrenceDescriptor & getRecurrenceDescriptor() const
Return the recurrence decriptor for the in-loop reduction.
Definition: VPlan.h:2379
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPValue * getCondOp() const
The VPValue of the condition for the block.
Definition: VPlan.h:2391
bool isOrdered() const
Return true if the in-loop reduction is ordered.
Definition: VPlan.h:2383
~VPReductionRecipe() override=default
VPValue * getChainOp() const
The VPValue of the scalar Chain being accumulated.
Definition: VPlan.h:2387
VPReductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2349
void execute(VPTransformState &State) override
Generate the reduction in the loop.
static bool classof(const VPUser *U)
Definition: VPlan.h:2360
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition: VPlan.h:3377
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
Definition: VPlan.cpp:716
const VPBlockBase * getEntry() const
Definition: VPlan.h:3413
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition: VPlan.h:3445
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
Definition: VPlan.h:3430
VPBlockBase * getExiting()
Definition: VPlan.h:3426
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
Definition: VPlan.h:3418
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of the block.
Definition: VPlan.cpp:779
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPRegionBlock to O (recursively), prefixing all lines with Indent.
Definition: VPlan.cpp:817
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock,...
Definition: VPlan.cpp:725
const VPBlockBase * getExiting() const
Definition: VPlan.h:3425
VPBlockBase * getEntry()
Definition: VPlan.h:3414
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
Definition: VPlan.h:3438
~VPRegionBlock() override
Definition: VPlan.h:3406
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:3409
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition: VPlan.h:2441
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate replicas of the desired Ingredient.
~VPReplicateRecipe() override=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPReplicateRecipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2490
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2497
bool isUniform() const
Definition: VPlan.h:2485
bool isPredicated() const
Definition: VPlan.h:2487
VPReplicateRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2460
VPReplicateRecipe(Instruction *I, iterator_range< IterT > Operands, bool IsUniform, VPValue *Mask=nullptr)
Definition: VPlan.h:2450
unsigned getOpcode() const
Definition: VPlan.h:2514
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
Definition: VPlan.h:2509
bool shouldPack() const
Returns true if the recipe is used by a widened recipe via an intervening VPPredInstPHIRecipe.
A recipe to compute the pointers for widened memory accesses of IndexTy in reverse order.
Definition: VPlan.h:1569
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPVectorPointerRecipe.
Definition: VPlan.h:1593
VPReverseVectorPointerRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1607
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition: VPlan.h:1600
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1586
VPReverseVectorPointerRecipe(VPValue *Ptr, VPValue *VF, Type *IndexedTy, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition: VPlan.h:1573
const VPValue * getVFValue() const
Definition: VPlan.h:1582
VPScalarCastRecipe is a recipe to create scalar cast instructions.
Definition: VPlan.h:1246
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPScalarCastRecipe.
Definition: VPlan.h:1271
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Each concrete VPDef prints itself.
~VPScalarCastRecipe() override=default
VPScalarCastRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1261
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1285
VPScalarCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL)
Definition: VPlan.h:1254
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Type * getResultType() const
Returns the result type of the cast.
Definition: VPlan.h:1283
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition: VPlan.h:3143
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3190
VPValue * getStepValue() const
Definition: VPlan.h:3187
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPScalarIVStepsRecipe.
Definition: VPlan.h:3175
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc, VPValue *IV, VPValue *Step)
Definition: VPlan.h:3153
VPScalarIVStepsRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3163
VPScalarIVStepsRecipe(VPValue *IV, VPValue *Step, Instruction::BinaryOps Opcode, FastMathFlags FMFs)
Definition: VPlan.h:3147
~VPScalarIVStepsRecipe() override=default
void execute(VPTransformState &State) override
Generate the scalarized versions of the phi node as needed by their users.
Recipe to generate a scalar PHI.
Definition: VPlan.h:1928
VPScalarPHIRecipe(VPValue *Start, VPValue *BackedgeValue, DebugLoc DL, StringRef Name)
Definition: VPlan.h:1932
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:1951
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPScalarPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the phi/select nodes.
VPScalarPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1941
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Definition: VPlan.h:493
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL={})
Definition: VPlan.h:499
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
Definition: VPlan.h:563
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:508
const Instruction * getUnderlyingInstr() const
Definition: VPlan.h:566
VPSingleDefRecipe(const unsigned char SC, IterT Operands, DebugLoc DL={})
Definition: VPlan.h:496
static bool classof(const VPUser *U)
Definition: VPlan.h:555
LLVM_DUMP_METHOD void dump() const
Print this VPSingleDefRecipe to dbgs() (for debugging).
VPSingleDefRecipe(const unsigned char SC, IterT Operands, Value *UV, DebugLoc DL={})
Definition: VPlan.h:504
virtual VPSingleDefRecipe * clone() override=0
Clone the current recipe.
This class can be used to assign names to VPValues.
Definition: VPlanHelpers.h:389
Helper to access the operand that contains the unroll part for this recipe after unrolling.
Definition: VPlan.h:830
VPValue * getUnrollPartOperand(VPUser &U) const
Return the VPValue operand containing the unroll part or null if there is no such operand.
unsigned getUnrollPart(VPUser &U) const
Return the unroll part.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition: VPlanValue.h:206
operand_range operands()
Definition: VPlanValue.h:263
void setOperand(unsigned I, VPValue *New)
Definition: VPlanValue.h:248
unsigned getNumOperands() const
Definition: VPlanValue.h:242
operand_iterator op_end()
Definition: VPlanValue.h:261
operand_iterator op_begin()
Definition: VPlanValue.h:259
VPValue * getOperand(unsigned N) const
Definition: VPlanValue.h:243
VPUser()=delete
void addOperand(VPValue *Operand)
Definition: VPlanValue.h:237
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop region.
Definition: VPlan.cpp:1435
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition: VPlan.cpp:125
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition: VPlanValue.h:89
unsigned getNumUsers() const
Definition: VPlanValue.h:117
Value * getLiveInIRValue()
Returns the underlying IR value, if this VPValue is defined outside the scope of VPlan.
Definition: VPlanValue.h:178
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
Definition: VPlanValue.h:173
friend class VPRecipeBase
Definition: VPlanValue.h:56
user_range users()
Definition: VPlanValue.h:138
A recipe to compute the pointers for widened memory accesses of IndexTy.
Definition: VPlan.h:1622
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPVectorPointerRecipe(VPValue *Ptr, Type *IndexedTy, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition: VPlan.h:1626
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition: VPlan.h:1643
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1636
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHeaderPHIRecipe.
Definition: VPlan.h:1656
VPVectorPointerRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1650
A recipe for widening Call instructions using library calls.
Definition: VPlan.h:1386
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
const_operand_range arg_operands() const
Definition: VPlan.h:1426
VPWidenCallRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1405
Function * getCalledScalarFunction() const
Definition: VPlan.h:1419
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCallRecipe.
void execute(VPTransformState &State) override
Produce a widened version of the call instruction.
operand_range arg_operands()
Definition: VPlan.h:1423
~VPWidenCallRecipe() override=default
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, DebugLoc DL={})
Definition: VPlan.h:1393
A Recipe for widening the canonical induction variable of the vector loop.
Definition: VPlan.h:3038
void execute(VPTransformState &State) override
Generate a canonical vector induction variable of the vector loop, with start = {<Part*VF,...
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPWidenCanonicalIVRecipe() override=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCanonicalIVPHIRecipe.
Definition: VPlan.h:3058
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3045
VPWidenCanonicalIVRecipe(VPCanonicalIVPHIRecipe *CanonicalIV)
Definition: VPlan.h:3040
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition: VPlan.h:1194
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, CastInst &UI)
Definition: VPlan.h:1202
Instruction::CastOps getOpcode() const
Definition: VPlan.h:1239
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getResultType() const
Returns the result type of the cast.
Definition: VPlan.h:1242
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
Definition: VPlan.h:1210
void execute(VPTransformState &State) override
Produce widened copies of the cast.
~VPWidenCastRecipe() override=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCastRecipe.
VPWidenCastRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1216
A recipe for widening operations with vector-predication intrinsics with explicit vector length (EVL)...
Definition: VPlan.h:1147
const VPValue * getEVL() const
Definition: VPlan.h:1171
~VPWidenEVLRecipe() override=default
VPWidenEVLRecipe(Instruction &I, iterator_range< IterT > Operands, VPValue &EVL)
Definition: VPlan.h:1152
VPWidenRecipe * clone() override final
Clone the current recipe.
Definition: VPlan.h:1163
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override final
Print the recipe.
VP_CLASSOF_IMPL(VPDef::VPWidenEVLSC)
VPWidenEVLRecipe(VPWidenRecipe &W, VPValue &EVL)
Definition: VPlan.h:1156
void execute(VPTransformState &State) override final
Produce a vp-intrinsic using the opcode and operands of the recipe, processing EVL elements.
VPValue * getEVL()
Definition: VPlan.h:1170
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:1178
A recipe for handling GEP instructions.
Definition: VPlan.h:1520
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the gep nodes.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenGEPRecipe.
Definition: VPlan.h:1553
VPWidenGEPRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1542
~VPWidenGEPRecipe() override=default
VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range< IterT > Operands)
Definition: VPlan.h:1537
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
Definition: VPlan.h:1754
static bool classof(const VPValue *V)
Definition: VPlan.h:1770
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
Definition: VPlan.h:1790
PHINode * getPHINode() const
Definition: VPlan.h:1785
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, DebugLoc DL)
Definition: VPlan.h:1758
VPValue * getStepValue()
Returns the step value of the induction.
Definition: VPlan.h:1782
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition: VPlan.h:1788
VPRecipeBase & getBackedgeRecipe() override
Returns the backedge value as a recipe.
Definition: VPlan.h:1797
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:1765
static bool classof(const VPHeaderPHIRecipe *R)
Definition: VPlan.h:1775
const VPValue * getStepValue() const
Definition: VPlan.h:1783
virtual void execute(VPTransformState &State) override=0
Generate the phi nodes.
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition: VPlan.h:1807
const TruncInst * getTruncInst() const
Definition: VPlan.h:1861
const VPValue * getVFValue() const
Definition: VPlan.h:1850
~VPWidenIntOrFpInductionRecipe() override=default
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, TruncInst *Trunc, DebugLoc DL)
Definition: VPlan.h:1820
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1831
TruncInst * getTruncInst()
Returns the first defined value as TruncInst, if it is one or nullptr otherwise.
Definition: VPlan.h:1860
void execute(VPTransformState &State) override
Generate the vectorized and scalarized versions of the phi node as needed by their users.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, DebugLoc DL)
Definition: VPlan.h:1811
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
Definition: VPlan.h:1876
Type * getScalarType() const
Returns the scalar type of the induction.
Definition: VPlan.h:1869
bool isCanonical() const
Returns true if the induction is canonical, i.e.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
A recipe for widening vector intrinsics.
Definition: VPlan.h:1294
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, std::initializer_list< VPValue * > CallArguments, Type *Ty, DebugLoc DL={})
Definition: VPlan.h:1335
Intrinsic::ID getVectorIntrinsicID() const
Return the ID of the intrinsic.
Definition: VPlan.h:1359
bool mayReadFromMemory() const
Returns true if the intrinsic may read from memory.
Definition: VPlan.h:1368
StringRef getIntrinsicName() const
Return to name of the intrinsic as string.
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, DebugLoc DL={})
Definition: VPlan.h:1320
bool mayHaveSideEffects() const
Returns true if the intrinsic may have side-effects.
Definition: VPlan.h:1374
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1343
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
Definition: VPlan.h:1371
~VPWidenIntrinsicRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getResultType() const
Return the scalar return type of the intrinsic.
Definition: VPlan.h:1362
void execute(VPTransformState &State) override
Produce a widened version of the vector intrinsic.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this vector intrinsic.
VPWidenIntrinsicRecipe(CallInst &CI, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, DebugLoc DL={})
Definition: VPlan.h:1311
A common base class for widening memory operations.
Definition: VPlan.h:2614
bool IsMasked
Whether the memory access is masked.
Definition: VPlan.h:2625
bool Reverse
Whether the consecutive accessed addresses are in reverse order.
Definition: VPlan.h:2622
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
Definition: VPlan.h:2661
static bool classof(const VPUser *U)
Definition: VPlan.h:2655
void execute(VPTransformState &State) override
Generate the wide load/store.
Definition: VPlan.h:2681
Instruction & Ingredient
Definition: VPlan.h:2616
VPWidenMemoryRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2644
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenMemoryRecipe.
Instruction & getIngredient() const
Definition: VPlan.h:2689
bool Consecutive
Whether the accessed addresses are consecutive.
Definition: VPlan.h:2619
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:2648
VPWidenMemoryRecipe(const char unsigned SC, Instruction &I, std::initializer_list< VPValue * > Operands, bool Consecutive, bool Reverse, DebugLoc DL)
Definition: VPlan.h:2635
VPValue * getMask() const
Return the mask used by this recipe.
Definition: VPlan.h:2675
bool isMasked() const
Returns true if the recipe is masked.
Definition: VPlan.h:2671
void setMask(VPValue *Mask)
Definition: VPlan.h:2627
VPValue * getAddr() const
Return the address accessed by this recipe.
Definition: VPlan.h:2668
bool isReverse() const
Return whether the consecutive loaded/stored addresses are in reverse order.
Definition: VPlan.h:2665
A recipe for handling phis that are widened in the vector loop.
Definition: VPlan.h:1967
void addIncoming(VPValue *IncomingV, VPBasicBlock *IncomingBlock)
Adds a pair (IncomingV, IncomingBlock) to the phi.
Definition: VPlan.h:1998
VPWidenPHIRecipe(PHINode *Phi, VPValue *Start=nullptr, DebugLoc DL={})
Create a new VPWidenPHIRecipe for Phi with start value Start and debug location DL.
Definition: VPlan.h:1974
VPValue * getIncomingValue(unsigned I)
Returns the I th incoming VPValue.
Definition: VPlan.h:2007
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1980
~VPWidenPHIRecipe() override=default
VPBasicBlock * getIncomingBlock(unsigned I)
Returns the I th incoming VPBasicBlock.
Definition: VPlan.h:2004
void execute(VPTransformState &State) override
Generate the phi/select nodes.
VPWidenPointerInductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1897
~VPWidenPointerInductionRecipe() override=default
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, bool IsScalarAfterVectorization, DebugLoc DL)
Create a new VPWidenPointerInductionRecipe for Phi with start value Start.
Definition: VPlan.h:1888
bool onlyScalarsGenerated(bool IsScalable)
Returns true if only scalar values will be generated.
VPValue * getFirstUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the first unrolled part,...
Definition: VPlan.h:1914
void execute(VPTransformState &State) override
Generate vector values for the pointer induction.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition: VPlan.h:1096
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenRecipe.
void execute(VPTransformState &State) override
Produce a widened instruction using the opcode and operands of the recipe, processing State....
VPWidenRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1112
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPWidenRecipe() override=default
VPWidenRecipe(Instruction &I, iterator_range< IterT > Operands)
Definition: VPlan.h:1107
unsigned getOpcode() const
Definition: VPlan.h:1136
VPWidenRecipe(unsigned VPDefOpcode, Instruction &I, iterator_range< IterT > Operands)
Definition: VPlan.h:1101
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:1118
static bool classof(const VPUser *U)
Definition: VPlan.h:1123
VPlanPrinter prints a given VPlan to a given output stream.
Definition: VPlanHelpers.h:418
Class that maps (parts of) an existing VPlan to trees of combined VPInstructions.
Definition: VPlanSLP.h:72
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition: VPlan.h:3476
void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition: VPlan.cpp:1163
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition: VPlan.cpp:1139
void prepareToExecute(Value *TripCount, Value *VectorTripCount, VPTransformState &State)
Prepare the plan for execution, setting up the required live-in values.
Definition: VPlan.cpp:938
bool hasScalableVF()
Definition: VPlan.h:3671
VPBasicBlock * getEntry()
Definition: VPlan.h:3589
VPRegionBlock * createVPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting, const std::string &Name="", bool IsReplicator=false)
Create a new VPRegionBlock with Entry, Exiting and Name.
Definition: VPlan.h:3772
VPValue & getVectorTripCount()
The vector trip count.
Definition: VPlan.h:3654
void setName(const Twine &newName)
Definition: VPlan.h:3699
VPValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition: VPlan.h:3660
VPValue & getVF()
Returns the VF of the vector loop region.
Definition: VPlan.h:3657
VPValue * getTripCount() const
The trip count of the original loop.
Definition: VPlan.h:3633
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
Definition: VPlan.h:3647
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition: VPlan.h:3677
VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and a tr...
Definition: VPlan.h:3551
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition: VPlan.cpp:967
const VPBasicBlock * getEntry() const
Definition: VPlan.h:3590
unsigned getUF() const
Definition: VPlan.h:3685
static VPlanPtr createInitialVPlan(Type *InductionTy, PredicatedScalarEvolution &PSE, bool RequiresScalarEpilogueCheck, bool TailFolded, Loop *TheLoop)
Create initial VPlan, having an "entry" VPBasicBlock (wrapping original scalar pre-header) which cont...
Definition: VPlan.cpp:859
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition: VPlan.cpp:1264
bool hasVF(ElementCount VF)
Definition: VPlan.h:3670
void addSCEVExpansion(const SCEV *S, VPValue *V)
Definition: VPlan.h:3750
bool hasUF(unsigned UF) const
Definition: VPlan.h:3683
void setVF(ElementCount VF)
Definition: VPlan.h:3664
VPRegionBlock * createVPRegionBlock(const std::string &Name="", bool IsReplicator=false)
Create a new VPRegionBlock with Name and entry and exiting blocks set to nullptr.
Definition: VPlan.h:3784
auto getExitBlocks()
Return an iterator range over the VPIRBasicBlock wrapping the exit blocks of the VPlan,...
Definition: VPlanCFG.h:310
VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition: VPlan.cpp:1070
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition: VPlan.cpp:1064
const VPBasicBlock * getMiddleBlock() const
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
Definition: VPlan.h:3608
void resetTripCount(VPValue *NewTripCount)
Resets the trip count for the VPlan.
Definition: VPlan.h:3640
VPBasicBlock * getMiddleBlock()
Definition: VPlan.h:3611
void setEntry(VPBasicBlock *VPBB)
Definition: VPlan.h:3559
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition: VPlan.h:3762
VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition: VPlan.cpp:1270
VPValue * getOrAddLiveIn(Value *V)
Gets the live-in VPValue for V or adds a new live-in (if none exists yet) for V.
Definition: VPlan.h:3703
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition: VPlan.cpp:1169
bool hasScalarVFOnly() const
Definition: VPlan.h:3681
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition: VPlan.h:3616
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition: VPlan.cpp:974
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the vector loop.
Definition: VPlan.h:3737
void print(raw_ostream &O) const
Print this VPlan to O.
Definition: VPlan.cpp:1122
void addVF(ElementCount VF)
Definition: VPlan.h:3662
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition: VPlan.h:3621
VPValue * getLiveIn(Value *V) const
Return the live-in VPValue for V, if there is one or nullptr otherwise.
Definition: VPlan.h:3720
VPValue * getSCEVExpansion(const SCEV *S) const
Definition: VPlan.h:3746
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition: VPlan.cpp:1086
VPBasicBlock * getVectorPreheader()
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition: VPlan.h:3594
void setUF(unsigned UF)
Definition: VPlan.h:3690
VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
Definition: VPlan.cpp:1210
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An ilist node that can access its parent list.
Definition: ilist_node.h:321
base_list_type::const_reverse_iterator const_reverse_iterator
Definition: ilist.h:125
void pop_back()
Definition: ilist.h:255
base_list_type::reverse_iterator reverse_iterator
Definition: ilist.h:123
base_list_type::const_iterator const_iterator
Definition: ilist.h:122
iterator insert(iterator where, pointer New)
Definition: ilist.h:165
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This file defines classes to implement an intrusive doubly linked list class (i.e.
This file defines the ilist_node class template, which is a convenient base class for creating classe...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
AttributeList getAttributes(LLVMContext &C, ID id)
Return the attributes for an intrinsic.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1759
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1739
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto cast_or_null(const Y &Val)
Definition: Casting.h:720
auto dyn_cast_or_null(const Y &Val)
Definition: Casting.h:759
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
std::unique_ptr< VPlan > VPlanPtr
Definition: VPlan.h:74
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#define N
Struct to hold various analysis needed for cost computations.
Definition: VPlanHelpers.h:356
A recipe for handling first-order recurrence phis.
Definition: VPlan.h:2013
void execute(VPTransformState &State) override
Generate the phi nodes.
VPFirstOrderRecurrencePHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2023
VPFirstOrderRecurrencePHIRecipe(PHINode *Phi, VPValue &Start)
Definition: VPlan.h:2014
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this first-order recurrence phi recipe.
static bool classof(const VPHeaderPHIRecipe *R)
Definition: VPlan.h:2019
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
WrapFlagsTy(bool HasNUW, bool HasNSW)
Definition: VPlan.h:594
VPTransformState holds information passed down when "executing" a VPlan, needed for generating the ou...
Definition: VPlanHelpers.h:196
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition: VPlan.h:2733
void execute(VPTransformState &State) override
Generate the wide load or gather.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenLoadEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
Definition: VPlan.h:2745
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2761
VPWidenLoadEVLRecipe(VPWidenLoadRecipe &L, VPValue &EVL, VPValue *Mask)
Definition: VPlan.h:2734
A recipe for widening load operations, using the address to load from and an optional mask.
Definition: VPlan.h:2694
VP_CLASSOF_IMPL(VPDef::VPWidenLoadSC)
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, bool Reverse, DebugLoc DL)
Definition: VPlan.h:2695
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2721
void execute(VPTransformState &State) override
Generate a wide load or gather.
VPWidenLoadRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2703
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
A recipe for widening select instructions.
Definition: VPlan.h:1483
bool isInvariantCond() const
Definition: VPlan.h:1514
VPWidenSelectRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1490
VPWidenSelectRecipe(SelectInst &I, iterator_range< IterT > Operands)
Definition: VPlan.h:1485
VPValue * getCond() const
Definition: VPlan.h:1510
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenSelectRecipe.
void execute(VPTransformState &State) override
Produce a widened version of the select instruction.
~VPWidenSelectRecipe() override=default
A recipe for widening store operations with vector-predication intrinsics, using the value to store,...
Definition: VPlan.h:2813
VPValue * getStoredValue() const
Return the address accessed by this recipe.
Definition: VPlan.h:2824
void execute(VPTransformState &State) override
Generate the wide store or scatter.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2843
VPWidenStoreEVLRecipe(VPWidenStoreRecipe &S, VPValue &EVL, VPValue *Mask)
Definition: VPlan.h:2814
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
Definition: VPlan.h:2827
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition: VPlan.h:2772
void execute(VPTransformState &State) override
Generate a wide store or scatter.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2801
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, bool Reverse, DebugLoc DL)
Definition: VPlan.h:2773
VP_CLASSOF_IMPL(VPDef::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
Definition: VPlan.h:2789
VPWidenStoreRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2780
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPlanIngredient(const Value *V)
Definition: VPlan.h:3807
const Value * V
Definition: VPlan.h:3805
void print(raw_ostream &O) const
Definition: VPlan.cpp:1408