LLVM 22.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"
43#include <algorithm>
44#include <cassert>
45#include <cstddef>
46#include <string>
47
48namespace llvm {
49
50class BasicBlock;
51class DominatorTree;
52class InnerLoopVectorizer;
53class IRBuilderBase;
54struct VPTransformState;
55class raw_ostream;
56class RecurrenceDescriptor;
57class SCEV;
58class Type;
59class VPBasicBlock;
60class VPBuilder;
61class VPDominatorTree;
62class VPRegionBlock;
63class VPlan;
64class VPLane;
65class VPReplicateRecipe;
66class VPlanSlp;
67class Value;
68class LoopVectorizationCostModel;
69class LoopVersioning;
70
71struct VPCostContext;
72
73namespace Intrinsic {
74typedef unsigned ID;
75}
76
77using VPlanPtr = std::unique_ptr<VPlan>;
78
79/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
80/// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
82 friend class VPBlockUtils;
83
84 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
85
86 /// An optional name for the block.
87 std::string Name;
88
89 /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if
90 /// it is a topmost VPBlockBase.
91 VPRegionBlock *Parent = nullptr;
92
93 /// List of predecessor blocks.
95
96 /// List of successor blocks.
98
99 /// VPlan containing the block. Can only be set on the entry block of the
100 /// plan.
101 VPlan *Plan = nullptr;
102
103 /// Add \p Successor as the last successor to this block.
104 void appendSuccessor(VPBlockBase *Successor) {
105 assert(Successor && "Cannot add nullptr successor!");
106 Successors.push_back(Successor);
107 }
108
109 /// Add \p Predecessor as the last predecessor to this block.
110 void appendPredecessor(VPBlockBase *Predecessor) {
111 assert(Predecessor && "Cannot add nullptr predecessor!");
112 Predecessors.push_back(Predecessor);
113 }
114
115 /// Remove \p Predecessor from the predecessors of this block.
116 void removePredecessor(VPBlockBase *Predecessor) {
117 auto Pos = find(Predecessors, Predecessor);
118 assert(Pos && "Predecessor does not exist");
119 Predecessors.erase(Pos);
120 }
121
122 /// Remove \p Successor from the successors of this block.
123 void removeSuccessor(VPBlockBase *Successor) {
124 auto Pos = find(Successors, Successor);
125 assert(Pos && "Successor does not exist");
126 Successors.erase(Pos);
127 }
128
129 /// This function replaces one predecessor with another, useful when
130 /// trying to replace an old block in the CFG with a new one.
131 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
132 auto I = find(Predecessors, Old);
133 assert(I != Predecessors.end());
134 assert(Old->getParent() == New->getParent() &&
135 "replaced predecessor must have the same parent");
136 *I = New;
137 }
138
139 /// This function replaces one successor with another, useful when
140 /// trying to replace an old block in the CFG with a new one.
141 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
142 auto I = find(Successors, Old);
143 assert(I != Successors.end());
144 assert(Old->getParent() == New->getParent() &&
145 "replaced successor must have the same parent");
146 *I = New;
147 }
148
149protected:
150 VPBlockBase(const unsigned char SC, const std::string &N)
151 : SubclassID(SC), Name(N) {}
152
153public:
154 /// An enumeration for keeping track of the concrete subclass of VPBlockBase
155 /// that are actually instantiated. Values of this enumeration are kept in the
156 /// SubclassID field of the VPBlockBase objects. They are used for concrete
157 /// type identification.
158 using VPBlockTy = enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC };
159
161
162 virtual ~VPBlockBase() = default;
163
164 const std::string &getName() const { return Name; }
165
166 void setName(const Twine &newName) { Name = newName.str(); }
167
168 /// \return an ID for the concrete type of this object.
169 /// This is used to implement the classof checks. This should not be used
170 /// for any other purpose, as the values may change as LLVM evolves.
171 unsigned getVPBlockID() const { return SubclassID; }
172
173 VPRegionBlock *getParent() { return Parent; }
174 const VPRegionBlock *getParent() const { return Parent; }
175
176 /// \return A pointer to the plan containing the current block.
177 VPlan *getPlan();
178 const VPlan *getPlan() const;
179
180 /// Sets the pointer of the plan containing the block. The block must be the
181 /// entry block into the VPlan.
182 void setPlan(VPlan *ParentPlan);
183
184 void setParent(VPRegionBlock *P) { Parent = P; }
185
186 /// \return the VPBasicBlock that is the entry of this VPBlockBase,
187 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
188 /// VPBlockBase is a VPBasicBlock, it is returned.
189 const VPBasicBlock *getEntryBasicBlock() const;
190 VPBasicBlock *getEntryBasicBlock();
191
192 /// \return the VPBasicBlock that is the exiting this VPBlockBase,
193 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
194 /// VPBlockBase is a VPBasicBlock, it is returned.
195 const VPBasicBlock *getExitingBasicBlock() const;
196 VPBasicBlock *getExitingBasicBlock();
197
198 const VPBlocksTy &getSuccessors() const { return Successors; }
199 VPBlocksTy &getSuccessors() { return Successors; }
200
203
204 const VPBlocksTy &getPredecessors() const { return Predecessors; }
205 VPBlocksTy &getPredecessors() { return Predecessors; }
206
207 /// \return the successor of this VPBlockBase if it has a single successor.
208 /// Otherwise return a null pointer.
210 return (Successors.size() == 1 ? *Successors.begin() : nullptr);
211 }
212
213 /// \return the predecessor of this VPBlockBase if it has a single
214 /// predecessor. Otherwise return a null pointer.
216 return (Predecessors.size() == 1 ? *Predecessors.begin() : nullptr);
217 }
218
219 size_t getNumSuccessors() const { return Successors.size(); }
220 size_t getNumPredecessors() const { return Predecessors.size(); }
221
222 /// An Enclosing Block of a block B is any block containing B, including B
223 /// itself. \return the closest enclosing block starting from "this", which
224 /// has successors. \return the root enclosing block if all enclosing blocks
225 /// have no successors.
226 VPBlockBase *getEnclosingBlockWithSuccessors();
227
228 /// \return the closest enclosing block starting from "this", which has
229 /// predecessors. \return the root enclosing block if all enclosing blocks
230 /// have no predecessors.
231 VPBlockBase *getEnclosingBlockWithPredecessors();
232
233 /// \return the successors either attached directly to this VPBlockBase or, if
234 /// this VPBlockBase is the exit block of a VPRegionBlock and has no
235 /// successors of its own, search recursively for the first enclosing
236 /// VPRegionBlock that has successors and return them. If no such
237 /// VPRegionBlock exists, return the (empty) successors of the topmost
238 /// VPBlockBase reached.
240 return getEnclosingBlockWithSuccessors()->getSuccessors();
241 }
242
243 /// \return the hierarchical successor of this VPBlockBase if it has a single
244 /// hierarchical successor. Otherwise return a null pointer.
246 return getEnclosingBlockWithSuccessors()->getSingleSuccessor();
247 }
248
249 /// \return the predecessors either attached directly to this VPBlockBase or,
250 /// if this VPBlockBase is the entry block of a VPRegionBlock and has no
251 /// predecessors of its own, search recursively for the first enclosing
252 /// VPRegionBlock that has predecessors and return them. If no such
253 /// VPRegionBlock exists, return the (empty) predecessors of the topmost
254 /// VPBlockBase reached.
256 return getEnclosingBlockWithPredecessors()->getPredecessors();
257 }
258
259 /// \return the hierarchical predecessor of this VPBlockBase if it has a
260 /// single hierarchical predecessor. Otherwise return a null pointer.
262 return getEnclosingBlockWithPredecessors()->getSinglePredecessor();
263 }
264
265 /// Set a given VPBlockBase \p Successor as the single successor of this
266 /// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor.
267 /// This VPBlockBase must have no successors.
268 void setOneSuccessor(VPBlockBase *Successor) {
269 assert(Successors.empty() && "Setting one successor when others exist.");
270 assert(Successor->getParent() == getParent() &&
271 "connected blocks must have the same parent");
272 appendSuccessor(Successor);
273 }
274
275 /// Set two given VPBlockBases \p IfTrue and \p IfFalse to be the two
276 /// successors of this VPBlockBase. This VPBlockBase is not added as
277 /// predecessor of \p IfTrue or \p IfFalse. This VPBlockBase must have no
278 /// successors.
279 void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse) {
280 assert(Successors.empty() && "Setting two successors when others exist.");
281 appendSuccessor(IfTrue);
282 appendSuccessor(IfFalse);
283 }
284
285 /// Set each VPBasicBlock in \p NewPreds as predecessor of this VPBlockBase.
286 /// This VPBlockBase must have no predecessors. This VPBlockBase is not added
287 /// as successor of any VPBasicBlock in \p NewPreds.
289 assert(Predecessors.empty() && "Block predecessors already set.");
290 for (auto *Pred : NewPreds)
291 appendPredecessor(Pred);
292 }
293
294 /// Set each VPBasicBlock in \p NewSuccss as successor of this VPBlockBase.
295 /// This VPBlockBase must have no successors. This VPBlockBase is not added
296 /// as predecessor of any VPBasicBlock in \p NewSuccs.
298 assert(Successors.empty() && "Block successors already set.");
299 for (auto *Succ : NewSuccs)
300 appendSuccessor(Succ);
301 }
302
303 /// Remove all the predecessor of this block.
304 void clearPredecessors() { Predecessors.clear(); }
305
306 /// Remove all the successors of this block.
307 void clearSuccessors() { Successors.clear(); }
308
309 /// Swap predecessors of the block. The block must have exactly 2
310 /// predecessors.
312 assert(Predecessors.size() == 2 && "must have 2 predecessors to swap");
313 std::swap(Predecessors[0], Predecessors[1]);
314 }
315
316 /// Swap successors of the block. The block must have exactly 2 successors.
317 // TODO: This should be part of introducing conditional branch recipes rather
318 // than being independent.
320 assert(Successors.size() == 2 && "must have 2 successors to swap");
321 std::swap(Successors[0], Successors[1]);
322 }
323
324 /// Returns the index for \p Pred in the blocks predecessors list.
325 unsigned getIndexForPredecessor(const VPBlockBase *Pred) const {
326 assert(count(Predecessors, Pred) == 1 &&
327 "must have Pred exactly once in Predecessors");
328 return std::distance(Predecessors.begin(), find(Predecessors, Pred));
329 }
330
331 /// Returns the index for \p Succ in the blocks successor list.
332 unsigned getIndexForSuccessor(const VPBlockBase *Succ) const {
333 assert(count(Successors, Succ) == 1 &&
334 "must have Succ exactly once in Successors");
335 return std::distance(Successors.begin(), find(Successors, Succ));
336 }
337
338 /// The method which generates the output IR that correspond to this
339 /// VPBlockBase, thereby "executing" the VPlan.
340 virtual void execute(VPTransformState *State) = 0;
341
342 /// Return the cost of the block.
344
345 /// Return true if it is legal to hoist instructions into this block.
347 // There are currently no constraints that prevent an instruction to be
348 // hoisted into a VPBlockBase.
349 return true;
350 }
351
352#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
353 void printAsOperand(raw_ostream &OS, bool PrintType = false) const {
354 OS << getName();
355 }
356
357 /// Print plain-text dump of this VPBlockBase to \p O, prefixing all lines
358 /// with \p Indent. \p SlotTracker is used to print unnamed VPValue's using
359 /// consequtive numbers.
360 ///
361 /// Note that the numbering is applied to the whole VPlan, so printing
362 /// individual blocks is consistent with the whole VPlan printing.
363 virtual void print(raw_ostream &O, const Twine &Indent,
364 VPSlotTracker &SlotTracker) const = 0;
365
366 /// Print plain-text dump of this VPlan to \p O.
367 void print(raw_ostream &O) const;
368
369 /// Print the successors of this block to \p O, prefixing all lines with \p
370 /// Indent.
371 void printSuccessors(raw_ostream &O, const Twine &Indent) const;
372
373 /// Dump this VPBlockBase to dbgs().
374 LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
375#endif
376
377 /// Clone the current block and it's recipes without updating the operands of
378 /// the cloned recipes, including all blocks in the single-entry single-exit
379 /// region for VPRegionBlocks.
380 virtual VPBlockBase *clone() = 0;
381};
382
383/// VPRecipeBase is a base class modeling a sequence of one or more output IR
384/// instructions. VPRecipeBase owns the VPValues it defines through VPDef
385/// and is responsible for deleting its defined values. Single-value
386/// recipes must inherit from VPSingleDef instead of inheriting from both
387/// VPRecipeBase and VPValue separately.
389 : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
390 public VPDef,
391 public VPUser {
392 friend VPBasicBlock;
393 friend class VPBlockUtils;
394
395 /// Each VPRecipe belongs to a single VPBasicBlock.
396 VPBasicBlock *Parent = nullptr;
397
398 /// The debug location for the recipe.
399 DebugLoc DL;
400
401public:
403 DebugLoc DL = DebugLoc::getUnknown())
404 : VPDef(SC), VPUser(Operands), DL(DL) {}
405
406 virtual ~VPRecipeBase() = default;
407
408 /// Clone the current recipe.
409 virtual VPRecipeBase *clone() = 0;
410
411 /// \return the VPBasicBlock which this VPRecipe belongs to.
412 VPBasicBlock *getParent() { return Parent; }
413 const VPBasicBlock *getParent() const { return Parent; }
414
415 /// The method which generates the output IR instructions that correspond to
416 /// this VPRecipe, thereby "executing" the VPlan.
417 virtual void execute(VPTransformState &State) = 0;
418
419 /// Return the cost of this recipe, taking into account if the cost
420 /// computation should be skipped and the ForceTargetInstructionCost flag.
421 /// Also takes care of printing the cost for debugging.
423
424 /// Insert an unlinked recipe into a basic block immediately before
425 /// the specified recipe.
426 void insertBefore(VPRecipeBase *InsertPos);
427 /// Insert an unlinked recipe into \p BB immediately before the insertion
428 /// point \p IP;
429 void insertBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator IP);
430
431 /// Insert an unlinked Recipe into a basic block immediately after
432 /// the specified Recipe.
433 void insertAfter(VPRecipeBase *InsertPos);
434
435 /// Unlink this recipe from its current VPBasicBlock and insert it into
436 /// the VPBasicBlock that MovePos lives in, right after MovePos.
437 void moveAfter(VPRecipeBase *MovePos);
438
439 /// Unlink this recipe and insert into BB before I.
440 ///
441 /// \pre I is a valid iterator into BB.
442 void moveBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator I);
443
444 /// This method unlinks 'this' from the containing basic block, but does not
445 /// delete it.
446 void removeFromParent();
447
448 /// This method unlinks 'this' from the containing basic block and deletes it.
449 ///
450 /// \returns an iterator pointing to the element after the erased one
451 iplist<VPRecipeBase>::iterator eraseFromParent();
452
453 /// Method to support type inquiry through isa, cast, and dyn_cast.
454 static inline bool classof(const VPDef *D) {
455 // All VPDefs are also VPRecipeBases.
456 return true;
457 }
458
459 static inline bool classof(const VPUser *U) { return true; }
460
461 /// Returns true if the recipe may have side-effects.
462 bool mayHaveSideEffects() const;
463
464 /// Returns true for PHI-like recipes.
465 bool isPhi() const;
466
467 /// Returns true if the recipe may read from memory.
468 bool mayReadFromMemory() const;
469
470 /// Returns true if the recipe may write to memory.
471 bool mayWriteToMemory() const;
472
473 /// Returns true if the recipe may read from or write to memory.
474 bool mayReadOrWriteMemory() const {
475 return mayReadFromMemory() || mayWriteToMemory();
476 }
477
478 /// Returns the debug location of the recipe.
479 DebugLoc getDebugLoc() const { return DL; }
480
481 /// Return true if the recipe is a scalar cast.
482 bool isScalarCast() const;
483
484 /// Set the recipe's debug location to \p NewDL.
485 void setDebugLoc(DebugLoc NewDL) { DL = NewDL; }
486
487protected:
488 /// Compute the cost of this recipe either using a recipe's specialized
489 /// implementation or using the legacy cost model and the underlying
490 /// instructions.
491 virtual InstructionCost computeCost(ElementCount VF,
492 VPCostContext &Ctx) const;
493};
494
495// Helper macro to define common classof implementations for recipes.
496#define VP_CLASSOF_IMPL(VPDefID) \
497 static inline bool classof(const VPDef *D) { \
498 return D->getVPDefID() == VPDefID; \
499 } \
500 static inline bool classof(const VPValue *V) { \
501 auto *R = V->getDefiningRecipe(); \
502 return R && R->getVPDefID() == VPDefID; \
503 } \
504 static inline bool classof(const VPUser *U) { \
505 auto *R = dyn_cast<VPRecipeBase>(U); \
506 return R && R->getVPDefID() == VPDefID; \
507 } \
508 static inline bool classof(const VPRecipeBase *R) { \
509 return R->getVPDefID() == VPDefID; \
510 } \
511 static inline bool classof(const VPSingleDefRecipe *R) { \
512 return R->getVPDefID() == VPDefID; \
513 }
514
515/// VPSingleDef is a base class for recipes for modeling a sequence of one or
516/// more output IR that define a single result VPValue.
517/// Note that VPRecipeBase must be inherited from before VPValue.
518class VPSingleDefRecipe : public VPRecipeBase, public VPValue {
519public:
520 VPSingleDefRecipe(const unsigned char SC, ArrayRef<VPValue *> Operands,
522 : VPRecipeBase(SC, Operands, DL), VPValue(this) {}
523
524 VPSingleDefRecipe(const unsigned char SC, ArrayRef<VPValue *> Operands,
526 : VPRecipeBase(SC, Operands, DL), VPValue(this, UV) {}
527
528 static inline bool classof(const VPRecipeBase *R) {
529 switch (R->getVPDefID()) {
530 case VPRecipeBase::VPDerivedIVSC:
531 case VPRecipeBase::VPEVLBasedIVPHISC:
532 case VPRecipeBase::VPExpandSCEVSC:
533 case VPRecipeBase::VPExpressionSC:
534 case VPRecipeBase::VPInstructionSC:
535 case VPRecipeBase::VPReductionEVLSC:
536 case VPRecipeBase::VPReductionSC:
537 case VPRecipeBase::VPReplicateSC:
538 case VPRecipeBase::VPScalarIVStepsSC:
539 case VPRecipeBase::VPVectorPointerSC:
540 case VPRecipeBase::VPVectorEndPointerSC:
541 case VPRecipeBase::VPWidenCallSC:
542 case VPRecipeBase::VPWidenCanonicalIVSC:
543 case VPRecipeBase::VPWidenCastSC:
544 case VPRecipeBase::VPWidenGEPSC:
545 case VPRecipeBase::VPWidenIntrinsicSC:
546 case VPRecipeBase::VPWidenSC:
547 case VPRecipeBase::VPWidenSelectSC:
548 case VPRecipeBase::VPBlendSC:
549 case VPRecipeBase::VPPredInstPHISC:
550 case VPRecipeBase::VPCanonicalIVPHISC:
551 case VPRecipeBase::VPActiveLaneMaskPHISC:
552 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
553 case VPRecipeBase::VPWidenPHISC:
554 case VPRecipeBase::VPWidenIntOrFpInductionSC:
555 case VPRecipeBase::VPWidenPointerInductionSC:
556 case VPRecipeBase::VPReductionPHISC:
557 case VPRecipeBase::VPPartialReductionSC:
558 return true;
559 case VPRecipeBase::VPBranchOnMaskSC:
560 case VPRecipeBase::VPInterleaveSC:
561 case VPRecipeBase::VPIRInstructionSC:
562 case VPRecipeBase::VPWidenLoadEVLSC:
563 case VPRecipeBase::VPWidenLoadSC:
564 case VPRecipeBase::VPWidenStoreEVLSC:
565 case VPRecipeBase::VPWidenStoreSC:
566 case VPRecipeBase::VPHistogramSC:
567 // TODO: Widened stores don't define a value, but widened loads do. Split
568 // the recipes to be able to make widened loads VPSingleDefRecipes.
569 return false;
570 }
571 llvm_unreachable("Unhandled VPDefID");
572 }
573
574 static inline bool classof(const VPUser *U) {
575 auto *R = dyn_cast<VPRecipeBase>(U);
576 return R && classof(R);
577 }
578
579 virtual VPSingleDefRecipe *clone() override = 0;
580
581 /// Returns the underlying instruction.
583 return cast<Instruction>(getUnderlyingValue());
584 }
586 return cast<Instruction>(getUnderlyingValue());
587 }
588
589#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
590 /// Print this VPSingleDefRecipe to dbgs() (for debugging).
591 LLVM_DUMP_METHOD void dump() const;
592#endif
593};
594
595/// Class to record and manage LLVM IR flags.
597 enum class OperationType : unsigned char {
598 Cmp,
599 OverflowingBinOp,
600 Trunc,
601 DisjointOp,
602 PossiblyExactOp,
603 GEPOp,
604 FPMathOp,
605 NonNegOp,
606 Other
607 };
608
609public:
610 struct WrapFlagsTy {
611 char HasNUW : 1;
612 char HasNSW : 1;
613
615 };
616
618 char HasNUW : 1;
619 char HasNSW : 1;
620
622 };
623
625 char IsDisjoint : 1;
627 };
628
630 char NonNeg : 1;
631 NonNegFlagsTy(bool IsNonNeg) : NonNeg(IsNonNeg) {}
632 };
633
634private:
635 struct ExactFlagsTy {
636 char IsExact : 1;
637 };
638 struct FastMathFlagsTy {
639 char AllowReassoc : 1;
640 char NoNaNs : 1;
641 char NoInfs : 1;
642 char NoSignedZeros : 1;
643 char AllowReciprocal : 1;
644 char AllowContract : 1;
645 char ApproxFunc : 1;
646
647 LLVM_ABI_FOR_TEST FastMathFlagsTy(const FastMathFlags &FMF);
648 };
649
650 OperationType OpType;
651
652 union {
657 ExactFlagsTy ExactFlags;
660 FastMathFlagsTy FMFs;
661 unsigned AllFlags;
662 };
663
664public:
665 VPIRFlags() : OpType(OperationType::Other), AllFlags(0) {}
666
668 if (auto *Op = dyn_cast<CmpInst>(&I)) {
669 OpType = OperationType::Cmp;
670 CmpPredicate = Op->getPredicate();
671 } else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
672 OpType = OperationType::DisjointOp;
673 DisjointFlags.IsDisjoint = Op->isDisjoint();
674 } else if (auto *Op = dyn_cast<OverflowingBinaryOperator>(&I)) {
675 OpType = OperationType::OverflowingBinOp;
676 WrapFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
677 } else if (auto *Op = dyn_cast<TruncInst>(&I)) {
678 OpType = OperationType::Trunc;
679 TruncFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
680 } else if (auto *Op = dyn_cast<PossiblyExactOperator>(&I)) {
681 OpType = OperationType::PossiblyExactOp;
682 ExactFlags.IsExact = Op->isExact();
683 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
684 OpType = OperationType::GEPOp;
685 GEPFlags = GEP->getNoWrapFlags();
686 } else if (auto *PNNI = dyn_cast<PossiblyNonNegInst>(&I)) {
687 OpType = OperationType::NonNegOp;
688 NonNegFlags.NonNeg = PNNI->hasNonNeg();
689 } else if (auto *Op = dyn_cast<FPMathOperator>(&I)) {
690 OpType = OperationType::FPMathOp;
691 FMFs = Op->getFastMathFlags();
692 } else {
693 OpType = OperationType::Other;
694 AllFlags = 0;
695 }
696 }
697
699 : OpType(OperationType::Cmp), CmpPredicate(Pred) {}
700
702 : OpType(OperationType::OverflowingBinOp), WrapFlags(WrapFlags) {}
703
704 VPIRFlags(FastMathFlags FMFs) : OpType(OperationType::FPMathOp), FMFs(FMFs) {}
705
707 : OpType(OperationType::DisjointOp), DisjointFlags(DisjointFlags) {}
708
710 : OpType(OperationType::NonNegOp), NonNegFlags(NonNegFlags) {}
711
713 : OpType(OperationType::GEPOp), GEPFlags(GEPFlags) {}
714
715public:
717 OpType = Other.OpType;
718 AllFlags = Other.AllFlags;
719 }
720
721 /// Drop all poison-generating flags.
723 // NOTE: This needs to be kept in-sync with
724 // Instruction::dropPoisonGeneratingFlags.
725 switch (OpType) {
726 case OperationType::OverflowingBinOp:
727 WrapFlags.HasNUW = false;
728 WrapFlags.HasNSW = false;
729 break;
730 case OperationType::Trunc:
731 TruncFlags.HasNUW = false;
732 TruncFlags.HasNSW = false;
733 break;
734 case OperationType::DisjointOp:
736 break;
737 case OperationType::PossiblyExactOp:
738 ExactFlags.IsExact = false;
739 break;
740 case OperationType::GEPOp:
742 break;
743 case OperationType::FPMathOp:
744 FMFs.NoNaNs = false;
745 FMFs.NoInfs = false;
746 break;
747 case OperationType::NonNegOp:
748 NonNegFlags.NonNeg = false;
749 break;
750 case OperationType::Cmp:
751 case OperationType::Other:
752 break;
753 }
754 }
755
756 /// Apply the IR flags to \p I.
757 void applyFlags(Instruction &I) const {
758 switch (OpType) {
759 case OperationType::OverflowingBinOp:
760 I.setHasNoUnsignedWrap(WrapFlags.HasNUW);
761 I.setHasNoSignedWrap(WrapFlags.HasNSW);
762 break;
763 case OperationType::Trunc:
764 I.setHasNoUnsignedWrap(TruncFlags.HasNUW);
765 I.setHasNoSignedWrap(TruncFlags.HasNSW);
766 break;
767 case OperationType::DisjointOp:
768 cast<PossiblyDisjointInst>(&I)->setIsDisjoint(DisjointFlags.IsDisjoint);
769 break;
770 case OperationType::PossiblyExactOp:
771 I.setIsExact(ExactFlags.IsExact);
772 break;
773 case OperationType::GEPOp:
774 cast<GetElementPtrInst>(&I)->setNoWrapFlags(GEPFlags);
775 break;
776 case OperationType::FPMathOp:
777 I.setHasAllowReassoc(FMFs.AllowReassoc);
778 I.setHasNoNaNs(FMFs.NoNaNs);
779 I.setHasNoInfs(FMFs.NoInfs);
780 I.setHasNoSignedZeros(FMFs.NoSignedZeros);
781 I.setHasAllowReciprocal(FMFs.AllowReciprocal);
782 I.setHasAllowContract(FMFs.AllowContract);
783 I.setHasApproxFunc(FMFs.ApproxFunc);
784 break;
785 case OperationType::NonNegOp:
786 I.setNonNeg(NonNegFlags.NonNeg);
787 break;
788 case OperationType::Cmp:
789 case OperationType::Other:
790 break;
791 }
792 }
793
795 assert(OpType == OperationType::Cmp &&
796 "recipe doesn't have a compare predicate");
797 return CmpPredicate;
798 }
799
801 assert(OpType == OperationType::Cmp &&
802 "recipe doesn't have a compare predicate");
803 CmpPredicate = Pred;
804 }
805
807
808 /// Returns true if the recipe has a comparison predicate.
809 bool hasPredicate() const { return OpType == OperationType::Cmp; }
810
811 /// Returns true if the recipe has fast-math flags.
812 bool hasFastMathFlags() const { return OpType == OperationType::FPMathOp; }
813
815
816 /// Returns true if the recipe has non-negative flag.
817 bool hasNonNegFlag() const { return OpType == OperationType::NonNegOp; }
818
819 bool isNonNeg() const {
820 assert(OpType == OperationType::NonNegOp &&
821 "recipe doesn't have a NNEG flag");
822 return NonNegFlags.NonNeg;
823 }
824
825 bool hasNoUnsignedWrap() const {
826 switch (OpType) {
827 case OperationType::OverflowingBinOp:
828 return WrapFlags.HasNUW;
829 case OperationType::Trunc:
830 return TruncFlags.HasNUW;
831 default:
832 llvm_unreachable("recipe doesn't have a NUW flag");
833 }
834 }
835
836 bool hasNoSignedWrap() const {
837 switch (OpType) {
838 case OperationType::OverflowingBinOp:
839 return WrapFlags.HasNSW;
840 case OperationType::Trunc:
841 return TruncFlags.HasNSW;
842 default:
843 llvm_unreachable("recipe doesn't have a NSW flag");
844 }
845 }
846
847 bool isDisjoint() const {
848 assert(OpType == OperationType::DisjointOp &&
849 "recipe cannot have a disjoing flag");
851 }
852
853#if !defined(NDEBUG)
854 /// Returns true if the set flags are valid for \p Opcode.
855 bool flagsValidForOpcode(unsigned Opcode) const;
856#endif
857
858#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
859 void printFlags(raw_ostream &O) const;
860#endif
861};
862
863/// A pure-virtual common base class for recipes defining a single VPValue and
864/// using IR flags.
866 VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
869
870 VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
871 Instruction &I)
873
874 VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
875 const VPIRFlags &Flags,
877 : VPSingleDefRecipe(SC, Operands, DL), VPIRFlags(Flags) {}
878
879 static inline bool classof(const VPRecipeBase *R) {
880 return R->getVPDefID() == VPRecipeBase::VPInstructionSC ||
881 R->getVPDefID() == VPRecipeBase::VPWidenSC ||
882 R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
883 R->getVPDefID() == VPRecipeBase::VPWidenCallSC ||
884 R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
885 R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
886 R->getVPDefID() == VPRecipeBase::VPWidenSelectSC ||
887 R->getVPDefID() == VPRecipeBase::VPReductionSC ||
888 R->getVPDefID() == VPRecipeBase::VPReductionEVLSC ||
889 R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
890 R->getVPDefID() == VPRecipeBase::VPVectorEndPointerSC ||
891 R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;
892 }
893
894 static inline bool classof(const VPUser *U) {
895 auto *R = dyn_cast<VPRecipeBase>(U);
896 return R && classof(R);
897 }
898
899 static inline bool classof(const VPValue *V) {
900 auto *R = dyn_cast_or_null<VPRecipeBase>(V->getDefiningRecipe());
901 return R && classof(R);
902 }
903
904 void execute(VPTransformState &State) override = 0;
905
906 /// Compute the cost for this recipe for \p VF, using \p Opcode and \p Ctx.
907 std::optional<InstructionCost>
908 getCostForRecipeWithOpcode(unsigned Opcode, ElementCount VF,
909 VPCostContext &Ctx) const;
910};
911
912/// Helper to access the operand that contains the unroll part for this recipe
913/// after unrolling.
914template <unsigned PartOpIdx> class LLVM_ABI_FOR_TEST VPUnrollPartAccessor {
915protected:
916 /// Return the VPValue operand containing the unroll part or null if there is
917 /// no such operand.
918 VPValue *getUnrollPartOperand(const VPUser &U) const;
919
920 /// Return the unroll part.
921 unsigned getUnrollPart(const VPUser &U) const;
922};
923
924/// Helper to manage IR metadata for recipes. It filters out metadata that
925/// cannot be propagated.
928
929public:
931
932 /// Adds metatadata that can be preserved from the original instruction
933 /// \p I.
935
936 /// Adds metatadata that can be preserved from the original instruction
937 /// \p I and noalias metadata guaranteed by runtime checks using \p LVer.
939
940 /// Copy constructor for cloning.
942
944 Metadata = Other.Metadata;
945 return *this;
946 }
947
948 /// Add all metadata to \p I.
949 void applyMetadata(Instruction &I) const;
950
951 /// Add metadata with kind \p Kind and \p Node.
952 void addMetadata(unsigned Kind, MDNode *Node) {
953 Metadata.emplace_back(Kind, Node);
954 }
955
956 /// Intersect this VPIRMetada object with \p MD, keeping only metadata
957 /// nodes that are common to both.
958 void intersect(const VPIRMetadata &MD);
959};
960
961/// This is a concrete Recipe that models a single VPlan-level instruction.
962/// While as any Recipe it may generate a sequence of IR instructions when
963/// executed, these instructions would always form a single-def expression as
964/// the VPInstruction is also a single def-use vertex.
966 public VPIRMetadata,
967 public VPUnrollPartAccessor<1> {
968 friend class VPlanSlp;
969
970public:
971 /// VPlan opcodes, extending LLVM IR with idiomatics instructions.
972 enum {
973 FirstOrderRecurrenceSplice =
974 Instruction::OtherOpsEnd + 1, // Combines the incoming and previous
975 // values of a first-order recurrence.
982 // Increment the canonical IV separately for each unrolled part.
987 /// Given operands of (the same) struct type, creates a struct of fixed-
988 /// width vectors each containing a struct field of all operands. The
989 /// number of operands matches the element count of every vector.
991 /// Creates a fixed-width vector containing all operands. The number of
992 /// operands matches the vector element count.
994 /// Compute the final result of a AnyOf reduction with select(cmp(),x,y),
995 /// where one of (x,y) is loop invariant, and both x and y are integer type.
999 // Extracts the last lane from its operand if it is a vector, or the last
1000 // part if scalar. In the latter case, the recipe will be removed during
1001 // unrolling.
1003 // Extracts the second-to-last lane from its operand or the second-to-last
1004 // part if it is scalar. In the latter case, the recipe will be removed
1005 // during unrolling.
1007 LogicalAnd, // Non-poison propagating logical And.
1008 // Add an offset in bytes (second operand) to a base pointer (first
1009 // operand). Only generates scalar values (either for the first lane only or
1010 // for all lanes, depending on its uses).
1012 // Add a vector offset in bytes (second operand) to a scalar base pointer
1013 // (first operand).
1015 // Returns a scalar boolean value, which is true if any lane of its
1016 // (boolean) vector operands is true. It produces the reduced value across
1017 // all unrolled iterations. Unrolling will add all copies of its original
1018 // operand as additional operands. AnyOf is poison-safe as all operands
1019 // will be frozen.
1021 // Calculates the first active lane index of the vector predicate operands.
1022 // It produces the lane index across all unrolled iterations. Unrolling will
1023 // add all copies of its original operand as additional operands.
1025
1026 // The opcodes below are used for VPInstructionWithType.
1027 //
1028 /// Scale the first operand (vector step) by the second operand
1029 /// (scalar-step). Casts both operands to the result type if needed.
1031 /// Start vector for reductions with 3 operands: the original start value,
1032 /// the identity value for the reduction and an integer indicating the
1033 /// scaling factor.
1035 // Creates a step vector starting from 0 to VF with a step of 1.
1037 /// Extracts a single lane (first operand) from a set of vector operands.
1038 /// The lane specifies an index into a vector formed by combining all vector
1039 /// operands (all operands after the first one).
1041 /// Explicit user for the resume phi of the canonical induction in the main
1042 /// VPlan, used by the epilogue vector loop.
1044 /// Returns the value for vscale.
1046 };
1047
1048private:
1049 typedef unsigned char OpcodeTy;
1050 OpcodeTy Opcode;
1051
1052 /// An optional name that can be used for the generated IR instruction.
1053 const std::string Name;
1054
1055 /// Returns true if this VPInstruction generates scalar values for all lanes.
1056 /// Most VPInstructions generate a single value per part, either vector or
1057 /// scalar. VPReplicateRecipe takes care of generating multiple (scalar)
1058 /// values per all lanes, stemming from an original ingredient. This method
1059 /// identifies the (rare) cases of VPInstructions that do so as well, w/o an
1060 /// underlying ingredient.
1061 bool doesGeneratePerAllLanes() const;
1062
1063 /// Returns true if we can generate a scalar for the first lane only if
1064 /// needed.
1065 bool canGenerateScalarForFirstLane() const;
1066
1067 /// Utility methods serving execute(): generates a single vector instance of
1068 /// the modeled instruction. \returns the generated value. . In some cases an
1069 /// existing value is returned rather than a generated one.
1070 Value *generate(VPTransformState &State);
1071
1072 /// Utility methods serving execute(): generates a scalar single instance of
1073 /// the modeled instruction for a given lane. \returns the scalar generated
1074 /// value for lane \p Lane.
1075 Value *generatePerLane(VPTransformState &State, const VPLane &Lane);
1076
1077#if !defined(NDEBUG)
1078 /// Return the number of operands determined by the opcode of the
1079 /// VPInstruction. Returns -1u if the number of operands cannot be determined
1080 /// directly by the opcode.
1081 static unsigned getNumOperandsForOpcode(unsigned Opcode);
1082#endif
1083
1084public:
1086 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "")
1087 : VPRecipeWithIRFlags(VPDef::VPInstructionSC, Operands, DL),
1088 VPIRMetadata(), Opcode(Opcode), Name(Name.str()) {}
1089
1091 const VPIRFlags &Flags, DebugLoc DL = DebugLoc::getUnknown(),
1092 const Twine &Name = "");
1093
1094 VP_CLASSOF_IMPL(VPDef::VPInstructionSC)
1095
1096 VPInstruction *clone() override {
1098 auto *New = new VPInstruction(Opcode, Operands, *this, getDebugLoc(), Name);
1099 if (getUnderlyingValue())
1100 New->setUnderlyingValue(getUnderlyingInstr());
1101 return New;
1102 }
1103
1104 unsigned getOpcode() const { return Opcode; }
1105
1106 /// Generate the instruction.
1107 /// TODO: We currently execute only per-part unless a specific instance is
1108 /// provided.
1109 void execute(VPTransformState &State) override;
1110
1111 /// Return the cost of this VPInstruction.
1112 InstructionCost computeCost(ElementCount VF,
1113 VPCostContext &Ctx) const override;
1114
1115#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1116 /// Print the VPInstruction to \p O.
1117 void print(raw_ostream &O, const Twine &Indent,
1118 VPSlotTracker &SlotTracker) const override;
1119
1120 /// Print the VPInstruction to dbgs() (for debugging).
1121 LLVM_DUMP_METHOD void dump() const;
1122#endif
1123
1124 bool hasResult() const {
1125 // CallInst may or may not have a result, depending on the called function.
1126 // Conservatively return calls have results for now.
1127 switch (getOpcode()) {
1128 case Instruction::Ret:
1129 case Instruction::Br:
1130 case Instruction::Store:
1131 case Instruction::Switch:
1132 case Instruction::IndirectBr:
1133 case Instruction::Resume:
1134 case Instruction::CatchRet:
1135 case Instruction::Unreachable:
1136 case Instruction::Fence:
1137 case Instruction::AtomicRMW:
1138 case VPInstruction::BranchOnCond:
1139 case VPInstruction::BranchOnCount:
1140 return false;
1141 default:
1142 return true;
1143 }
1144 }
1145
1146 /// Returns true if the underlying opcode may read from or write to memory.
1147 bool opcodeMayReadOrWriteFromMemory() const;
1148
1149 /// Returns true if the recipe only uses the first lane of operand \p Op.
1150 bool onlyFirstLaneUsed(const VPValue *Op) const override;
1151
1152 /// Returns true if the recipe only uses the first part of operand \p Op.
1153 bool onlyFirstPartUsed(const VPValue *Op) const override;
1154
1155 /// Returns true if this VPInstruction produces a scalar value from a vector,
1156 /// e.g. by performing a reduction or extracting a lane.
1157 bool isVectorToScalar() const;
1158
1159 /// Returns true if this VPInstruction's operands are single scalars and the
1160 /// result is also a single scalar.
1161 bool isSingleScalar() const;
1162
1163 /// Returns the symbolic name assigned to the VPInstruction.
1164 StringRef getName() const { return Name; }
1165};
1166
1167/// A specialization of VPInstruction augmenting it with a dedicated result
1168/// type, to be used when the opcode and operands of the VPInstruction don't
1169/// directly determine the result type. Note that there is no separate VPDef ID
1170/// for VPInstructionWithType; it shares the same ID as VPInstruction and is
1171/// distinguished purely by the opcode.
1173 /// Scalar result type produced by the recipe.
1174 Type *ResultTy;
1175
1176public:
1178 Type *ResultTy, const VPIRFlags &Flags, DebugLoc DL,
1179 const Twine &Name = "")
1180 : VPInstruction(Opcode, Operands, Flags, DL, Name), ResultTy(ResultTy) {}
1181
1182 static inline bool classof(const VPRecipeBase *R) {
1183 // VPInstructionWithType are VPInstructions with specific opcodes requiring
1184 // type information.
1185 if (R->isScalarCast())
1186 return true;
1187 auto *VPI = dyn_cast<VPInstruction>(R);
1188 if (!VPI)
1189 return false;
1190 switch (VPI->getOpcode()) {
1194 return true;
1195 default:
1196 return false;
1197 }
1198 }
1199
1200 static inline bool classof(const VPUser *R) {
1201 return isa<VPInstructionWithType>(cast<VPRecipeBase>(R));
1202 }
1203
1204 VPInstruction *clone() override {
1206 auto *New =
1208 getDebugLoc(), getName());
1209 New->setUnderlyingValue(getUnderlyingValue());
1210 return New;
1211 }
1212
1213 void execute(VPTransformState &State) override;
1214
1215 /// Return the cost of this VPInstruction.
1217 VPCostContext &Ctx) const override {
1218 // TODO: Compute accurate cost after retiring the legacy cost model.
1219 return 0;
1220 }
1221
1222 Type *getResultType() const { return ResultTy; }
1223
1224#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1225 /// Print the recipe.
1226 void print(raw_ostream &O, const Twine &Indent,
1227 VPSlotTracker &SlotTracker) const override;
1228#endif
1229};
1230
1231/// Helper type to provide functions to access incoming values and blocks for
1232/// phi-like recipes.
1234protected:
1235 /// Return a VPRecipeBase* to the current object.
1236 virtual const VPRecipeBase *getAsRecipe() const = 0;
1237
1238public:
1239 virtual ~VPPhiAccessors() = default;
1240
1241 /// Returns the incoming VPValue with index \p Idx.
1242 VPValue *getIncomingValue(unsigned Idx) const {
1243 return getAsRecipe()->getOperand(Idx);
1244 }
1245
1246 /// Returns the incoming block with index \p Idx.
1247 const VPBasicBlock *getIncomingBlock(unsigned Idx) const;
1248
1249 /// Returns the number of incoming values, also number of incoming blocks.
1250 virtual unsigned getNumIncoming() const {
1251 return getAsRecipe()->getNumOperands();
1252 }
1253
1254 /// Returns an interator range over the incoming values.
1256 return make_range(getAsRecipe()->op_begin(),
1257 getAsRecipe()->op_begin() + getNumIncoming());
1258 }
1259
1261 detail::index_iterator, std::function<const VPBasicBlock *(size_t)>>>;
1262
1263 /// Returns an iterator range over the incoming blocks.
1265 std::function<const VPBasicBlock *(size_t)> GetBlock = [this](size_t Idx) {
1266 return getIncomingBlock(Idx);
1267 };
1268 return map_range(index_range(0, getNumIncoming()), GetBlock);
1269 }
1270
1271 /// Returns an iterator range over pairs of incoming values and corresponding
1272 /// incoming blocks.
1277 }
1278
1279 /// Removes the incoming value for \p IncomingBlock, which must be a
1280 /// predecessor.
1281 void removeIncomingValueFor(VPBlockBase *IncomingBlock) const;
1282
1283#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1284 /// Print the recipe.
1286#endif
1287};
1288
1292
1293 static inline bool classof(const VPUser *U) {
1294 auto *VPI = dyn_cast<VPInstruction>(U);
1295 return VPI && VPI->getOpcode() == Instruction::PHI;
1296 }
1297
1298 static inline bool classof(const VPValue *V) {
1299 auto *VPI = dyn_cast<VPInstruction>(V);
1300 return VPI && VPI->getOpcode() == Instruction::PHI;
1301 }
1302
1303 static inline bool classof(const VPSingleDefRecipe *SDR) {
1304 auto *VPI = dyn_cast<VPInstruction>(SDR);
1305 return VPI && VPI->getOpcode() == Instruction::PHI;
1306 }
1307
1308 VPPhi *clone() override {
1309 auto *PhiR = new VPPhi(operands(), getDebugLoc(), getName());
1310 PhiR->setUnderlyingValue(getUnderlyingValue());
1311 return PhiR;
1312 }
1313
1314 void execute(VPTransformState &State) override;
1315
1316#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1317 /// Print the recipe.
1318 void print(raw_ostream &O, const Twine &Indent,
1319 VPSlotTracker &SlotTracker) const override;
1320#endif
1321
1322protected:
1323 const VPRecipeBase *getAsRecipe() const override { return this; }
1324};
1325
1326/// A recipe to wrap on original IR instruction not to be modified during
1327/// execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
1328/// Expect PHIs, VPIRInstructions cannot have any operands.
1330 Instruction &I;
1331
1332protected:
1333 /// VPIRInstruction::create() should be used to create VPIRInstructions, as
1334 /// subclasses may need to be created, e.g. VPIRPhi.
1336 : VPRecipeBase(VPDef::VPIRInstructionSC, ArrayRef<VPValue *>()), I(I) {}
1337
1338public:
1339 ~VPIRInstruction() override = default;
1340
1341 /// Create a new VPIRPhi for \p \I, if it is a PHINode, otherwise create a
1342 /// VPIRInstruction.
1344
1345 VP_CLASSOF_IMPL(VPDef::VPIRInstructionSC)
1346
1348 auto *R = create(I);
1349 for (auto *Op : operands())
1350 R->addOperand(Op);
1351 return R;
1352 }
1353
1354 void execute(VPTransformState &State) override;
1355
1356 /// Return the cost of this VPIRInstruction.
1358 computeCost(ElementCount VF, VPCostContext &Ctx) const override;
1359
1360 Instruction &getInstruction() const { return I; }
1361
1362#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1363 /// Print the recipe.
1364 void print(raw_ostream &O, const Twine &Indent,
1365 VPSlotTracker &SlotTracker) const override;
1366#endif
1367
1368 bool usesScalars(const VPValue *Op) const override {
1370 "Op must be an operand of the recipe");
1371 return true;
1372 }
1373
1374 bool onlyFirstPartUsed(const VPValue *Op) const override {
1376 "Op must be an operand of the recipe");
1377 return true;
1378 }
1379
1380 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1382 "Op must be an operand of the recipe");
1383 return true;
1384 }
1385
1386 /// Update the recipes first operand to the last lane of the operand using \p
1387 /// Builder. Must only be used for VPIRInstructions with at least one operand
1388 /// wrapping a PHINode.
1390};
1391
1392/// An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
1393/// cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
1394/// allowed, and it is used to add a new incoming value for the single
1395/// predecessor VPBB.
1397 public VPPhiAccessors {
1399
1400 static inline bool classof(const VPRecipeBase *U) {
1401 auto *R = dyn_cast<VPIRInstruction>(U);
1402 return R && isa<PHINode>(R->getInstruction());
1403 }
1404
1405 PHINode &getIRPhi() { return cast<PHINode>(getInstruction()); }
1406
1407 void execute(VPTransformState &State) override;
1408
1409#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1410 /// Print the recipe.
1411 void print(raw_ostream &O, const Twine &Indent,
1412 VPSlotTracker &SlotTracker) const override;
1413#endif
1414
1415protected:
1416 const VPRecipeBase *getAsRecipe() const override { return this; }
1417};
1418
1419/// VPWidenRecipe is a recipe for producing a widened instruction using the
1420/// opcode and operands of the recipe. This recipe covers most of the
1421/// traditional vectorization cases where each recipe transforms into a
1422/// vectorized version of itself.
1424 public VPIRMetadata {
1425 unsigned Opcode;
1426
1427public:
1429 const VPIRFlags &Flags, const VPIRMetadata &Metadata,
1430 DebugLoc DL)
1431 : VPRecipeWithIRFlags(VPDef::VPWidenSC, Operands, Flags, DL),
1432 VPIRMetadata(Metadata), Opcode(Opcode) {}
1433
1436 Opcode(I.getOpcode()) {}
1437
1438 ~VPWidenRecipe() override = default;
1439
1440 VPWidenRecipe *clone() override {
1441 auto *R =
1442 new VPWidenRecipe(getOpcode(), operands(), *this, *this, getDebugLoc());
1443 R->setUnderlyingValue(getUnderlyingValue());
1444 return R;
1445 }
1446
1447 VP_CLASSOF_IMPL(VPDef::VPWidenSC)
1448
1449 /// Produce a widened instruction using the opcode and operands of the recipe,
1450 /// processing State.VF elements.
1451 void execute(VPTransformState &State) override;
1452
1453 /// Return the cost of this VPWidenRecipe.
1454 InstructionCost computeCost(ElementCount VF,
1455 VPCostContext &Ctx) const override;
1456
1457 unsigned getOpcode() const { return Opcode; }
1458
1459#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1460 /// Print the recipe.
1461 void print(raw_ostream &O, const Twine &Indent,
1462 VPSlotTracker &SlotTracker) const override;
1463#endif
1464};
1465
1466/// VPWidenCastRecipe is a recipe to create vector cast instructions.
1468 /// Cast instruction opcode.
1469 Instruction::CastOps Opcode;
1470
1471 /// Result type for the cast.
1472 Type *ResultTy;
1473
1474public:
1476 CastInst &UI)
1477 : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, UI), VPIRMetadata(UI),
1478 Opcode(Opcode), ResultTy(ResultTy) {
1479 assert(UI.getOpcode() == Opcode &&
1480 "opcode of underlying cast doesn't match");
1481 }
1482
1484 const VPIRFlags &Flags = {},
1486 : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, Flags, DL),
1487 VPIRMetadata(), Opcode(Opcode), ResultTy(ResultTy) {
1488 assert(flagsValidForOpcode(Opcode) &&
1489 "Set flags not supported for the provided opcode");
1490 }
1491
1492 ~VPWidenCastRecipe() override = default;
1493
1495 if (auto *UV = getUnderlyingValue())
1496 return new VPWidenCastRecipe(Opcode, getOperand(0), ResultTy,
1497 *cast<CastInst>(UV));
1498
1499 return new VPWidenCastRecipe(Opcode, getOperand(0), ResultTy);
1500 }
1501
1502 VP_CLASSOF_IMPL(VPDef::VPWidenCastSC)
1503
1504 /// Produce widened copies of the cast.
1505 void execute(VPTransformState &State) override;
1506
1507 /// Return the cost of this VPWidenCastRecipe.
1509 VPCostContext &Ctx) const override;
1510
1511#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1512 /// Print the recipe.
1513 void print(raw_ostream &O, const Twine &Indent,
1514 VPSlotTracker &SlotTracker) const override;
1515#endif
1516
1517 Instruction::CastOps getOpcode() const { return Opcode; }
1518
1519 /// Returns the result type of the cast.
1520 Type *getResultType() const { return ResultTy; }
1521};
1522
1523/// A recipe for widening vector intrinsics.
1525 /// ID of the vector intrinsic to widen.
1526 Intrinsic::ID VectorIntrinsicID;
1527
1528 /// Scalar return type of the intrinsic.
1529 Type *ResultTy;
1530
1531 /// True if the intrinsic may read from memory.
1532 bool MayReadFromMemory;
1533
1534 /// True if the intrinsic may read write to memory.
1535 bool MayWriteToMemory;
1536
1537 /// True if the intrinsic may have side-effects.
1538 bool MayHaveSideEffects;
1539
1540public:
1542 ArrayRef<VPValue *> CallArguments, Type *Ty,
1544 : VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, CI),
1545 VPIRMetadata(CI), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
1546 MayReadFromMemory(CI.mayReadFromMemory()),
1547 MayWriteToMemory(CI.mayWriteToMemory()),
1548 MayHaveSideEffects(CI.mayHaveSideEffects()) {}
1549
1551 ArrayRef<VPValue *> CallArguments, Type *Ty,
1553 : VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, DL),
1554 VPIRMetadata(), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
1555 LLVMContext &Ctx = Ty->getContext();
1556 AttributeSet Attrs = Intrinsic::getFnAttributes(Ctx, VectorIntrinsicID);
1557 MemoryEffects ME = Attrs.getMemoryEffects();
1558 MayReadFromMemory = !ME.onlyWritesMemory();
1559 MayWriteToMemory = !ME.onlyReadsMemory();
1560 MayHaveSideEffects = MayWriteToMemory ||
1561 !Attrs.hasAttribute(Attribute::NoUnwind) ||
1562 !Attrs.hasAttribute(Attribute::WillReturn);
1563 }
1564
1565 ~VPWidenIntrinsicRecipe() override = default;
1566
1568 if (Value *CI = getUnderlyingValue())
1569 return new VPWidenIntrinsicRecipe(*cast<CallInst>(CI), VectorIntrinsicID,
1570 operands(), ResultTy, getDebugLoc());
1571 return new VPWidenIntrinsicRecipe(VectorIntrinsicID, operands(), ResultTy,
1572 getDebugLoc());
1573 }
1574
1575 VP_CLASSOF_IMPL(VPDef::VPWidenIntrinsicSC)
1576
1577 /// Produce a widened version of the vector intrinsic.
1578 void execute(VPTransformState &State) override;
1579
1580 /// Return the cost of this vector intrinsic.
1582 VPCostContext &Ctx) const override;
1583
1584 /// Return the ID of the intrinsic.
1585 Intrinsic::ID getVectorIntrinsicID() const { return VectorIntrinsicID; }
1586
1587 /// Return the scalar return type of the intrinsic.
1588 Type *getResultType() const { return ResultTy; }
1589
1590 /// Return to name of the intrinsic as string.
1592
1593 /// Returns true if the intrinsic may read from memory.
1594 bool mayReadFromMemory() const { return MayReadFromMemory; }
1595
1596 /// Returns true if the intrinsic may write to memory.
1597 bool mayWriteToMemory() const { return MayWriteToMemory; }
1598
1599 /// Returns true if the intrinsic may have side-effects.
1600 bool mayHaveSideEffects() const { return MayHaveSideEffects; }
1601
1602#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1603 /// Print the recipe.
1604 void print(raw_ostream &O, const Twine &Indent,
1605 VPSlotTracker &SlotTracker) const override;
1606#endif
1607
1608 bool onlyFirstLaneUsed(const VPValue *Op) const override;
1609};
1610
1611/// A recipe for widening Call instructions using library calls.
1613 public VPIRMetadata {
1614 /// Variant stores a pointer to the chosen function. There is a 1:1 mapping
1615 /// between a given VF and the chosen vectorized variant, so there will be a
1616 /// different VPlan for each VF with a valid variant.
1617 Function *Variant;
1618
1619public:
1621 ArrayRef<VPValue *> CallArguments,
1622 DebugLoc DL = DebugLoc::getUnknown())
1623 : VPRecipeWithIRFlags(VPDef::VPWidenCallSC, CallArguments,
1624 *cast<Instruction>(UV)),
1625 VPIRMetadata(*cast<Instruction>(UV)), Variant(Variant) {
1626 assert(
1627 isa<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue()) &&
1628 "last operand must be the called function");
1629 }
1630
1631 ~VPWidenCallRecipe() override = default;
1632
1634 return new VPWidenCallRecipe(getUnderlyingValue(), Variant, operands(),
1635 getDebugLoc());
1636 }
1637
1638 VP_CLASSOF_IMPL(VPDef::VPWidenCallSC)
1639
1640 /// Produce a widened version of the call instruction.
1641 void execute(VPTransformState &State) override;
1642
1643 /// Return the cost of this VPWidenCallRecipe.
1644 InstructionCost computeCost(ElementCount VF,
1645 VPCostContext &Ctx) const override;
1646
1648 return cast<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue());
1649 }
1650
1651 operand_range args() { return drop_end(operands()); }
1652 const_operand_range args() const { return drop_end(operands()); }
1653
1654#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1655 /// Print the recipe.
1656 void print(raw_ostream &O, const Twine &Indent,
1657 VPSlotTracker &SlotTracker) const override;
1658#endif
1659};
1660
1661/// A recipe representing a sequence of load -> update -> store as part of
1662/// a histogram operation. This means there may be aliasing between vector
1663/// lanes, which is handled by the llvm.experimental.vector.histogram family
1664/// of intrinsics. The only update operations currently supported are
1665/// 'add' and 'sub' where the other term is loop-invariant.
1667 /// Opcode of the update operation, currently either add or sub.
1668 unsigned Opcode;
1669
1670public:
1671 VPHistogramRecipe(unsigned Opcode, ArrayRef<VPValue *> Operands,
1673 : VPRecipeBase(VPDef::VPHistogramSC, Operands, DL), Opcode(Opcode) {}
1674
1675 ~VPHistogramRecipe() override = default;
1676
1678 return new VPHistogramRecipe(Opcode, operands(), getDebugLoc());
1679 }
1680
1681 VP_CLASSOF_IMPL(VPDef::VPHistogramSC);
1682
1683 /// Produce a vectorized histogram operation.
1684 void execute(VPTransformState &State) override;
1685
1686 /// Return the cost of this VPHistogramRecipe.
1688 VPCostContext &Ctx) const override;
1689
1690 unsigned getOpcode() const { return Opcode; }
1691
1692 /// Return the mask operand if one was provided, or a null pointer if all
1693 /// lanes should be executed unconditionally.
1694 VPValue *getMask() const {
1695 return getNumOperands() == 3 ? getOperand(2) : nullptr;
1696 }
1697
1698#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1699 /// Print the recipe
1700 void print(raw_ostream &O, const Twine &Indent,
1701 VPSlotTracker &SlotTracker) const override;
1702#endif
1703};
1704
1705/// A recipe for widening select instructions.
1707 public VPIRMetadata {
1709 : VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I),
1710 VPIRMetadata(I) {}
1711
1712 ~VPWidenSelectRecipe() override = default;
1713
1715 return new VPWidenSelectRecipe(*cast<SelectInst>(getUnderlyingInstr()),
1716 operands());
1717 }
1718
1719 VP_CLASSOF_IMPL(VPDef::VPWidenSelectSC)
1720
1721 /// Produce a widened version of the select instruction.
1722 void execute(VPTransformState &State) override;
1723
1724 /// Return the cost of this VPWidenSelectRecipe.
1725 InstructionCost computeCost(ElementCount VF,
1726 VPCostContext &Ctx) const override;
1727
1728#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1729 /// Print the recipe.
1730 void print(raw_ostream &O, const Twine &Indent,
1731 VPSlotTracker &SlotTracker) const override;
1732#endif
1733
1734 unsigned getOpcode() const { return Instruction::Select; }
1735
1736 VPValue *getCond() const {
1737 return getOperand(0);
1738 }
1739
1740 bool isInvariantCond() const {
1741 return getCond()->isDefinedOutsideLoopRegions();
1742 }
1743
1744 /// Returns true if the recipe only uses the first lane of operand \p Op.
1745 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1746 assert(is_contained(operands(), Op) &&
1747 "Op must be an operand of the recipe");
1748 return Op == getCond() && isInvariantCond();
1749 }
1750};
1751
1752/// A recipe for handling GEP instructions.
1754 bool isPointerLoopInvariant() const {
1755 return getOperand(0)->isDefinedOutsideLoopRegions();
1756 }
1757
1758 bool isIndexLoopInvariant(unsigned I) const {
1759 return getOperand(I + 1)->isDefinedOutsideLoopRegions();
1760 }
1761
1762 bool areAllOperandsInvariant() const {
1763 return all_of(operands(), [](VPValue *Op) {
1764 return Op->isDefinedOutsideLoopRegions();
1765 });
1766 }
1767
1768public:
1770 : VPRecipeWithIRFlags(VPDef::VPWidenGEPSC, Operands, *GEP) {
1772 (void)Metadata;
1774 assert(Metadata.empty() && "unexpected metadata on GEP");
1775 }
1776
1777 ~VPWidenGEPRecipe() override = default;
1778
1780 return new VPWidenGEPRecipe(cast<GetElementPtrInst>(getUnderlyingInstr()),
1781 operands());
1782 }
1783
1784 VP_CLASSOF_IMPL(VPDef::VPWidenGEPSC)
1785
1786 /// Generate the gep nodes.
1787 void execute(VPTransformState &State) override;
1788
1789 /// Return the cost of this VPWidenGEPRecipe.
1791 VPCostContext &Ctx) const override {
1792 // TODO: Compute accurate cost after retiring the legacy cost model.
1793 return 0;
1794 }
1795
1796#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1797 /// Print the recipe.
1798 void print(raw_ostream &O, const Twine &Indent,
1799 VPSlotTracker &SlotTracker) const override;
1800#endif
1801
1802 /// Returns true if the recipe only uses the first lane of operand \p Op.
1803 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1804 assert(is_contained(operands(), Op) &&
1805 "Op must be an operand of the recipe");
1806 if (Op == getOperand(0))
1807 return isPointerLoopInvariant();
1808 else
1809 return !isPointerLoopInvariant() && Op->isDefinedOutsideLoopRegions();
1810 }
1811};
1812
1813/// A recipe to compute a pointer to the last element of each part of a widened
1814/// memory access for widened memory accesses of IndexedTy. Used for
1815/// VPWidenMemoryRecipes or VPInterleaveRecipes that are reversed.
1817 public VPUnrollPartAccessor<2> {
1818 Type *IndexedTy;
1819
1820 /// The constant stride of the pointer computed by this recipe, expressed in
1821 /// units of IndexedTy.
1822 int64_t Stride;
1823
1824public:
1826 int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
1827 : VPRecipeWithIRFlags(VPDef::VPVectorEndPointerSC,
1828 ArrayRef<VPValue *>({Ptr, VF}), GEPFlags, DL),
1829 IndexedTy(IndexedTy), Stride(Stride) {
1830 assert(Stride < 0 && "Stride must be negative");
1831 }
1832
1833 VP_CLASSOF_IMPL(VPDef::VPVectorEndPointerSC)
1834
1836 const VPValue *getVFValue() const { return getOperand(1); }
1837
1838 void execute(VPTransformState &State) override;
1839
1840 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1842 "Op must be an operand of the recipe");
1843 return true;
1844 }
1845
1846 /// Return the cost of this VPVectorPointerRecipe.
1848 VPCostContext &Ctx) const override {
1849 // TODO: Compute accurate cost after retiring the legacy cost model.
1850 return 0;
1851 }
1852
1853 /// Returns true if the recipe only uses the first part of operand \p Op.
1854 bool onlyFirstPartUsed(const VPValue *Op) const override {
1856 "Op must be an operand of the recipe");
1857 assert(getNumOperands() <= 2 && "must have at most two operands");
1858 return true;
1859 }
1860
1862 return new VPVectorEndPointerRecipe(getOperand(0), getVFValue(), IndexedTy,
1863 Stride, getGEPNoWrapFlags(),
1864 getDebugLoc());
1865 }
1866
1867#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1868 /// Print the recipe.
1869 void print(raw_ostream &O, const Twine &Indent,
1870 VPSlotTracker &SlotTracker) const override;
1871#endif
1872};
1873
1874/// A recipe to compute the pointers for widened memory accesses of IndexTy.
1876 public VPUnrollPartAccessor<1> {
1877 Type *IndexedTy;
1878
1879public:
1881 DebugLoc DL)
1882 : VPRecipeWithIRFlags(VPDef::VPVectorPointerSC, ArrayRef<VPValue *>(Ptr),
1883 GEPFlags, DL),
1884 IndexedTy(IndexedTy) {}
1885
1886 VP_CLASSOF_IMPL(VPDef::VPVectorPointerSC)
1887
1888 void execute(VPTransformState &State) override;
1889
1890 bool onlyFirstLaneUsed(const VPValue *Op) const override {
1892 "Op must be an operand of the recipe");
1893 return true;
1894 }
1895
1896 /// Returns true if the recipe only uses the first part of operand \p Op.
1897 bool onlyFirstPartUsed(const VPValue *Op) const override {
1899 "Op must be an operand of the recipe");
1900 assert(getNumOperands() <= 2 && "must have at most two operands");
1901 return true;
1902 }
1903
1905 return new VPVectorPointerRecipe(getOperand(0), IndexedTy,
1907 }
1908
1909 /// Return true if this VPVectorPointerRecipe corresponds to part 0. Note that
1910 /// this is only accurate after the VPlan has been unrolled.
1911 bool isFirstPart() const { return getUnrollPart(*this) == 0; }
1912
1913 /// Return the cost of this VPHeaderPHIRecipe.
1915 VPCostContext &Ctx) const override {
1916 // TODO: Compute accurate cost after retiring the legacy cost model.
1917 return 0;
1918 }
1919
1920#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1921 /// Print the recipe.
1922 void print(raw_ostream &O, const Twine &Indent,
1923 VPSlotTracker &SlotTracker) const override;
1924#endif
1925};
1926
1927/// A pure virtual base class for all recipes modeling header phis, including
1928/// phis for first order recurrences, pointer inductions and reductions. The
1929/// start value is the first operand of the recipe and the incoming value from
1930/// the backedge is the second operand.
1931///
1932/// Inductions are modeled using the following sub-classes:
1933/// * VPCanonicalIVPHIRecipe: Canonical scalar induction of the vector loop,
1934/// starting at a specified value (zero for the main vector loop, the resume
1935/// value for the epilogue vector loop) and stepping by 1. The induction
1936/// controls exiting of the vector loop by comparing against the vector trip
1937/// count. Produces a single scalar PHI for the induction value per
1938/// iteration.
1939/// * VPWidenIntOrFpInductionRecipe: Generates vector values for integer and
1940/// floating point inductions with arbitrary start and step values. Produces
1941/// a vector PHI per-part.
1942/// * VPDerivedIVRecipe: Converts the canonical IV value to the corresponding
1943/// value of an IV with different start and step values. Produces a single
1944/// scalar value per iteration
1945/// * VPScalarIVStepsRecipe: Generates scalar values per-lane based on a
1946/// canonical or derived induction.
1947/// * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
1948/// pointer induction. Produces either a vector PHI per-part or scalar values
1949/// per-lane based on the canonical induction.
1951 public VPPhiAccessors {
1952protected:
1953 VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr,
1954 VPValue *Start, DebugLoc DL = DebugLoc::getUnknown())
1955 : VPSingleDefRecipe(VPDefID, ArrayRef<VPValue *>({Start}),
1956 UnderlyingInstr, DL) {}
1957
1958 const VPRecipeBase *getAsRecipe() const override { return this; }
1959
1960public:
1961 ~VPHeaderPHIRecipe() override = default;
1962
1963 /// Method to support type inquiry through isa, cast, and dyn_cast.
1964 static inline bool classof(const VPRecipeBase *B) {
1965 return B->getVPDefID() >= VPDef::VPFirstHeaderPHISC &&
1966 B->getVPDefID() <= VPDef::VPLastHeaderPHISC;
1967 }
1968 static inline bool classof(const VPValue *V) {
1969 auto *B = V->getDefiningRecipe();
1970 return B && B->getVPDefID() >= VPRecipeBase::VPFirstHeaderPHISC &&
1971 B->getVPDefID() <= VPRecipeBase::VPLastHeaderPHISC;
1972 }
1973
1974 /// Generate the phi nodes.
1975 void execute(VPTransformState &State) override = 0;
1976
1977 /// Return the cost of this header phi recipe.
1978 InstructionCost computeCost(ElementCount VF,
1979 VPCostContext &Ctx) const override;
1980
1981#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1982 /// Print the recipe.
1983 void print(raw_ostream &O, const Twine &Indent,
1984 VPSlotTracker &SlotTracker) const override = 0;
1985#endif
1986
1987 /// Returns the start value of the phi, if one is set.
1989 return getNumOperands() == 0 ? nullptr : getOperand(0);
1990 }
1992 return getNumOperands() == 0 ? nullptr : getOperand(0);
1993 }
1994
1995 /// Update the start value of the recipe.
1996 void setStartValue(VPValue *V) { setOperand(0, V); }
1997
1998 /// Returns the incoming value from the loop backedge.
2000 return getOperand(1);
2001 }
2002
2003 /// Returns the backedge value as a recipe. The backedge value is guaranteed
2004 /// to be a recipe.
2006 return *getBackedgeValue()->getDefiningRecipe();
2007 }
2008};
2009
2010/// Base class for widened induction (VPWidenIntOrFpInductionRecipe and
2011/// VPWidenPointerInductionRecipe), providing shared functionality, including
2012/// retrieving the step value, induction descriptor and original phi node.
2014 const InductionDescriptor &IndDesc;
2015
2016public:
2017 VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start,
2018 VPValue *Step, const InductionDescriptor &IndDesc,
2019 DebugLoc DL)
2020 : VPHeaderPHIRecipe(Kind, IV, Start, DL), IndDesc(IndDesc) {
2021 addOperand(Step);
2022 }
2023
2024 static inline bool classof(const VPRecipeBase *R) {
2025 return R->getVPDefID() == VPDef::VPWidenIntOrFpInductionSC ||
2026 R->getVPDefID() == VPDef::VPWidenPointerInductionSC;
2027 }
2028
2029 static inline bool classof(const VPValue *V) {
2030 auto *R = V->getDefiningRecipe();
2031 return R && classof(R);
2032 }
2033
2034 static inline bool classof(const VPHeaderPHIRecipe *R) {
2035 return classof(static_cast<const VPRecipeBase *>(R));
2036 }
2037
2038 virtual void execute(VPTransformState &State) override = 0;
2039
2040 /// Returns the step value of the induction.
2042 const VPValue *getStepValue() const { return getOperand(1); }
2043
2044 /// Update the step value of the recipe.
2045 void setStepValue(VPValue *V) { setOperand(1, V); }
2046
2048 const VPValue *getVFValue() const { return getOperand(2); }
2049
2050 /// Returns the number of incoming values, also number of incoming blocks.
2051 /// Note that at the moment, VPWidenPointerInductionRecipe only has a single
2052 /// incoming value, its start value.
2053 unsigned getNumIncoming() const override { return 1; }
2054
2055 PHINode *getPHINode() const { return cast<PHINode>(getUnderlyingValue()); }
2056
2057 /// Returns the induction descriptor for the recipe.
2058 const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2059
2061 // TODO: All operands of base recipe must exist and be at same index in
2062 // derived recipe.
2064 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2065 }
2066
2068 // TODO: All operands of base recipe must exist and be at same index in
2069 // derived recipe.
2071 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2072 }
2073
2074 /// Returns true if the recipe only uses the first lane of operand \p Op.
2075 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2077 "Op must be an operand of the recipe");
2078 // The recipe creates its own wide start value, so it only requests the
2079 // first lane of the operand.
2080 // TODO: Remove once creating the start value is modeled separately.
2081 return Op == getStartValue() || Op == getStepValue();
2082 }
2083};
2084
2085/// A recipe for handling phi nodes of integer and floating-point inductions,
2086/// producing their vector values. This is an abstract recipe and must be
2087/// converted to concrete recipes before executing.
2089 TruncInst *Trunc;
2090
2091 // If this recipe is unrolled it will have 2 additional operands.
2092 bool isUnrolled() const { return getNumOperands() == 5; }
2093
2094public:
2096 VPValue *VF, const InductionDescriptor &IndDesc,
2097 DebugLoc DL)
2098 : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2099 Step, IndDesc, DL),
2100 Trunc(nullptr) {
2101 addOperand(VF);
2102 }
2103
2105 VPValue *VF, const InductionDescriptor &IndDesc,
2106 TruncInst *Trunc, DebugLoc DL)
2107 : VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2108 Step, IndDesc, DL),
2109 Trunc(Trunc) {
2110 addOperand(VF);
2112 (void)Metadata;
2113 if (Trunc)
2115 assert(Metadata.empty() && "unexpected metadata on Trunc");
2116 }
2117
2119
2124 }
2125
2126 VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)
2127
2128 void execute(VPTransformState &State) override {
2129 llvm_unreachable("cannot execute this recipe, should be expanded via "
2130 "expandVPWidenIntOrFpInductionRecipe");
2131 }
2132
2133#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2134 /// Print the recipe.
2135 void print(raw_ostream &O, const Twine &Indent,
2136 VPSlotTracker &SlotTracker) const override;
2137#endif
2138
2140 // If the recipe has been unrolled return the VPValue for the induction
2141 // increment.
2142 return isUnrolled() ? getOperand(getNumOperands() - 2) : nullptr;
2143 }
2144
2145 /// Returns the number of incoming values, also number of incoming blocks.
2146 /// Note that at the moment, VPWidenIntOrFpInductionRecipes only have a single
2147 /// incoming value, its start value.
2148 unsigned getNumIncoming() const override { return 1; }
2149
2150 /// Returns the first defined value as TruncInst, if it is one or nullptr
2151 /// otherwise.
2152 TruncInst *getTruncInst() { return Trunc; }
2153 const TruncInst *getTruncInst() const { return Trunc; }
2154
2155 /// Returns true if the induction is canonical, i.e. starting at 0 and
2156 /// incremented by UF * VF (= the original IV is incremented by 1) and has the
2157 /// same type as the canonical induction.
2158 bool isCanonical() const;
2159
2160 /// Returns the scalar type of the induction.
2162 return Trunc ? Trunc->getType()
2164 }
2165
2166 /// Returns the VPValue representing the value of this induction at
2167 /// the last unrolled part, if it exists. Returns itself if unrolling did not
2168 /// take place.
2170 return isUnrolled() ? getOperand(getNumOperands() - 1) : this;
2171 }
2172};
2173
2175 bool IsScalarAfterVectorization;
2176
2177public:
2178 /// Create a new VPWidenPointerInductionRecipe for \p Phi with start value \p
2179 /// Start and the number of elements unrolled \p NumUnrolledElems, typically
2180 /// VF*UF.
2182 VPValue *NumUnrolledElems,
2183 const InductionDescriptor &IndDesc,
2184 bool IsScalarAfterVectorization, DebugLoc DL)
2185 : VPWidenInductionRecipe(VPDef::VPWidenPointerInductionSC, Phi, Start,
2186 Step, IndDesc, DL),
2187 IsScalarAfterVectorization(IsScalarAfterVectorization) {
2188 addOperand(NumUnrolledElems);
2189 }
2190
2192
2195 cast<PHINode>(getUnderlyingInstr()), getOperand(0), getOperand(1),
2196 getOperand(2), getInductionDescriptor(), IsScalarAfterVectorization,
2197 getDebugLoc());
2198 }
2199
2200 VP_CLASSOF_IMPL(VPDef::VPWidenPointerInductionSC)
2201
2202 /// Generate vector values for the pointer induction.
2203 void execute(VPTransformState &State) override {
2204 llvm_unreachable("cannot execute this recipe, should be expanded via "
2205 "expandVPWidenPointerInduction");
2206 };
2207
2208 /// Returns true if only scalar values will be generated.
2209 bool onlyScalarsGenerated(bool IsScalable);
2210
2211#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2212 /// Print the recipe.
2213 void print(raw_ostream &O, const Twine &Indent,
2214 VPSlotTracker &SlotTracker) const override;
2215#endif
2216};
2217
2218/// A recipe for widened phis. Incoming values are operands of the recipe and
2219/// their operand index corresponds to the incoming predecessor block. If the
2220/// recipe is placed in an entry block to a (non-replicate) region, it must have
2221/// exactly 2 incoming values, the first from the predecessor of the region and
2222/// the second from the exiting block of the region.
2224 public VPPhiAccessors {
2225 /// Name to use for the generated IR instruction for the widened phi.
2226 std::string Name;
2227
2228protected:
2229 const VPRecipeBase *getAsRecipe() const override { return this; }
2230
2231public:
2232 /// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
2233 /// debug location \p DL.
2234 VPWidenPHIRecipe(PHINode *Phi, VPValue *Start = nullptr,
2235 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "")
2236 : VPSingleDefRecipe(VPDef::VPWidenPHISC, ArrayRef<VPValue *>(), Phi, DL),
2237 Name(Name.str()) {
2238 if (Start)
2239 addOperand(Start);
2240 }
2241
2243 auto *C = new VPWidenPHIRecipe(cast<PHINode>(getUnderlyingValue()),
2244 getOperand(0), getDebugLoc(), Name);
2245 for (VPValue *Op : llvm::drop_begin(operands()))
2246 C->addOperand(Op);
2247 return C;
2248 }
2249
2250 ~VPWidenPHIRecipe() override = default;
2251
2252 VP_CLASSOF_IMPL(VPDef::VPWidenPHISC)
2253
2254 /// Generate the phi/select nodes.
2255 void execute(VPTransformState &State) override;
2256
2257#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2258 /// Print the recipe.
2259 void print(raw_ostream &O, const Twine &Indent,
2260 VPSlotTracker &SlotTracker) const override;
2261#endif
2262};
2263
2264/// A recipe for handling first-order recurrence phis. The start value is the
2265/// first operand of the recipe and the incoming value from the backedge is the
2266/// second operand.
2269 : VPHeaderPHIRecipe(VPDef::VPFirstOrderRecurrencePHISC, Phi, &Start) {}
2270
2271 VP_CLASSOF_IMPL(VPDef::VPFirstOrderRecurrencePHISC)
2272
2275 cast<PHINode>(getUnderlyingInstr()), *getOperand(0));
2276 }
2277
2278 void execute(VPTransformState &State) override;
2279
2280 /// Return the cost of this first-order recurrence phi recipe.
2282 VPCostContext &Ctx) const override;
2283
2284#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2285 /// Print the recipe.
2286 void print(raw_ostream &O, const Twine &Indent,
2287 VPSlotTracker &SlotTracker) const override;
2288#endif
2289
2290 /// Returns true if the recipe only uses the first lane of operand \p Op.
2291 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2293 "Op must be an operand of the recipe");
2294 return Op == getStartValue();
2295 }
2296};
2297
2298/// A recipe for handling reduction phis. The start value is the first operand
2299/// of the recipe and the incoming value from the backedge is the second
2300/// operand.
2302 public VPUnrollPartAccessor<2> {
2303 /// The recurrence kind of the reduction.
2304 const RecurKind Kind;
2305
2306 /// The phi is part of an in-loop reduction.
2307 bool IsInLoop;
2308
2309 /// The phi is part of an ordered reduction. Requires IsInLoop to be true.
2310 bool IsOrdered;
2311
2312 /// When expanding the reduction PHI, the plan's VF element count is divided
2313 /// by this factor to form the reduction phi's VF.
2314 unsigned VFScaleFactor = 1;
2315
2316public:
2317 /// Create a new VPReductionPHIRecipe for the reduction \p Phi.
2319 bool IsInLoop = false, bool IsOrdered = false,
2320 unsigned VFScaleFactor = 1)
2321 : VPHeaderPHIRecipe(VPDef::VPReductionPHISC, Phi, &Start), Kind(Kind),
2322 IsInLoop(IsInLoop), IsOrdered(IsOrdered), VFScaleFactor(VFScaleFactor) {
2323 assert((!IsOrdered || IsInLoop) && "IsOrdered requires IsInLoop");
2324 }
2325
2326 ~VPReductionPHIRecipe() override = default;
2327
2329 auto *R = new VPReductionPHIRecipe(
2330 dyn_cast_or_null<PHINode>(getUnderlyingValue()), getRecurrenceKind(),
2331 *getOperand(0), IsInLoop, IsOrdered, VFScaleFactor);
2332 R->addOperand(getBackedgeValue());
2333 return R;
2334 }
2335
2336 VP_CLASSOF_IMPL(VPDef::VPReductionPHISC)
2337
2338 /// Generate the phi/select nodes.
2339 void execute(VPTransformState &State) override;
2340
2341 /// Get the factor that the VF of this recipe's output should be scaled by.
2342 unsigned getVFScaleFactor() const { return VFScaleFactor; }
2343
2344#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2345 /// Print the recipe.
2346 void print(raw_ostream &O, const Twine &Indent,
2347 VPSlotTracker &SlotTracker) const override;
2348#endif
2349
2350 /// Returns the number of incoming values, also number of incoming blocks.
2351 /// Note that at the moment, VPWidenPointerInductionRecipe only has a single
2352 /// incoming value, its start value.
2353 unsigned getNumIncoming() const override { return 2; }
2354
2355 /// Returns the recurrence kind of the reduction.
2356 RecurKind getRecurrenceKind() const { return Kind; }
2357
2358 /// Returns true, if the phi is part of an ordered reduction.
2359 bool isOrdered() const { return IsOrdered; }
2360
2361 /// Returns true, if the phi is part of an in-loop reduction.
2362 bool isInLoop() const { return IsInLoop; }
2363
2364 /// Returns true if the recipe only uses the first lane of operand \p Op.
2365 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2367 "Op must be an operand of the recipe");
2368 return isOrdered() || isInLoop();
2369 }
2370};
2371
2372/// A recipe for vectorizing a phi-node as a sequence of mask-based select
2373/// instructions.
2375public:
2376 /// The blend operation is a User of the incoming values and of their
2377 /// respective masks, ordered [I0, M0, I1, M1, I2, M2, ...]. Note that M0 can
2378 /// be omitted (implied by passing an odd number of operands) in which case
2379 /// all other incoming values are merged into it.
2381 : VPSingleDefRecipe(VPDef::VPBlendSC, Operands, Phi, DL) {
2382 assert(Operands.size() > 0 && "Expected at least one operand!");
2383 }
2384
2385 VPBlendRecipe *clone() override {
2386 return new VPBlendRecipe(cast_or_null<PHINode>(getUnderlyingValue()),
2387 operands(), getDebugLoc());
2388 }
2389
2390 VP_CLASSOF_IMPL(VPDef::VPBlendSC)
2391
2392 /// A normalized blend is one that has an odd number of operands, whereby the
2393 /// first operand does not have an associated mask.
2394 bool isNormalized() const { return getNumOperands() % 2; }
2395
2396 /// Return the number of incoming values, taking into account when normalized
2397 /// the first incoming value will have no mask.
2398 unsigned getNumIncomingValues() const {
2399 return (getNumOperands() + isNormalized()) / 2;
2400 }
2401
2402 /// Return incoming value number \p Idx.
2403 VPValue *getIncomingValue(unsigned Idx) const {
2404 return Idx == 0 ? getOperand(0) : getOperand(Idx * 2 - isNormalized());
2405 }
2406
2407 /// Return mask number \p Idx.
2408 VPValue *getMask(unsigned Idx) const {
2409 assert((Idx > 0 || !isNormalized()) && "First index has no mask!");
2410 return Idx == 0 ? getOperand(1) : getOperand(Idx * 2 + !isNormalized());
2411 }
2412
2413 void execute(VPTransformState &State) override {
2414 llvm_unreachable("VPBlendRecipe should be expanded by simplifyBlends");
2415 }
2416
2417 /// Return the cost of this VPWidenMemoryRecipe.
2418 InstructionCost computeCost(ElementCount VF,
2419 VPCostContext &Ctx) const override;
2420
2421#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2422 /// Print the recipe.
2423 void print(raw_ostream &O, const Twine &Indent,
2424 VPSlotTracker &SlotTracker) const override;
2425#endif
2426
2427 /// Returns true if the recipe only uses the first lane of operand \p Op.
2428 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2429 assert(is_contained(operands(), Op) &&
2430 "Op must be an operand of the recipe");
2431 // Recursing through Blend recipes only, must terminate at header phi's the
2432 // latest.
2433 return all_of(users(),
2434 [this](VPUser *U) { return U->onlyFirstLaneUsed(this); });
2435 }
2436};
2437
2438/// VPInterleaveRecipe is a recipe for transforming an interleave group of load
2439/// or stores into one wide load/store and shuffles. The first operand of a
2440/// VPInterleave recipe is the address, followed by the stored values, followed
2441/// by an optional mask.
2443 public VPIRMetadata {
2445
2446 /// Indicates if the interleave group is in a conditional block and requires a
2447 /// mask.
2448 bool HasMask = false;
2449
2450 /// Indicates if gaps between members of the group need to be masked out or if
2451 /// unusued gaps can be loaded speculatively.
2452 bool NeedsMaskForGaps = false;
2453
2454public:
2456 ArrayRef<VPValue *> StoredValues, VPValue *Mask,
2457 bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
2458 : VPRecipeBase(VPDef::VPInterleaveSC, {Addr}, DL), VPIRMetadata(MD),
2459 IG(IG), NeedsMaskForGaps(NeedsMaskForGaps) {
2460 // TODO: extend the masked interleaved-group support to reversed access.
2461 assert((!Mask || !IG->isReverse()) &&
2462 "Reversed masked interleave-group not supported.");
2463 for (unsigned I = 0; I < IG->getFactor(); ++I)
2464 if (Instruction *Inst = IG->getMember(I)) {
2465 if (Inst->getType()->isVoidTy())
2466 continue;
2467 new VPValue(Inst, this);
2468 }
2469
2470 for (auto *SV : StoredValues)
2471 addOperand(SV);
2472 if (Mask) {
2473 HasMask = true;
2474 addOperand(Mask);
2475 }
2476 }
2477 ~VPInterleaveRecipe() override = default;
2478
2480 return new VPInterleaveRecipe(IG, getAddr(), getStoredValues(), getMask(),
2481 NeedsMaskForGaps, *this, getDebugLoc());
2482 }
2483
2484 VP_CLASSOF_IMPL(VPDef::VPInterleaveSC)
2485
2486 /// Return the address accessed by this recipe.
2487 VPValue *getAddr() const {
2488 return getOperand(0); // Address is the 1st, mandatory operand.
2489 }
2490
2491 /// Return the mask used by this recipe. Note that a full mask is represented
2492 /// by a nullptr.
2493 VPValue *getMask() const {
2494 // Mask is optional and therefore the last, currently 2nd operand.
2495 return HasMask ? getOperand(getNumOperands() - 1) : nullptr;
2496 }
2497
2498 /// Return the VPValues stored by this interleave group. If it is a load
2499 /// interleave group, return an empty ArrayRef.
2501 // The first operand is the address, followed by the stored values, followed
2502 // by an optional mask.
2503 return ArrayRef<VPValue *>(op_begin(), getNumOperands())
2504 .slice(1, getNumStoreOperands());
2505 }
2506
2507 /// Generate the wide load or store, and shuffles.
2508 void execute(VPTransformState &State) override;
2509
2510 /// Return the cost of this VPInterleaveRecipe.
2511 InstructionCost computeCost(ElementCount VF,
2512 VPCostContext &Ctx) const override;
2513
2514#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2515 /// Print the recipe.
2516 void print(raw_ostream &O, const Twine &Indent,
2517 VPSlotTracker &SlotTracker) const override;
2518#endif
2519
2521
2522 /// Returns the number of stored operands of this interleave group. Returns 0
2523 /// for load interleave groups.
2524 unsigned getNumStoreOperands() const {
2525 return getNumOperands() - (HasMask ? 2 : 1);
2526 }
2527
2528 /// The recipe only uses the first lane of the address.
2529 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2530 assert(is_contained(operands(), Op) &&
2531 "Op must be an operand of the recipe");
2532 return Op == getAddr() && !llvm::is_contained(getStoredValues(), Op);
2533 }
2534
2535 Instruction *getInsertPos() const { return IG->getInsertPos(); }
2536};
2537
2538/// A recipe to represent inloop reduction operations, performing a reduction on
2539/// a vector operand into a scalar value, and adding the result to a chain.
2540/// The Operands are {ChainOp, VecOp, [Condition]}.
2542 /// The recurrence kind for the reduction in question.
2543 RecurKind RdxKind;
2544 bool IsOrdered;
2545 /// Whether the reduction is conditional.
2546 bool IsConditional = false;
2547
2548protected:
2549 VPReductionRecipe(const unsigned char SC, RecurKind RdxKind,
2552 bool IsOrdered, DebugLoc DL)
2553 : VPRecipeWithIRFlags(SC, Operands, FMFs, DL), RdxKind(RdxKind),
2554 IsOrdered(IsOrdered) {
2555 if (CondOp) {
2556 IsConditional = true;
2557 addOperand(CondOp);
2558 }
2559 setUnderlyingValue(I);
2560 }
2561
2562public:
2564 VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp,
2565 bool IsOrdered, DebugLoc DL = DebugLoc::getUnknown())
2566 : VPReductionRecipe(VPDef::VPReductionSC, RdxKind, FMFs, I,
2567 ArrayRef<VPValue *>({ChainOp, VecOp}), CondOp,
2568 IsOrdered, DL) {}
2569
2571 VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp,
2572 bool IsOrdered, DebugLoc DL = DebugLoc::getUnknown())
2573 : VPReductionRecipe(VPDef::VPReductionSC, RdxKind, FMFs, nullptr,
2574 ArrayRef<VPValue *>({ChainOp, VecOp}), CondOp,
2575 IsOrdered, DL) {}
2576
2577 ~VPReductionRecipe() override = default;
2578
2580 return new VPReductionRecipe(RdxKind, getFastMathFlags(),
2581 getUnderlyingInstr(), getChainOp(), getVecOp(),
2582 getCondOp(), IsOrdered, getDebugLoc());
2583 }
2584
2585 static inline bool classof(const VPRecipeBase *R) {
2586 return R->getVPDefID() == VPRecipeBase::VPReductionSC ||
2587 R->getVPDefID() == VPRecipeBase::VPReductionEVLSC;
2588 }
2589
2590 static inline bool classof(const VPUser *U) {
2591 auto *R = dyn_cast<VPRecipeBase>(U);
2592 return R && classof(R);
2593 }
2594
2595 /// Generate the reduction in the loop.
2596 void execute(VPTransformState &State) override;
2597
2598 /// Return the cost of VPReductionRecipe.
2599 InstructionCost computeCost(ElementCount VF,
2600 VPCostContext &Ctx) const override;
2601
2602#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2603 /// Print the recipe.
2604 void print(raw_ostream &O, const Twine &Indent,
2605 VPSlotTracker &SlotTracker) const override;
2606#endif
2607
2608 /// Return the recurrence kind for the in-loop reduction.
2609 RecurKind getRecurrenceKind() const { return RdxKind; }
2610 /// Return true if the in-loop reduction is ordered.
2611 bool isOrdered() const { return IsOrdered; };
2612 /// Return true if the in-loop reduction is conditional.
2613 bool isConditional() const { return IsConditional; };
2614 /// The VPValue of the scalar Chain being accumulated.
2615 VPValue *getChainOp() const { return getOperand(0); }
2616 /// The VPValue of the vector value to be reduced.
2617 VPValue *getVecOp() const { return getOperand(1); }
2618 /// The VPValue of the condition for the block.
2620 return isConditional() ? getOperand(getNumOperands() - 1) : nullptr;
2621 }
2622};
2623
2624/// A recipe for forming partial reductions. In the loop, an accumulator and
2625/// vector operand are added together and passed to the next iteration as the
2626/// next accumulator. After the loop body, the accumulator is reduced to a
2627/// scalar value.
2629 unsigned Opcode;
2630
2631 /// The divisor by which the VF of this recipe's output should be divided
2632 /// during execution.
2633 unsigned VFScaleFactor;
2634
2635public:
2637 VPValue *Op1, VPValue *Cond, unsigned VFScaleFactor)
2638 : VPPartialReductionRecipe(ReductionInst->getOpcode(), Op0, Op1, Cond,
2639 VFScaleFactor, ReductionInst) {}
2640 VPPartialReductionRecipe(unsigned Opcode, VPValue *Op0, VPValue *Op1,
2641 VPValue *Cond, unsigned ScaleFactor,
2642 Instruction *ReductionInst = nullptr)
2643 : VPReductionRecipe(VPDef::VPPartialReductionSC, RecurKind::Add,
2644 FastMathFlags(), ReductionInst,
2645 ArrayRef<VPValue *>({Op0, Op1}), Cond, false, {}),
2646 Opcode(Opcode), VFScaleFactor(ScaleFactor) {
2647 [[maybe_unused]] auto *AccumulatorRecipe =
2649 assert((isa<VPReductionPHIRecipe>(AccumulatorRecipe) ||
2650 isa<VPPartialReductionRecipe>(AccumulatorRecipe)) &&
2651 "Unexpected operand order for partial reduction recipe");
2652 }
2653 ~VPPartialReductionRecipe() override = default;
2654
2656 return new VPPartialReductionRecipe(Opcode, getOperand(0), getOperand(1),
2657 getCondOp(), VFScaleFactor,
2659 }
2660
2661 VP_CLASSOF_IMPL(VPDef::VPPartialReductionSC)
2662
2663 /// Generate the reduction in the loop.
2664 void execute(VPTransformState &State) override;
2665
2666 /// Return the cost of this VPPartialReductionRecipe.
2668 VPCostContext &Ctx) const override;
2669
2670 /// Get the binary op's opcode.
2671 unsigned getOpcode() const { return Opcode; }
2672
2673 /// Get the factor that the VF of this recipe's output should be scaled by.
2674 unsigned getVFScaleFactor() const { return VFScaleFactor; }
2675
2676#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2677 /// Print the recipe.
2678 void print(raw_ostream &O, const Twine &Indent,
2679 VPSlotTracker &SlotTracker) const override;
2680#endif
2681};
2682
2683/// A recipe to represent inloop reduction operations with vector-predication
2684/// intrinsics, performing a reduction on a vector operand with the explicit
2685/// vector length (EVL) into a scalar value, and adding the result to a chain.
2686/// The Operands are {ChainOp, VecOp, EVL, [Condition]}.
2688public:
2690 DebugLoc DL = DebugLoc::getUnknown())
2692 VPDef::VPReductionEVLSC, R.getRecurrenceKind(),
2693 R.getFastMathFlags(),
2694 cast_or_null<Instruction>(R.getUnderlyingValue()),
2695 ArrayRef<VPValue *>({R.getChainOp(), R.getVecOp(), &EVL}), CondOp,
2696 R.isOrdered(), DL) {}
2697
2698 ~VPReductionEVLRecipe() override = default;
2699
2701 llvm_unreachable("cloning not implemented yet");
2702 }
2703
2704 VP_CLASSOF_IMPL(VPDef::VPReductionEVLSC)
2705
2706 /// Generate the reduction in the loop
2707 void execute(VPTransformState &State) override;
2708
2709#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2710 /// Print the recipe.
2711 void print(raw_ostream &O, const Twine &Indent,
2712 VPSlotTracker &SlotTracker) const override;
2713#endif
2714
2715 /// The VPValue of the explicit vector length.
2716 VPValue *getEVL() const { return getOperand(2); }
2717
2718 /// Returns true if the recipe only uses the first lane of operand \p Op.
2719 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2720 assert(is_contained(operands(), Op) &&
2721 "Op must be an operand of the recipe");
2722 return Op == getEVL();
2723 }
2724};
2725
2726/// VPReplicateRecipe replicates a given instruction producing multiple scalar
2727/// copies of the original scalar type, one per lane, instead of producing a
2728/// single copy of widened type for all lanes. If the instruction is known to be
2729/// a single scalar, only one copy, per lane zero, will be generated.
2731 public VPIRMetadata {
2732 /// Indicator if only a single replica per lane is needed.
2733 bool IsSingleScalar;
2734
2735 /// Indicator if the replicas are also predicated.
2736 bool IsPredicated;
2737
2738public:
2740 bool IsSingleScalar, VPValue *Mask = nullptr,
2742 : VPRecipeWithIRFlags(VPDef::VPReplicateSC, Operands, *I),
2743 VPIRMetadata(Metadata), IsSingleScalar(IsSingleScalar),
2744 IsPredicated(Mask) {
2745 if (Mask)
2746 addOperand(Mask);
2747 }
2748
2749 ~VPReplicateRecipe() override = default;
2750
2752 auto *Copy =
2753 new VPReplicateRecipe(getUnderlyingInstr(), operands(), IsSingleScalar,
2754 isPredicated() ? getMask() : nullptr, *this);
2755 Copy->transferFlags(*this);
2756 return Copy;
2757 }
2758
2759 VP_CLASSOF_IMPL(VPDef::VPReplicateSC)
2760
2761 /// Generate replicas of the desired Ingredient. Replicas will be generated
2762 /// for all parts and lanes unless a specific part and lane are specified in
2763 /// the \p State.
2764 void execute(VPTransformState &State) override;
2765
2766 /// Return the cost of this VPReplicateRecipe.
2767 InstructionCost computeCost(ElementCount VF,
2768 VPCostContext &Ctx) const override;
2769
2770#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2771 /// Print the recipe.
2772 void print(raw_ostream &O, const Twine &Indent,
2773 VPSlotTracker &SlotTracker) const override;
2774#endif
2775
2776 bool isSingleScalar() const { return IsSingleScalar; }
2777
2778 bool isPredicated() const { return IsPredicated; }
2779
2780 /// Returns true if the recipe only uses the first lane of operand \p Op.
2781 bool onlyFirstLaneUsed(const VPValue *Op) const override {
2782 assert(is_contained(operands(), Op) &&
2783 "Op must be an operand of the recipe");
2784 return isSingleScalar();
2785 }
2786
2787 /// Returns true if the recipe uses scalars of operand \p Op.
2788 bool usesScalars(const VPValue *Op) const override {
2789 assert(is_contained(operands(), Op) &&
2790 "Op must be an operand of the recipe");
2791 return true;
2792 }
2793
2794 /// Returns true if the recipe is used by a widened recipe via an intervening
2795 /// VPPredInstPHIRecipe. In this case, the scalar values should also be packed
2796 /// in a vector.
2797 bool shouldPack() const;
2798
2799 /// Return the mask of a predicated VPReplicateRecipe.
2801 assert(isPredicated() && "Trying to get the mask of a unpredicated recipe");
2802 return getOperand(getNumOperands() - 1);
2803 }
2804
2805 unsigned getOpcode() const { return getUnderlyingInstr()->getOpcode(); }
2806};
2807
2808/// A recipe for generating conditional branches on the bits of a mask.
2810public:
2812 : VPRecipeBase(VPDef::VPBranchOnMaskSC, {BlockInMask}, DL) {}
2813
2815 return new VPBranchOnMaskRecipe(getOperand(0), getDebugLoc());
2816 }
2817
2818 VP_CLASSOF_IMPL(VPDef::VPBranchOnMaskSC)
2819
2820 /// Generate the extraction of the appropriate bit from the block mask and the
2821 /// conditional branch.
2822 void execute(VPTransformState &State) override;
2823
2824 /// Return the cost of this VPBranchOnMaskRecipe.
2825 InstructionCost computeCost(ElementCount VF,
2826 VPCostContext &Ctx) const override;
2827
2828#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2829 /// Print the recipe.
2830 void print(raw_ostream &O, const Twine &Indent,
2831 VPSlotTracker &SlotTracker) const override {
2832 O << Indent << "BRANCH-ON-MASK ";
2833 printOperands(O, SlotTracker);
2834 }
2835#endif
2836
2837 /// Returns true if the recipe uses scalars of operand \p Op.
2838 bool usesScalars(const VPValue *Op) const override {
2839 assert(is_contained(operands(), Op) &&
2840 "Op must be an operand of the recipe");
2841 return true;
2842 }
2843};
2844
2845/// A recipe to combine multiple recipes into a single 'expression' recipe,
2846/// which should be considered a single entity for cost-modeling and transforms.
2847/// The recipe needs to be 'decomposed', i.e. replaced by its individual
2848/// expression recipes, before execute. The individual expression recipes are
2849/// completely disconnected from the def-use graph of other recipes not part of
2850/// the expression. Def-use edges between pairs of expression recipes remain
2851/// intact, whereas every edge between an expression recipe and a recipe outside
2852/// the expression is elevated to connect the non-expression recipe with the
2853/// VPExpressionRecipe itself.
2855 /// Recipes included in this VPExpressionRecipe.
2856 SmallVector<VPSingleDefRecipe *> ExpressionRecipes;
2857
2858 /// Temporary VPValues used for external operands of the expression, i.e.
2859 /// operands not defined by recipes in the expression.
2860 SmallVector<VPValue *> LiveInPlaceholders;
2861
2862 enum class ExpressionTypes {
2863 /// Represents an inloop extended reduction operation, performing a
2864 /// reduction on an extended vector operand into a scalar value, and adding
2865 /// the result to a chain.
2866 ExtendedReduction,
2867 /// Represent an inloop multiply-accumulate reduction, multiplying the
2868 /// extended vector operands, performing a reduction.add on the result, and
2869 /// adding the scalar result to a chain.
2870 ExtMulAccReduction,
2871 /// Represent an inloop multiply-accumulate reduction, multiplying the
2872 /// vector operands, performing a reduction.add on the result, and adding
2873 /// the scalar result to a chain.
2874 MulAccReduction,
2875 };
2876
2877 /// Type of the expression.
2878 ExpressionTypes ExpressionType;
2879
2880 /// Construct a new VPExpressionRecipe by internalizing recipes in \p
2881 /// ExpressionRecipes. External operands (i.e. not defined by another recipe
2882 /// in the expression) are replaced by temporary VPValues and the original
2883 /// operands are transferred to the VPExpressionRecipe itself. Clone recipes
2884 /// as needed (excluding last) to ensure they are only used by other recipes
2885 /// in the expression.
2886 VPExpressionRecipe(ExpressionTypes ExpressionType,
2887 ArrayRef<VPSingleDefRecipe *> ExpressionRecipes);
2888
2889public:
2891 : VPExpressionRecipe(ExpressionTypes::ExtendedReduction, {Ext, Red}) {}
2893 : VPExpressionRecipe(ExpressionTypes::MulAccReduction, {Mul, Red}) {}
2896 : VPExpressionRecipe(ExpressionTypes::ExtMulAccReduction,
2897 {Ext0, Ext1, Mul, Red}) {}
2898
2900 for (auto *R : reverse(ExpressionRecipes))
2901 delete R;
2902 for (VPValue *T : LiveInPlaceholders)
2903 delete T;
2904 }
2905
2906 VP_CLASSOF_IMPL(VPDef::VPExpressionSC)
2907
2909 assert(!ExpressionRecipes.empty() && "empty expressions should be removed");
2910 SmallVector<VPSingleDefRecipe *> NewExpressiondRecipes;
2911 for (auto *R : ExpressionRecipes)
2912 NewExpressiondRecipes.push_back(R->clone());
2913 for (auto *New : NewExpressiondRecipes) {
2914 for (const auto &[Idx, Old] : enumerate(ExpressionRecipes))
2915 New->replaceUsesOfWith(Old, NewExpressiondRecipes[Idx]);
2916 // Update placeholder operands in the cloned recipe to use the external
2917 // operands, to be internalized when the cloned expression is constructed.
2918 for (const auto &[Placeholder, OutsideOp] :
2919 zip(LiveInPlaceholders, operands()))
2920 New->replaceUsesOfWith(Placeholder, OutsideOp);
2921 }
2922 return new VPExpressionRecipe(ExpressionType, NewExpressiondRecipes);
2923 }
2924
2925 /// Return the VPValue to use to infer the result type of the recipe.
2927 unsigned OpIdx =
2928 cast<VPReductionRecipe>(ExpressionRecipes.back())->isConditional() ? 2
2929 : 1;
2930 return getOperand(getNumOperands() - OpIdx);
2931 }
2932
2933 /// Insert the recipes of the expression back into the VPlan, directly before
2934 /// the current recipe. Leaves the expression recipe empty, which must be
2935 /// removed before codegen.
2936 void decompose();
2937
2938 /// Method for generating code, must not be called as this recipe is abstract.
2939 void execute(VPTransformState &State) override {
2940 llvm_unreachable("recipe must be removed before execute");
2941 }
2942
2944 VPCostContext &Ctx) const override;
2945
2946#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2947 /// Print the recipe.
2948 void print(raw_ostream &O, const Twine &Indent,
2949 VPSlotTracker &SlotTracker) const override;
2950#endif
2951
2952 /// Returns true if this expression contains recipes that may read from or
2953 /// write to memory.
2954 bool mayReadOrWriteMemory() const;
2955
2956 /// Returns true if this expression contains recipes that may have side
2957 /// effects.
2958 bool mayHaveSideEffects() const;
2959};
2960
2961/// VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when
2962/// control converges back from a Branch-on-Mask. The phi nodes are needed in
2963/// order to merge values that are set under such a branch and feed their uses.
2964/// The phi nodes can be scalar or vector depending on the users of the value.
2965/// This recipe works in concert with VPBranchOnMaskRecipe.
2967public:
2968 /// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
2969 /// nodes after merging back from a Branch-on-Mask.
2971 : VPSingleDefRecipe(VPDef::VPPredInstPHISC, PredV, DL) {}
2972 ~VPPredInstPHIRecipe() override = default;
2973
2975 return new VPPredInstPHIRecipe(getOperand(0), getDebugLoc());
2976 }
2977
2978 VP_CLASSOF_IMPL(VPDef::VPPredInstPHISC)
2979
2980 /// Generates phi nodes for live-outs (from a replicate region) as needed to
2981 /// retain SSA form.
2982 void execute(VPTransformState &State) override;
2983
2984 /// Return the cost of this VPPredInstPHIRecipe.
2986 VPCostContext &Ctx) const override {
2987 // TODO: Compute accurate cost after retiring the legacy cost model.
2988 return 0;
2989 }
2990
2991#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2992 /// Print the recipe.
2993 void print(raw_ostream &O, const Twine &Indent,
2994 VPSlotTracker &SlotTracker) const override;
2995#endif
2996
2997 /// Returns true if the recipe uses scalars of operand \p Op.
2998 bool usesScalars(const VPValue *Op) const override {
2999 assert(is_contained(operands(), Op) &&
3000 "Op must be an operand of the recipe");
3001 return true;
3002 }
3003};
3004
3005/// A common base class for widening memory operations. An optional mask can be
3006/// provided as the last operand.
3008 public VPIRMetadata {
3009protected:
3011
3012 /// Whether the accessed addresses are consecutive.
3014
3015 /// Whether the consecutive accessed addresses are in reverse order.
3017
3018 /// Whether the memory access is masked.
3019 bool IsMasked = false;
3020
3021 void setMask(VPValue *Mask) {
3022 assert(!IsMasked && "cannot re-set mask");
3023 if (!Mask)
3024 return;
3025 addOperand(Mask);
3026 IsMasked = true;
3027 }
3028
3029 VPWidenMemoryRecipe(const char unsigned SC, Instruction &I,
3030 std::initializer_list<VPValue *> Operands,
3031 bool Consecutive, bool Reverse,
3033 : VPRecipeBase(SC, Operands, DL), VPIRMetadata(Metadata), Ingredient(I),
3034 Consecutive(Consecutive), Reverse(Reverse) {
3035 assert((Consecutive || !Reverse) && "Reverse implies consecutive");
3036 }
3037
3038public:
3040 llvm_unreachable("cloning not supported");
3041 }
3042
3043 static inline bool classof(const VPRecipeBase *R) {
3044 return R->getVPDefID() == VPRecipeBase::VPWidenLoadSC ||
3045 R->getVPDefID() == VPRecipeBase::VPWidenStoreSC ||
3046 R->getVPDefID() == VPRecipeBase::VPWidenLoadEVLSC ||
3047 R->getVPDefID() == VPRecipeBase::VPWidenStoreEVLSC;
3048 }
3049
3050 static inline bool classof(const VPUser *U) {
3051 auto *R = dyn_cast<VPRecipeBase>(U);
3052 return R && classof(R);
3053 }
3054
3055 /// Return whether the loaded-from / stored-to addresses are consecutive.
3056 bool isConsecutive() const { return Consecutive; }
3057
3058 /// Return whether the consecutive loaded/stored addresses are in reverse
3059 /// order.
3060 bool isReverse() const { return Reverse; }
3061
3062 /// Return the address accessed by this recipe.
3063 VPValue *getAddr() const { return getOperand(0); }
3064
3065 /// Returns true if the recipe is masked.
3066 bool isMasked() const { return IsMasked; }
3067
3068 /// Return the mask used by this recipe. Note that a full mask is represented
3069 /// by a nullptr.
3070 VPValue *getMask() const {
3071 // Mask is optional and therefore the last operand.
3072 return isMasked() ? getOperand(getNumOperands() - 1) : nullptr;
3073 }
3074
3075 /// Generate the wide load/store.
3076 void execute(VPTransformState &State) override {
3077 llvm_unreachable("VPWidenMemoryRecipe should not be instantiated.");
3078 }
3079
3080 /// Return the cost of this VPWidenMemoryRecipe.
3081 InstructionCost computeCost(ElementCount VF,
3082 VPCostContext &Ctx) const override;
3083
3084 Instruction &getIngredient() const { return Ingredient; }
3085};
3086
3087/// A recipe for widening load operations, using the address to load from and an
3088/// optional mask.
3090 public VPValue {
3092 bool Consecutive, bool Reverse,
3094 : VPWidenMemoryRecipe(VPDef::VPWidenLoadSC, Load, {Addr}, Consecutive,
3095 Reverse, Metadata, DL),
3096 VPValue(this, &Load) {
3097 setMask(Mask);
3098 }
3099
3101 return new VPWidenLoadRecipe(cast<LoadInst>(Ingredient), getAddr(),
3102 getMask(), Consecutive, Reverse, *this,
3103 getDebugLoc());
3104 }
3105
3106 VP_CLASSOF_IMPL(VPDef::VPWidenLoadSC);
3107
3108 /// Generate a wide load or gather.
3109 void execute(VPTransformState &State) override;
3110
3111#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3112 /// Print the recipe.
3113 void print(raw_ostream &O, const Twine &Indent,
3114 VPSlotTracker &SlotTracker) const override;
3115#endif
3116
3117 /// Returns true if the recipe only uses the first lane of operand \p Op.
3118 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3119 assert(is_contained(operands(), Op) &&
3120 "Op must be an operand of the recipe");
3121 // Widened, consecutive loads operations only demand the first lane of
3122 // their address.
3123 return Op == getAddr() && isConsecutive();
3124 }
3125};
3126
3127/// A recipe for widening load operations with vector-predication intrinsics,
3128/// using the address to load from, the explicit vector length and an optional
3129/// mask.
3130struct VPWidenLoadEVLRecipe final : public VPWidenMemoryRecipe, public VPValue {
3132 VPValue *Mask)
3133 : VPWidenMemoryRecipe(VPDef::VPWidenLoadEVLSC, L.getIngredient(),
3134 {Addr, &EVL}, L.isConsecutive(), L.isReverse(), L,
3135 L.getDebugLoc()),
3136 VPValue(this, &getIngredient()) {
3137 setMask(Mask);
3138 }
3139
3140 VP_CLASSOF_IMPL(VPDef::VPWidenLoadEVLSC)
3141
3142 /// Return the EVL operand.
3143 VPValue *getEVL() const { return getOperand(1); }
3144
3145 /// Generate the wide load or gather.
3146 void execute(VPTransformState &State) override;
3147
3148 /// Return the cost of this VPWidenLoadEVLRecipe.
3150 VPCostContext &Ctx) const override;
3151
3152#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3153 /// Print the recipe.
3154 void print(raw_ostream &O, const Twine &Indent,
3155 VPSlotTracker &SlotTracker) const override;
3156#endif
3157
3158 /// Returns true if the recipe only uses the first lane of operand \p Op.
3159 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3161 "Op must be an operand of the recipe");
3162 // Widened loads only demand the first lane of EVL and consecutive loads
3163 // only demand the first lane of their address.
3164 return Op == getEVL() || (Op == getAddr() && isConsecutive());
3165 }
3166};
3167
3168/// A recipe for widening store operations, using the stored value, the address
3169/// to store to and an optional mask.
3172 VPValue *Mask, bool Consecutive, bool Reverse,
3174 : VPWidenMemoryRecipe(VPDef::VPWidenStoreSC, Store, {Addr, StoredVal},
3175 Consecutive, Reverse, Metadata, DL) {
3176 setMask(Mask);
3177 }
3178
3180 return new VPWidenStoreRecipe(cast<StoreInst>(Ingredient), getAddr(),
3181 getStoredValue(), getMask(), Consecutive,
3182 Reverse, *this, getDebugLoc());
3183 }
3184
3185 VP_CLASSOF_IMPL(VPDef::VPWidenStoreSC);
3186
3187 /// Return the value stored by this recipe.
3188 VPValue *getStoredValue() const { return getOperand(1); }
3189
3190 /// Generate a wide store or scatter.
3191 void execute(VPTransformState &State) override;
3192
3193#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3194 /// Print the recipe.
3195 void print(raw_ostream &O, const Twine &Indent,
3196 VPSlotTracker &SlotTracker) const override;
3197#endif
3198
3199 /// Returns true if the recipe only uses the first lane of operand \p Op.
3200 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3201 assert(is_contained(operands(), Op) &&
3202 "Op must be an operand of the recipe");
3203 // Widened, consecutive stores only demand the first lane of their address,
3204 // unless the same operand is also stored.
3205 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
3206 }
3207};
3208
3209/// A recipe for widening store operations with vector-predication intrinsics,
3210/// using the value to store, the address to store to, the explicit vector
3211/// length and an optional mask.
3214 VPValue *Mask)
3215 : VPWidenMemoryRecipe(VPDef::VPWidenStoreEVLSC, S.getIngredient(),
3216 {Addr, S.getStoredValue(), &EVL}, S.isConsecutive(),
3217 S.isReverse(), S, S.getDebugLoc()) {
3218 setMask(Mask);
3219 }
3220
3221 VP_CLASSOF_IMPL(VPDef::VPWidenStoreEVLSC)
3222
3223 /// Return the address accessed by this recipe.
3224 VPValue *getStoredValue() const { return getOperand(1); }
3225
3226 /// Return the EVL operand.
3227 VPValue *getEVL() const { return getOperand(2); }
3228
3229 /// Generate the wide store or scatter.
3230 void execute(VPTransformState &State) override;
3231
3232 /// Return the cost of this VPWidenStoreEVLRecipe.
3234 VPCostContext &Ctx) const override;
3235
3236#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3237 /// Print the recipe.
3238 void print(raw_ostream &O, const Twine &Indent,
3239 VPSlotTracker &SlotTracker) const override;
3240#endif
3241
3242 /// Returns true if the recipe only uses the first lane of operand \p Op.
3243 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3245 "Op must be an operand of the recipe");
3246 if (Op == getEVL()) {
3247 assert(getStoredValue() != Op && "unexpected store of EVL");
3248 return true;
3249 }
3250 // Widened, consecutive memory operations only demand the first lane of
3251 // their address, unless the same operand is also stored. That latter can
3252 // happen with opaque pointers.
3253 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
3254 }
3255};
3256
3257/// Recipe to expand a SCEV expression.
3259 const SCEV *Expr;
3260
3261public:
3263 : VPSingleDefRecipe(VPDef::VPExpandSCEVSC, {}), Expr(Expr) {}
3264
3265 ~VPExpandSCEVRecipe() override = default;
3266
3267 VPExpandSCEVRecipe *clone() override { return new VPExpandSCEVRecipe(Expr); }
3268
3269 VP_CLASSOF_IMPL(VPDef::VPExpandSCEVSC)
3270
3271 void execute(VPTransformState &State) override {
3272 llvm_unreachable("SCEV expressions must be expanded before final execute");
3273 }
3274
3275 /// Return the cost of this VPExpandSCEVRecipe.
3277 VPCostContext &Ctx) const override {
3278 // TODO: Compute accurate cost after retiring the legacy cost model.
3279 return 0;
3280 }
3281
3282#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3283 /// Print the recipe.
3284 void print(raw_ostream &O, const Twine &Indent,
3285 VPSlotTracker &SlotTracker) const override;
3286#endif
3287
3288 const SCEV *getSCEV() const { return Expr; }
3289};
3290
3291/// Canonical scalar induction phi of the vector loop. Starting at the specified
3292/// start value (either 0 or the resume value when vectorizing the epilogue
3293/// loop). VPWidenCanonicalIVRecipe represents the vector version of the
3294/// canonical induction variable.
3296public:
3298 : VPHeaderPHIRecipe(VPDef::VPCanonicalIVPHISC, nullptr, StartV, DL) {}
3299
3300 ~VPCanonicalIVPHIRecipe() override = default;
3301
3303 auto *R = new VPCanonicalIVPHIRecipe(getOperand(0), getDebugLoc());
3304 R->addOperand(getBackedgeValue());
3305 return R;
3306 }
3307
3308 VP_CLASSOF_IMPL(VPDef::VPCanonicalIVPHISC)
3309
3310 void execute(VPTransformState &State) override {
3311 llvm_unreachable("cannot execute this recipe, should be replaced by a "
3312 "scalar phi recipe");
3313 }
3314
3315#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3316 /// Print the recipe.
3317 void print(raw_ostream &O, const Twine &Indent,
3318 VPSlotTracker &SlotTracker) const override;
3319#endif
3320
3321 /// Returns the scalar type of the induction.
3323 return getStartValue()->getLiveInIRValue()->getType();
3324 }
3325
3326 /// Returns true if the recipe only uses the first lane of operand \p Op.
3327 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3329 "Op must be an operand of the recipe");
3330 return true;
3331 }
3332
3333 /// Returns true if the recipe only uses the first part of operand \p Op.
3334 bool onlyFirstPartUsed(const VPValue *Op) const override {
3336 "Op must be an operand of the recipe");
3337 return true;
3338 }
3339
3340 /// Return the cost of this VPCanonicalIVPHIRecipe.
3342 VPCostContext &Ctx) const override {
3343 // For now, match the behavior of the legacy cost model.
3344 return 0;
3345 }
3346};
3347
3348/// A recipe for generating the active lane mask for the vector loop that is
3349/// used to predicate the vector operations.
3350/// TODO: It would be good to use the existing VPWidenPHIRecipe instead and
3351/// remove VPActiveLaneMaskPHIRecipe.
3353public:
3355 : VPHeaderPHIRecipe(VPDef::VPActiveLaneMaskPHISC, nullptr, StartMask,
3356 DL) {}
3357
3358 ~VPActiveLaneMaskPHIRecipe() override = default;
3359
3362 if (getNumOperands() == 2)
3363 R->addOperand(getOperand(1));
3364 return R;
3365 }
3366
3367 VP_CLASSOF_IMPL(VPDef::VPActiveLaneMaskPHISC)
3368
3369 /// Generate the active lane mask phi of the vector loop.
3370 void execute(VPTransformState &State) override;
3371
3372#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3373 /// Print the recipe.
3374 void print(raw_ostream &O, const Twine &Indent,
3375 VPSlotTracker &SlotTracker) const override;
3376#endif
3377};
3378
3379/// A recipe for generating the phi node for the current index of elements,
3380/// adjusted in accordance with EVL value. It starts at the start value of the
3381/// canonical induction and gets incremented by EVL in each iteration of the
3382/// vector loop.
3384public:
3386 : VPHeaderPHIRecipe(VPDef::VPEVLBasedIVPHISC, nullptr, StartIV, DL) {}
3387
3388 ~VPEVLBasedIVPHIRecipe() override = default;
3389
3391 llvm_unreachable("cloning not implemented yet");
3392 }
3393
3394 VP_CLASSOF_IMPL(VPDef::VPEVLBasedIVPHISC)
3395
3396 void execute(VPTransformState &State) override {
3397 llvm_unreachable("cannot execute this recipe, should be replaced by a "
3398 "scalar phi recipe");
3399 }
3400
3401 /// Return the cost of this VPEVLBasedIVPHIRecipe.
3403 VPCostContext &Ctx) const override {
3404 // For now, match the behavior of the legacy cost model.
3405 return 0;
3406 }
3407
3408 /// Returns true if the recipe only uses the first lane of operand \p Op.
3409 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3411 "Op must be an operand of the recipe");
3412 return true;
3413 }
3414
3415#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3416 /// Print the recipe.
3417 void print(raw_ostream &O, const Twine &Indent,
3418 VPSlotTracker &SlotTracker) const override;
3419#endif
3420};
3421
3422/// A Recipe for widening the canonical induction variable of the vector loop.
3424 public VPUnrollPartAccessor<1> {
3425public:
3427 : VPSingleDefRecipe(VPDef::VPWidenCanonicalIVSC, {CanonicalIV}) {}
3428
3429 ~VPWidenCanonicalIVRecipe() override = default;
3430
3432 return new VPWidenCanonicalIVRecipe(
3433 cast<VPCanonicalIVPHIRecipe>(getOperand(0)));
3434 }
3435
3436 VP_CLASSOF_IMPL(VPDef::VPWidenCanonicalIVSC)
3437
3438 /// Generate a canonical vector induction variable of the vector loop, with
3439 /// start = {<Part*VF, Part*VF+1, ..., Part*VF+VF-1> for 0 <= Part < UF}, and
3440 /// step = <VF*UF, VF*UF, ..., VF*UF>.
3441 void execute(VPTransformState &State) override;
3442
3443 /// Return the cost of this VPWidenCanonicalIVPHIRecipe.
3445 VPCostContext &Ctx) const override {
3446 // TODO: Compute accurate cost after retiring the legacy cost model.
3447 return 0;
3448 }
3449
3450#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3451 /// Print the recipe.
3452 void print(raw_ostream &O, const Twine &Indent,
3453 VPSlotTracker &SlotTracker) const override;
3454#endif
3455};
3456
3457/// A recipe for converting the input value \p IV value to the corresponding
3458/// value of an IV with different start and step values, using Start + IV *
3459/// Step.
3461 /// Kind of the induction.
3463 /// If not nullptr, the floating point induction binary operator. Must be set
3464 /// for floating point inductions.
3465 const FPMathOperator *FPBinOp;
3466
3467 /// Name to use for the generated IR instruction for the derived IV.
3468 std::string Name;
3469
3470public:
3472 VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step,
3473 const Twine &Name = "")
3475 IndDesc.getKind(),
3476 dyn_cast_or_null<FPMathOperator>(IndDesc.getInductionBinOp()),
3477 Start, CanonicalIV, Step, Name) {}
3478
3480 const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV,
3481 VPValue *Step, const Twine &Name = "")
3482 : VPSingleDefRecipe(VPDef::VPDerivedIVSC, {Start, IV, Step}), Kind(Kind),
3483 FPBinOp(FPBinOp), Name(Name.str()) {}
3484
3485 ~VPDerivedIVRecipe() override = default;
3486
3488 return new VPDerivedIVRecipe(Kind, FPBinOp, getStartValue(), getOperand(1),
3489 getStepValue());
3490 }
3491
3492 VP_CLASSOF_IMPL(VPDef::VPDerivedIVSC)
3493
3494 /// Generate the transformed value of the induction at offset StartValue (1.
3495 /// operand) + IV (2. operand) * StepValue (3, operand).
3496 void execute(VPTransformState &State) override;
3497
3498 /// Return the cost of this VPDerivedIVRecipe.
3500 VPCostContext &Ctx) const override {
3501 // TODO: Compute accurate cost after retiring the legacy cost model.
3502 return 0;
3503 }
3504
3505#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3506 /// Print the recipe.
3507 void print(raw_ostream &O, const Twine &Indent,
3508 VPSlotTracker &SlotTracker) const override;
3509#endif
3510
3512 return getStartValue()->getLiveInIRValue()->getType();
3513 }
3514
3515 VPValue *getStartValue() const { return getOperand(0); }
3516 VPValue *getStepValue() const { return getOperand(2); }
3517
3518 /// Returns true if the recipe only uses the first lane of operand \p Op.
3519 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3521 "Op must be an operand of the recipe");
3522 return true;
3523 }
3524};
3525
3526/// A recipe for handling phi nodes of integer and floating-point inductions,
3527/// producing their scalar values.
3529 public VPUnrollPartAccessor<3> {
3530 Instruction::BinaryOps InductionOpcode;
3531
3532public:
3535 DebugLoc DL)
3536 : VPRecipeWithIRFlags(VPDef::VPScalarIVStepsSC,
3537 ArrayRef<VPValue *>({IV, Step, VF}), FMFs, DL),
3538 InductionOpcode(Opcode) {}
3539
3541 VPValue *Step, VPValue *VF,
3542 DebugLoc DL = DebugLoc::getUnknown())
3544 IV, Step, VF, IndDesc.getInductionOpcode(),
3545 dyn_cast_or_null<FPMathOperator>(IndDesc.getInductionBinOp())
3546 ? IndDesc.getInductionBinOp()->getFastMathFlags()
3547 : FastMathFlags(),
3548 DL) {}
3549
3550 ~VPScalarIVStepsRecipe() override = default;
3551
3553 return new VPScalarIVStepsRecipe(
3554 getOperand(0), getOperand(1), getOperand(2), InductionOpcode,
3555 hasFastMathFlags() ? getFastMathFlags() : FastMathFlags(),
3556 getDebugLoc());
3557 }
3558
3559 /// Return true if this VPScalarIVStepsRecipe corresponds to part 0. Note that
3560 /// this is only accurate after the VPlan has been unrolled.
3561 bool isPart0() const { return getUnrollPart(*this) == 0; }
3562
3563 VP_CLASSOF_IMPL(VPDef::VPScalarIVStepsSC)
3564
3565 /// Generate the scalarized versions of the phi node as needed by their users.
3566 void execute(VPTransformState &State) override;
3567
3568 /// Return the cost of this VPScalarIVStepsRecipe.
3570 VPCostContext &Ctx) const override {
3571 // TODO: Compute accurate cost after retiring the legacy cost model.
3572 return 0;
3573 }
3574
3575#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3576 /// Print the recipe.
3577 void print(raw_ostream &O, const Twine &Indent,
3578 VPSlotTracker &SlotTracker) const override;
3579#endif
3580
3581 VPValue *getStepValue() const { return getOperand(1); }
3582
3583 /// Returns true if the recipe only uses the first lane of operand \p Op.
3584 bool onlyFirstLaneUsed(const VPValue *Op) const override {
3585 assert(is_contained(operands(), Op) &&
3586 "Op must be an operand of the recipe");
3587 return true;
3588 }
3589};
3590
3591/// Casting from VPRecipeBase -> VPPhiAccessors is supported for all recipe
3592/// types implementing VPPhiAccessors. Used by isa<> & co.
3594 static inline bool isPossible(const VPRecipeBase *f) {
3595 // TODO: include VPPredInstPHIRecipe too, once it implements VPPhiAccessors.
3596 return isa<VPIRPhi, VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPhi>(f);
3597 }
3598};
3599/// Support casting from VPRecipeBase -> VPPhiAccessors, by down-casting to the
3600/// recipe types implementing VPPhiAccessors. Used by cast<>, dyn_cast<> & co.
3601template <typename SrcTy>
3602struct CastInfoVPPhiAccessors : public CastIsPossible<VPPhiAccessors, SrcTy> {
3603
3605
3606 /// doCast is used by cast<>.
3607 static inline VPPhiAccessors *doCast(SrcTy R) {
3608 return const_cast<VPPhiAccessors *>([R]() -> const VPPhiAccessors * {
3609 switch (R->getVPDefID()) {
3610 case VPDef::VPInstructionSC:
3611 return cast<VPPhi>(R);
3612 case VPDef::VPIRInstructionSC:
3613 return cast<VPIRPhi>(R);
3614 case VPDef::VPWidenPHISC:
3615 return cast<VPWidenPHIRecipe>(R);
3616 default:
3617 return cast<VPHeaderPHIRecipe>(R);
3618 }
3619 }());
3620 }
3621
3622 /// doCastIfPossible is used by dyn_cast<>.
3623 static inline VPPhiAccessors *doCastIfPossible(SrcTy f) {
3624 if (!Self::isPossible(f))
3625 return nullptr;
3626 return doCast(f);
3627 }
3628};
3629template <>
3632template <>
3635
3636/// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
3637/// holds a sequence of zero or more VPRecipe's each representing a sequence of
3638/// output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
3640 friend class VPlan;
3641
3642 /// Use VPlan::createVPBasicBlock to create VPBasicBlocks.
3643 VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr)
3644 : VPBlockBase(VPBasicBlockSC, Name.str()) {
3645 if (Recipe)
3646 appendRecipe(Recipe);
3647 }
3648
3649public:
3651
3652protected:
3653 /// The VPRecipes held in the order of output instructions to generate.
3655
3656 VPBasicBlock(const unsigned char BlockSC, const Twine &Name = "")
3657 : VPBlockBase(BlockSC, Name.str()) {}
3658
3659public:
3660 ~VPBasicBlock() override {
3661 while (!Recipes.empty())
3662 Recipes.pop_back();
3663 }
3664
3665 /// Instruction iterators...
3670
3671 //===--------------------------------------------------------------------===//
3672 /// Recipe iterator methods
3673 ///
3674 inline iterator begin() { return Recipes.begin(); }
3675 inline const_iterator begin() const { return Recipes.begin(); }
3676 inline iterator end() { return Recipes.end(); }
3677 inline const_iterator end() const { return Recipes.end(); }
3678
3679 inline reverse_iterator rbegin() { return Recipes.rbegin(); }
3680 inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); }
3681 inline reverse_iterator rend() { return Recipes.rend(); }
3682 inline const_reverse_iterator rend() const { return Recipes.rend(); }
3683
3684 inline size_t size() const { return Recipes.size(); }
3685 inline bool empty() const { return Recipes.empty(); }
3686 inline const VPRecipeBase &front() const { return Recipes.front(); }
3687 inline VPRecipeBase &front() { return Recipes.front(); }
3688 inline const VPRecipeBase &back() const { return Recipes.back(); }
3689 inline VPRecipeBase &back() { return Recipes.back(); }
3690
3691 /// Returns a reference to the list of recipes.
3692 RecipeListTy &getRecipeList() { return Recipes; }
3693
3694 /// Returns a pointer to a member of the recipe list.
3696 return &VPBasicBlock::Recipes;
3697 }
3698
3699 /// Method to support type inquiry through isa, cast, and dyn_cast.
3700 static inline bool classof(const VPBlockBase *V) {
3701 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
3702 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3703 }
3704
3705 void insert(VPRecipeBase *Recipe, iterator InsertPt) {
3706 assert(Recipe && "No recipe to append.");
3707 assert(!Recipe->Parent && "Recipe already in VPlan");
3708 Recipe->Parent = this;
3709 Recipes.insert(InsertPt, Recipe);
3710 }
3711
3712 /// Augment the existing recipes of a VPBasicBlock with an additional
3713 /// \p Recipe as the last recipe.
3714 void appendRecipe(VPRecipeBase *Recipe) { insert(Recipe, end()); }
3715
3716 /// The method which generates the output IR instructions that correspond to
3717 /// this VPBasicBlock, thereby "executing" the VPlan.
3718 void execute(VPTransformState *State) override;
3719
3720 /// Return the cost of this VPBasicBlock.
3721 InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override;
3722
3723 /// Return the position of the first non-phi node recipe in the block.
3724 iterator getFirstNonPhi();
3725
3726 /// Returns an iterator range over the PHI-like recipes in the block.
3728 return make_range(begin(), getFirstNonPhi());
3729 }
3730
3731 /// Split current block at \p SplitAt by inserting a new block between the
3732 /// current block and its successors and moving all recipes starting at
3733 /// SplitAt to the new block. Returns the new block.
3734 VPBasicBlock *splitAt(iterator SplitAt);
3735
3736 VPRegionBlock *getEnclosingLoopRegion();
3737 const VPRegionBlock *getEnclosingLoopRegion() const;
3738
3739#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3740 /// Print this VPBsicBlock to \p O, prefixing all lines with \p Indent. \p
3741 /// SlotTracker is used to print unnamed VPValue's using consequtive numbers.
3742 ///
3743 /// Note that the numbering is applied to the whole VPlan, so printing
3744 /// individual blocks is consistent with the whole VPlan printing.
3745 void print(raw_ostream &O, const Twine &Indent,
3746 VPSlotTracker &SlotTracker) const override;
3747 using VPBlockBase::print; // Get the print(raw_stream &O) version.
3748#endif
3749
3750 /// If the block has multiple successors, return the branch recipe terminating
3751 /// the block. If there are no or only a single successor, return nullptr;
3752 VPRecipeBase *getTerminator();
3753 const VPRecipeBase *getTerminator() const;
3754
3755 /// Returns true if the block is exiting it's parent region.
3756 bool isExiting() const;
3757
3758 /// Clone the current block and it's recipes, without updating the operands of
3759 /// the cloned recipes.
3760 VPBasicBlock *clone() override;
3761
3762 /// Returns the predecessor block at index \p Idx with the predecessors as per
3763 /// the corresponding plain CFG. If the block is an entry block to a region,
3764 /// the first predecessor is the single predecessor of a region, and the
3765 /// second predecessor is the exiting block of the region.
3766 const VPBasicBlock *getCFGPredecessor(unsigned Idx) const;
3767
3768protected:
3769 /// Execute the recipes in the IR basic block \p BB.
3770 void executeRecipes(VPTransformState *State, BasicBlock *BB);
3771
3772 /// Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block
3773 /// generated for this VPBB.
3774 void connectToPredecessors(VPTransformState &State);
3775
3776private:
3777 /// Create an IR BasicBlock to hold the output instructions generated by this
3778 /// VPBasicBlock, and return it. Update the CFGState accordingly.
3779 BasicBlock *createEmptyBasicBlock(VPTransformState &State);
3780};
3781
3782inline const VPBasicBlock *
3785}
3786
3787/// A special type of VPBasicBlock that wraps an existing IR basic block.
3788/// Recipes of the block get added before the first non-phi instruction in the
3789/// wrapped block.
3790/// Note: At the moment, VPIRBasicBlock can only be used to wrap VPlan's
3791/// preheader block.
3793 friend class VPlan;
3794
3795 BasicBlock *IRBB;
3796
3797 /// Use VPlan::createVPIRBasicBlock to create VPIRBasicBlocks.
3799 : VPBasicBlock(VPIRBasicBlockSC,
3800 (Twine("ir-bb<") + IRBB->getName() + Twine(">")).str()),
3801 IRBB(IRBB) {}
3802
3803public:
3804 ~VPIRBasicBlock() override {}
3805
3806 static inline bool classof(const VPBlockBase *V) {
3807 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3808 }
3809
3810 /// The method which generates the output IR instructions that correspond to
3811 /// this VPBasicBlock, thereby "executing" the VPlan.
3812 void execute(VPTransformState *State) override;
3813
3814 VPIRBasicBlock *clone() override;
3815
3816 BasicBlock *getIRBasicBlock() const { return IRBB; }
3817};
3818
3819/// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
3820/// which form a Single-Entry-Single-Exiting subgraph of the output IR CFG.
3821/// A VPRegionBlock may indicate that its contents are to be replicated several
3822/// times. This is designed to support predicated scalarization, in which a
3823/// scalar if-then code structure needs to be generated VF * UF times. Having
3824/// this replication indicator helps to keep a single model for multiple
3825/// candidate VF's. The actual replication takes place only once the desired VF
3826/// and UF have been determined.
3828 friend class VPlan;
3829
3830 /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
3831 VPBlockBase *Entry;
3832
3833 /// Hold the Single Exiting block of the SESE region modelled by the
3834 /// VPRegionBlock.
3835 VPBlockBase *Exiting;
3836
3837 /// An indicator whether this region is to generate multiple replicated
3838 /// instances of output IR corresponding to its VPBlockBases.
3839 bool IsReplicator;
3840
3841 /// Use VPlan::createVPRegionBlock to create VPRegionBlocks.
3842 VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting,
3843 const std::string &Name = "", bool IsReplicator = false)
3844 : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exiting(Exiting),
3845 IsReplicator(IsReplicator) {
3846 assert(Entry->getPredecessors().empty() && "Entry block has predecessors.");
3847 assert(Exiting->getSuccessors().empty() && "Exit block has successors.");
3848 Entry->setParent(this);
3849 Exiting->setParent(this);
3850 }
3851 VPRegionBlock(const std::string &Name = "", bool IsReplicator = false)
3852 : VPBlockBase(VPRegionBlockSC, Name), Entry(nullptr), Exiting(nullptr),
3853 IsReplicator(IsReplicator) {}
3854
3855public:
3856 ~VPRegionBlock() override {}
3857
3858 /// Method to support type inquiry through isa, cast, and dyn_cast.
3859 static inline bool classof(const VPBlockBase *V) {
3860 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
3861 }
3862
3863 const VPBlockBase *getEntry() const { return Entry; }
3864 VPBlockBase *getEntry() { return Entry; }
3865
3866 /// Set \p EntryBlock as the entry VPBlockBase of this VPRegionBlock. \p
3867 /// EntryBlock must have no predecessors.
3868 void setEntry(VPBlockBase *EntryBlock) {
3869 assert(EntryBlock->getPredecessors().empty() &&
3870 "Entry block cannot have predecessors.");
3871 Entry = EntryBlock;
3872 EntryBlock->setParent(this);
3873 }
3874
3875 const VPBlockBase *getExiting() const { return Exiting; }
3876 VPBlockBase *getExiting() { return Exiting; }
3877
3878 /// Set \p ExitingBlock as the exiting VPBlockBase of this VPRegionBlock. \p
3879 /// ExitingBlock must have no successors.
3880 void setExiting(VPBlockBase *ExitingBlock) {
3881 assert(ExitingBlock->getSuccessors().empty() &&
3882 "Exit block cannot have successors.");
3883 Exiting = ExitingBlock;
3884 ExitingBlock->setParent(this);
3885 }
3886
3887 /// Returns the pre-header VPBasicBlock of the loop region.
3889 assert(!isReplicator() && "should only get pre-header of loop regions");
3890 return getSinglePredecessor()->getExitingBasicBlock();
3891 }
3892
3893 /// An indicator whether this region is to generate multiple replicated
3894 /// instances of output IR corresponding to its VPBlockBases.
3895 bool isReplicator() const { return IsReplicator; }
3896
3897 /// The method which generates the output IR instructions that correspond to
3898 /// this VPRegionBlock, thereby "executing" the VPlan.
3899 void execute(VPTransformState *State) override;
3900
3901 // Return the cost of this region.
3902 InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override;
3903
3904#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3905 /// Print this VPRegionBlock to \p O (recursively), prefixing all lines with
3906 /// \p Indent. \p SlotTracker is used to print unnamed VPValue's using
3907 /// consequtive numbers.
3908 ///
3909 /// Note that the numbering is applied to the whole VPlan, so printing
3910 /// individual regions is consistent with the whole VPlan printing.
3911 void print(raw_ostream &O, const Twine &Indent,
3912 VPSlotTracker &SlotTracker) const override;
3913 using VPBlockBase::print; // Get the print(raw_stream &O) version.
3914#endif
3915
3916 /// Clone all blocks in the single-entry single-exit region of the block and
3917 /// their recipes without updating the operands of the cloned recipes.
3918 VPRegionBlock *clone() override;
3919
3920 /// Remove the current region from its VPlan, connecting its predecessor to
3921 /// its entry, and its exiting block to its successor.
3922 void dissolveToCFGLoop();
3923};
3924
3925/// VPlan models a candidate for vectorization, encoding various decisions take
3926/// to produce efficient output IR, including which branches, basic-blocks and
3927/// output IR instructions to generate, and their cost. VPlan holds a
3928/// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry
3929/// VPBasicBlock.
3930class VPlan {
3931 friend class VPlanPrinter;
3932 friend class VPSlotTracker;
3933
3934 /// VPBasicBlock corresponding to the original preheader. Used to place
3935 /// VPExpandSCEV recipes for expressions used during skeleton creation and the
3936 /// rest of VPlan execution.
3937 /// When this VPlan is used for the epilogue vector loop, the entry will be
3938 /// replaced by a new entry block created during skeleton creation.
3939 VPBasicBlock *Entry;
3940
3941 /// VPIRBasicBlock wrapping the header of the original scalar loop.
3942 VPIRBasicBlock *ScalarHeader;
3943
3944 /// Immutable list of VPIRBasicBlocks wrapping the exit blocks of the original
3945 /// scalar loop. Note that some exit blocks may be unreachable at the moment,
3946 /// e.g. if the scalar epilogue always executes.
3948
3949 /// Holds the VFs applicable to this VPlan.
3951
3952 /// Holds the UFs applicable to this VPlan. If empty, the VPlan is valid for
3953 /// any UF.
3955
3956 /// Holds the name of the VPlan, for printing.
3957 std::string Name;
3958
3959 /// Represents the trip count of the original loop, for folding
3960 /// the tail.
3961 VPValue *TripCount = nullptr;
3962
3963 /// Represents the backedge taken count of the original loop, for folding
3964 /// the tail. It equals TripCount - 1.
3965 VPValue *BackedgeTakenCount = nullptr;
3966
3967 /// Represents the vector trip count.
3968 VPValue VectorTripCount;
3969
3970 /// Represents the vectorization factor of the loop.
3971 VPValue VF;
3972
3973 /// Represents the loop-invariant VF * UF of the vector loop region.
3974 VPValue VFxUF;
3975
3976 /// Holds a mapping between Values and their corresponding VPValue inside
3977 /// VPlan.
3978 Value2VPValueTy Value2VPValue;
3979
3980 /// Contains all the external definitions created for this VPlan. External
3981 /// definitions are VPValues that hold a pointer to their underlying IR.
3983
3984 /// Mapping from SCEVs to the VPValues representing their expansions.
3985 /// NOTE: This mapping is temporary and will be removed once all users have
3986 /// been modeled in VPlan directly.
3987 DenseMap<const SCEV *, VPValue *> SCEVToExpansion;
3988
3989 /// Blocks allocated and owned by the VPlan. They will be deleted once the
3990 /// VPlan is destroyed.
3991 SmallVector<VPBlockBase *> CreatedBlocks;
3992
3993 /// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
3994 /// wrapping the original header of the scalar loop.
3995 VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader)
3996 : Entry(Entry), ScalarHeader(ScalarHeader) {
3997 Entry->setPlan(this);
3998 assert(ScalarHeader->getNumSuccessors() == 0 &&
3999 "scalar header must be a leaf node");
4000 }
4001
4002public:
4003 /// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the
4004 /// original preheader and scalar header of \p L, to be used as entry and
4005 /// scalar header blocks of the new VPlan.
4006 VPlan(Loop *L);
4007
4008 /// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock
4009 /// wrapping \p ScalarHeaderBB and a trip count of \p TC.
4010 VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC) {
4011 setEntry(createVPBasicBlock("preheader"));
4012 ScalarHeader = createVPIRBasicBlock(ScalarHeaderBB);
4013 TripCount = TC;
4014 }
4015
4017
4019 Entry = VPBB;
4020 VPBB->setPlan(this);
4021 }
4022
4023 /// Generate the IR code for this VPlan.
4024 void execute(VPTransformState *State);
4025
4026 /// Return the cost of this plan.
4028
4029 VPBasicBlock *getEntry() { return Entry; }
4030 const VPBasicBlock *getEntry() const { return Entry; }
4031
4032 /// Returns the preheader of the vector loop region, if one exists, or null
4033 /// otherwise.
4035 VPRegionBlock *VectorRegion = getVectorLoopRegion();
4036 return VectorRegion
4037 ? cast<VPBasicBlock>(VectorRegion->getSinglePredecessor())
4038 : nullptr;
4039 }
4040
4041 /// Returns the VPRegionBlock of the vector loop.
4044
4045 /// Returns the 'middle' block of the plan, that is the block that selects
4046 /// whether to execute the scalar tail loop or the exit block from the loop
4047 /// latch. If there is an early exit from the vector loop, the middle block
4048 /// conceptully has the early exit block as third successor, split accross 2
4049 /// VPBBs. In that case, the second VPBB selects whether to execute the scalar
4050 /// tail loop or the exit bock. If the scalar tail loop or exit block are
4051 /// known to always execute, the middle block may branch directly to that
4052 /// block. This function cannot be called once the vector loop region has been
4053 /// removed.
4055 VPRegionBlock *LoopRegion = getVectorLoopRegion();
4056 assert(
4057 LoopRegion &&
4058 "cannot call the function after vector loop region has been removed");
4059 auto *RegionSucc = cast<VPBasicBlock>(LoopRegion->getSingleSuccessor());
4060 if (RegionSucc->getSingleSuccessor() ||
4061 is_contained(RegionSucc->getSuccessors(), getScalarPreheader()))
4062 return RegionSucc;
4063 // There is an early exit. The successor of RegionSucc is the middle block.
4064 return cast<VPBasicBlock>(RegionSucc->getSuccessors()[1]);
4065 }
4066
4068 return const_cast<VPlan *>(this)->getMiddleBlock();
4069 }
4070
4071 /// Return the VPBasicBlock for the preheader of the scalar loop.
4073 return cast<VPBasicBlock>(getScalarHeader()->getSinglePredecessor());
4074 }
4075
4076 /// Return the VPIRBasicBlock wrapping the header of the scalar loop.
4077 VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; }
4078
4079 /// Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of
4080 /// the original scalar loop.
4081 ArrayRef<VPIRBasicBlock *> getExitBlocks() const { return ExitBlocks; }
4082
4083 /// Return the VPIRBasicBlock corresponding to \p IRBB. \p IRBB must be an
4084 /// exit block.
4086
4087 /// Returns true if \p VPBB is an exit block.
4088 bool isExitBlock(VPBlockBase *VPBB);
4089
4090 /// The trip count of the original loop.
4092 assert(TripCount && "trip count needs to be set before accessing it");
4093 return TripCount;
4094 }
4095
4096 /// Set the trip count assuming it is currently null; if it is not - use
4097 /// resetTripCount().
4098 void setTripCount(VPValue *NewTripCount) {
4099 assert(!TripCount && NewTripCount && "TripCount should not be set yet.");
4100 TripCount = NewTripCount;
4101 }
4102
4103 /// Resets the trip count for the VPlan. The caller must make sure all uses of
4104 /// the original trip count have been replaced.
4105 void resetTripCount(VPValue *NewTripCount) {
4106 assert(TripCount && NewTripCount && TripCount->getNumUsers() == 0 &&
4107 "TripCount must be set when resetting");
4108 TripCount = NewTripCount;
4109 }
4110
4111 /// The backedge taken count of the original loop.
4113 if (!BackedgeTakenCount)
4114 BackedgeTakenCount = new VPValue();
4115 return BackedgeTakenCount;
4116 }
4117
4118 /// The vector trip count.
4119 VPValue &getVectorTripCount() { return VectorTripCount; }
4120
4121 /// Returns the VF of the vector loop region.
4122 VPValue &getVF() { return VF; };
4123
4124 /// Returns VF * UF of the vector loop region.
4125 VPValue &getVFxUF() { return VFxUF; }
4126
4129 }
4130
4131 void addVF(ElementCount VF) { VFs.insert(VF); }
4132
4134 assert(hasVF(VF) && "Cannot set VF not already in plan");
4135 VFs.clear();
4136 VFs.insert(VF);
4137 }
4138
4139 bool hasVF(ElementCount VF) const { return VFs.count(VF); }
4140 bool hasScalableVF() const {
4141 return any_of(VFs, [](ElementCount VF) { return VF.isScalable(); });
4142 }
4143
4144 /// Returns an iterator range over all VFs of the plan.
4147 return VFs;
4148 }
4149
4150 bool hasScalarVFOnly() const {
4151 bool HasScalarVFOnly = VFs.size() == 1 && VFs[0].isScalar();
4152 assert(HasScalarVFOnly == hasVF(ElementCount::getFixed(1)) &&
4153 "Plan with scalar VF should only have a single VF");
4154 return HasScalarVFOnly;
4155 }
4156
4157 bool hasUF(unsigned UF) const { return UFs.empty() || UFs.contains(UF); }
4158
4159 unsigned getUF() const {
4160 assert(UFs.size() == 1 && "Expected a single UF");
4161 return UFs[0];
4162 }
4163
4164 void setUF(unsigned UF) {
4165 assert(hasUF(UF) && "Cannot set the UF not already in plan");
4166 UFs.clear();
4167 UFs.insert(UF);
4168 }
4169
4170 /// Returns true if the VPlan already has been unrolled, i.e. it has a single
4171 /// concrete UF.
4172 bool isUnrolled() const { return UFs.size() == 1; }
4173
4174 /// Return a string with the name of the plan and the applicable VFs and UFs.
4175 std::string getName() const;
4176
4177 void setName(const Twine &newName) { Name = newName.str(); }
4178
4179 /// Gets the live-in VPValue for \p V or adds a new live-in (if none exists
4180 /// yet) for \p V.
4182 assert(V && "Trying to get or add the VPValue of a null Value");
4183 auto [It, Inserted] = Value2VPValue.try_emplace(V);
4184 if (Inserted) {
4185 VPValue *VPV = new VPValue(V);
4186 VPLiveIns.push_back(VPV);
4187 assert(VPV->isLiveIn() && "VPV must be a live-in.");
4188 It->second = VPV;
4189 }
4190
4191 assert(It->second->isLiveIn() && "Only live-ins should be in mapping");
4192 return It->second;
4193 }
4194
4195 /// Return a VPValue wrapping i1 true.
4197 LLVMContext &Ctx = getContext();
4199 }
4200
4201 /// Return a VPValue wrapping i1 false.
4203 LLVMContext &Ctx = getContext();
4205 }
4206
4207 /// Return the live-in VPValue for \p V, if there is one or nullptr otherwise.
4208 VPValue *getLiveIn(Value *V) const { return Value2VPValue.lookup(V); }
4209
4210 /// Return the list of live-in VPValues available in the VPlan.
4212 assert(all_of(Value2VPValue,
4213 [this](const auto &P) {
4214 return is_contained(VPLiveIns, P.second);
4215 }) &&
4216 "all VPValues in Value2VPValue must also be in VPLiveIns");
4217 return VPLiveIns;
4218 }
4219
4220#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4221 /// Print the live-ins of this VPlan to \p O.
4222 void printLiveIns(raw_ostream &O) const;
4223
4224 /// Print this VPlan to \p O.
4225 void print(raw_ostream &O) const;
4226
4227 /// Print this VPlan in DOT format to \p O.
4228 void printDOT(raw_ostream &O) const;
4229
4230 /// Dump the plan to stderr (for debugging).
4231 LLVM_DUMP_METHOD void dump() const;
4232#endif
4233
4234 /// Returns the canonical induction recipe of the vector loop.
4237 if (EntryVPBB->empty()) {
4238 // VPlan native path.
4239 EntryVPBB = cast<VPBasicBlock>(EntryVPBB->getSingleSuccessor());
4240 }
4241 return cast<VPCanonicalIVPHIRecipe>(&*EntryVPBB->begin());
4242 }
4243
4244 VPValue *getSCEVExpansion(const SCEV *S) const {
4245 return SCEVToExpansion.lookup(S);
4246 }
4247
4248 void addSCEVExpansion(const SCEV *S, VPValue *V) {
4249 assert(!SCEVToExpansion.contains(S) && "SCEV already expanded");
4250 SCEVToExpansion[S] = V;
4251 }
4252
4253 /// Clone the current VPlan, update all VPValues of the new VPlan and cloned
4254 /// recipes to refer to the clones, and return it.
4255 VPlan *duplicate();
4256
4257 /// Create a new VPBasicBlock with \p Name and containing \p Recipe if
4258 /// present. The returned block is owned by the VPlan and deleted once the
4259 /// VPlan is destroyed.
4261 VPRecipeBase *Recipe = nullptr) {
4262 auto *VPB = new VPBasicBlock(Name, Recipe);
4263 CreatedBlocks.push_back(VPB);
4264 return VPB;
4265 }
4266
4267 /// Create a new VPRegionBlock with \p Entry, \p Exiting and \p Name. If \p
4268 /// IsReplicator is true, the region is a replicate region. The returned block
4269 /// is owned by the VPlan and deleted once the VPlan is destroyed.
4271 const std::string &Name = "",
4272 bool IsReplicator = false) {
4273 auto *VPB = new VPRegionBlock(Entry, Exiting, Name, IsReplicator);
4274 CreatedBlocks.push_back(VPB);
4275 return VPB;
4276 }
4277
4278 /// Create a new loop VPRegionBlock with \p Name and entry and exiting blocks set
4279 /// to nullptr. The returned block is owned by the VPlan and deleted once the
4280 /// VPlan is destroyed.
4281 VPRegionBlock *createVPRegionBlock(const std::string &Name = "") {
4282 auto *VPB = new VPRegionBlock(Name);
4283 CreatedBlocks.push_back(VPB);
4284 return VPB;
4285 }
4286
4287 /// Create a VPIRBasicBlock wrapping \p IRBB, but do not create
4288 /// VPIRInstructions wrapping the instructions in t\p IRBB. The returned
4289 /// block is owned by the VPlan and deleted once the VPlan is destroyed.
4291
4292 /// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
4293 /// instructions in \p IRBB, except its terminator which is managed by the
4294 /// successors of the block in VPlan. The returned block is owned by the VPlan
4295 /// and deleted once the VPlan is destroyed.
4297
4298 /// Returns true if the VPlan is based on a loop with an early exit. That is
4299 /// the case if the VPlan has either more than one exit block or a single exit
4300 /// block with multiple predecessors (one for the exit via the latch and one
4301 /// via the other early exit).
4302 bool hasEarlyExit() const {
4303 return count_if(ExitBlocks,
4304 [](VPIRBasicBlock *EB) {
4305 return EB->getNumPredecessors() != 0;
4306 }) > 1 ||
4307 (ExitBlocks.size() == 1 && ExitBlocks[0]->getNumPredecessors() > 1);
4308 }
4309
4310 /// Returns true if the scalar tail may execute after the vector loop. Note
4311 /// that this relies on unneeded branches to the scalar tail loop being
4312 /// removed.
4313 bool hasScalarTail() const {
4314 return !(getScalarPreheader()->getNumPredecessors() == 0 ||
4316 }
4317};
4318
4319#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4321 Plan.print(OS);
4322 return OS;
4323}
4324#endif
4325
4326} // end namespace llvm
4327
4328#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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:638
#define LLVM_ABI_FOR_TEST
Definition: Compiler.h:218
dxil translate DXIL Translate Metadata
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:1328
Hexagon Common GEP
iv users
Definition: IVUsers.cpp:48
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
#define T
MachineInstr unsigned OpIdx
#define P(N)
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
static bool mayHaveSideEffects(MachineInstr &MI)
raw_pwrite_stream & OS
This file implements the SmallBitVector class.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static const BasicSubtargetSubTypeKV * find(StringRef S, ArrayRef< BasicSubtargetSubTypeKV > A)
Find KV in array using binary search.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:247
This file contains the declarations of the entities induced by Vectorization Plans,...
#define VP_CLASSOF_IMPL(VPDefID)
Definition: VPlan.h:496
static const uint32_t IV[8]
Definition: blake3_impl.h:83
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:191
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:131
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:448
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition: InstrTypes.h:612
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:678
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Definition: CmpPredicate.h:23
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:868
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:875
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:124
static DebugLoc getUnknown()
Definition: DebugLoc.h:162
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:203
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:168
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:312
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition: Operator.h:200
Convenience struct for specifying and reasoning about fast-math flags.
Definition: FMF.h:22
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:949
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
The group of interleaved loads/stores sharing the same stride and close to each other.
Definition: VectorUtils.h:524
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
An instruction for reading from memory.
Definition: Instructions.h:180
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:40
Metadata node.
Definition: Metadata.h:1077
bool onlyWritesMemory() const
Whether this function only (at most) writes memory.
Definition: ModRef.h:221
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition: ModRef.h:218
Root of the metadata hierarchy.
Definition: Metadata.h:63
This class represents an analyzed expression in the program.
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:104
void clear()
Completely clear the SetVector.
Definition: SetVector.h:284
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:279
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:99
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Definition: SetVector.h:269
This class provides computation of slot numbers for LLVM Assembly writing.
Definition: AsmWriter.cpp:757
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
iterator erase(const_iterator CI)
Definition: SmallVector.h:738
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
An instruction for storing to memory.
Definition: Instructions.h:296
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
LLVM_ABI 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:3352
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:3360
VPActiveLaneMaskPHIRecipe(VPValue *StartMask, DebugLoc DL)
Definition: VPlan.h:3354
~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:3639
RecipeListTy::const_iterator const_iterator
Definition: VPlan.h:3667
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition: VPlan.h:3714
RecipeListTy::const_reverse_iterator const_reverse_iterator
Definition: VPlan.h:3669
RecipeListTy::iterator iterator
Instruction iterators...
Definition: VPlan.h:3666
RecipeListTy & getRecipeList()
Returns a reference to the list of recipes.
Definition: VPlan.h:3692
VPBasicBlock(const unsigned char BlockSC, const Twine &Name="")
Definition: VPlan.h:3656
iterator end()
Definition: VPlan.h:3676
iterator begin()
Recipe iterator methods.
Definition: VPlan.h:3674
RecipeListTy::reverse_iterator reverse_iterator
Definition: VPlan.h:3668
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition: VPlan.h:3727
const VPBasicBlock * getCFGPredecessor(unsigned Idx) const
Returns the predecessor block at index Idx with the predecessors as per the corresponding plain CFG.
Definition: VPlan.cpp:810
~VPBasicBlock() override
Definition: VPlan.h:3660
const_reverse_iterator rbegin() const
Definition: VPlan.h:3680
reverse_iterator rend()
Definition: VPlan.h:3681
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition: VPlan.h:3654
VPRecipeBase & back()
Definition: VPlan.h:3689
const VPRecipeBase & front() const
Definition: VPlan.h:3686
const_iterator begin() const
Definition: VPlan.h:3675
VPRecipeBase & front()
Definition: VPlan.h:3687
const VPRecipeBase & back() const
Definition: VPlan.h:3688
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition: VPlan.h:3705
bool empty() const
Definition: VPlan.h:3685
const_iterator end() const
Definition: VPlan.h:3677
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:3700
static RecipeListTy VPBasicBlock::* getSublistAccess(VPRecipeBase *)
Returns a pointer to a member of the recipe list.
Definition: VPlan.h:3695
reverse_iterator rbegin()
Definition: VPlan.h:3679
size_t size() const
Definition: VPlan.h:3684
const_reverse_iterator rend() const
Definition: VPlan.h:3682
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition: VPlan.h:2374
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2428
VPValue * getIncomingValue(unsigned Idx) const
Return incoming value number Idx.
Definition: VPlan.h:2403
VPValue * getMask(unsigned Idx) const
Return mask number Idx.
Definition: VPlan.h:2408
unsigned getNumIncomingValues() const
Return the number of incoming values, taking into account when normalized the first incoming value wi...
Definition: VPlan.h:2398
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition: VPlan.h:2413
VPBlendRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2385
VPBlendRecipe(PHINode *Phi, ArrayRef< VPValue * > Operands, DebugLoc DL)
The blend operation is a User of the incoming values and of their respective masks,...
Definition: VPlan.h:2380
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:81
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition: VPlan.h:297
VPRegionBlock * getParent()
Definition: VPlan.h:173
VPBlocksTy & getPredecessors()
Definition: VPlan.h:205
iterator_range< VPBlockBase ** > predecessors()
Definition: VPlan.h:202
LLVM_DUMP_METHOD void dump() const
Dump this VPBlockBase to dbgs().
Definition: VPlan.h:374
void setName(const Twine &newName)
Definition: VPlan.h:166
size_t getNumSuccessors() const
Definition: VPlan.h:219
iterator_range< VPBlockBase ** > successors()
Definition: VPlan.h:201
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:319
bool isLegalToHoistInto()
Return true if it is legal to hoist instructions into this block.
Definition: VPlan.h:346
virtual ~VPBlockBase()=default
const VPBlocksTy & getHierarchicalPredecessors()
Definition: VPlan.h:255
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
Definition: VPlan.h:332
size_t getNumPredecessors() const
Definition: VPlan.h:220
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition: VPlan.h:288
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
Definition: VPlan.h:325
const VPBlocksTy & getPredecessors() const
Definition: VPlan.h:204
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:158
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
Definition: VPlan.cpp:174
const VPRegionBlock * getParent() const
Definition: VPlan.h:174
const std::string & getName() const
Definition: VPlan.h:164
void clearSuccessors()
Remove all the successors of this block.
Definition: VPlan.h:307
VPBlockBase * getSingleHierarchicalSuccessor()
Definition: VPlan.h:245
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition: VPlan.h:279
VPBlockBase * getSinglePredecessor() const
Definition: VPlan.h:215
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:239
void clearPredecessors()
Remove all the predecessor of this block.
Definition: VPlan.h:304
unsigned getVPBlockID() const
Definition: VPlan.h:171
void printAsOperand(raw_ostream &OS, bool PrintType=false) const
Definition: VPlan.h:353
void swapPredecessors()
Swap predecessors of the block.
Definition: VPlan.h:311
VPBlockBase(const unsigned char SC, const std::string &N)
Definition: VPlan.h:150
VPBlocksTy & getSuccessors()
Definition: VPlan.h:199
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:268
void setParent(VPRegionBlock *P)
Definition: VPlan.h:184
VPBlockBase * getSingleHierarchicalPredecessor()
Definition: VPlan.h:261
VPBlockBase * getSingleSuccessor() const
Definition: VPlan.h:209
const VPBlocksTy & getSuccessors() const
Definition: VPlan.h:198
Class that provides utilities for VPBlockBases in VPlan.
Definition: VPlanUtils.h:110
A recipe for generating conditional branches on the bits of a mask.
Definition: VPlan.h:2809
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Definition: VPlan.h:2830
VPBranchOnMaskRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2814
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2838
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL)
Definition: VPlan.h:2811
VPlan-based builder utility analogous to IRBuilder.
Canonical scalar induction phi of the vector loop.
Definition: VPlan.h:3295
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition: VPlan.h:3334
~VPCanonicalIVPHIRecipe() override=default
VPCanonicalIVPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3302
VPCanonicalIVPHIRecipe(VPValue *StartV, DebugLoc DL)
Definition: VPlan.h:3297
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3327
Type * getScalarType() const
Returns the scalar type of the induction.
Definition: VPlan.h:3322
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition: VPlan.h:3310
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:3341
This class augments a recipe with a set of VPValues defined by the recipe.
Definition: VPlanValue.h:300
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition: VPlan.h:3460
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:3499
VPValue * getStepValue() const
Definition: VPlan.h:3516
Type * getScalarType() const
Definition: VPlan.h:3511
VPDerivedIVRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3487
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV, VPValue *Step, const Twine &Name="")
Definition: VPlan.h:3479
~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:3519
VPValue * getStartValue() const
Definition: VPlan.h:3515
VPDerivedIVRecipe(const InductionDescriptor &IndDesc, VPValue *Start, VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step, const Twine &Name="")
Definition: VPlan.h:3471
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
Definition: VPlan.h:3383
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:3390
~VPEVLBasedIVPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition: VPlan.h:3396
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPEVLBasedIVPHIRecipe.
Definition: VPlan.h:3402
VPEVLBasedIVPHIRecipe(VPValue *StartIV, DebugLoc DL)
Definition: VPlan.h:3385
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3409
Recipe to expand a SCEV expression.
Definition: VPlan.h:3258
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition: VPlan.h:3271
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPExpandSCEVRecipe.
Definition: VPlan.h:3276
VPExpandSCEVRecipe(const SCEV *Expr)
Definition: VPlan.h:3262
const SCEV * getSCEV() const
Definition: VPlan.h:3288
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:3267
~VPExpandSCEVRecipe() override=default
A recipe to combine multiple recipes into a single 'expression' recipe, which should be considered a ...
Definition: VPlan.h:2854
void execute(VPTransformState &State) override
Method for generating code, must not be called as this recipe is abstract.
Definition: VPlan.h:2939
VPValue * getOperandOfResultType() const
Return the VPValue to use to infer the result type of the recipe.
Definition: VPlan.h:2926
VPExpressionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2908
void decompose()
Insert the recipes of the expression back into the VPlan, directly before the current recipe.
~VPExpressionRecipe() override
Definition: VPlan.h:2899
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPExpressionRecipe(VPWidenCastRecipe *Ext, VPReductionRecipe *Red)
Definition: VPlan.h:2890
bool mayHaveSideEffects() const
Returns true if this expression contains recipes that may have side effects.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Compute the cost of this recipe either using a recipe's specialized implementation or using the legac...
bool mayReadOrWriteMemory() const
Returns true if this expression contains recipes that may read from or write to memory.
VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1, VPWidenRecipe *Mul, VPReductionRecipe *Red)
Definition: VPlan.h:2894
VPExpressionRecipe(VPWidenRecipe *Mul, VPReductionRecipe *Red)
Definition: VPlan.h:2892
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition: VPlan.h:1951
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition: VPlan.h:1958
static bool classof(const VPValue *V)
Definition: VPlan.h:1968
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:1999
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition: VPlan.h:1988
void setStartValue(VPValue *V)
Update the start value of the recipe.
Definition: VPlan.h:1996
VPValue * getStartValue() const
Definition: VPlan.h:1991
static bool classof(const VPRecipeBase *B)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:1964
void execute(VPTransformState &State) override=0
Generate the phi nodes.
virtual VPRecipeBase & getBackedgeRecipe()
Returns the backedge value as a recipe.
Definition: VPlan.h:2005
VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr, VPValue *Start, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1953
~VPHeaderPHIRecipe() override=default
A recipe representing a sequence of load -> update -> store as part of a histogram operation.
Definition: VPlan.h:1666
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:1677
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHistogramRecipe.
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:1694
unsigned getOpcode() const
Definition: VPlan.h:1690
VPHistogramRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1671
~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:3792
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition: VPlan.cpp:493
BasicBlock * getIRBasicBlock() const
Definition: VPlan.h:3816
~VPIRBasicBlock() override
Definition: VPlan.h:3804
static bool classof(const VPBlockBase *V)
Definition: VPlan.h:3806
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition: VPlan.cpp:515
Class to record and manage LLVM IR flags.
Definition: VPlan.h:596
FastMathFlagsTy FMFs
Definition: VPlan.h:660
bool flagsValidForOpcode(unsigned Opcode) const
Returns true if the set flags are valid for Opcode.
VPIRFlags(DisjointFlagsTy DisjointFlags)
Definition: VPlan.h:706
VPIRFlags(WrapFlagsTy WrapFlags)
Definition: VPlan.h:701
WrapFlagsTy WrapFlags
Definition: VPlan.h:654
CmpInst::Predicate CmpPredicate
Definition: VPlan.h:653
void printFlags(raw_ostream &O) const
GEPNoWrapFlags GEPFlags
Definition: VPlan.h:658
bool hasFastMathFlags() const
Returns true if the recipe has fast-math flags.
Definition: VPlan.h:812
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlags() const
TruncFlagsTy TruncFlags
Definition: VPlan.h:655
CmpInst::Predicate getPredicate() const
Definition: VPlan.h:794
bool hasNonNegFlag() const
Returns true if the recipe has non-negative flag.
Definition: VPlan.h:817
void transferFlags(VPIRFlags &Other)
Definition: VPlan.h:716
ExactFlagsTy ExactFlags
Definition: VPlan.h:657
bool hasNoSignedWrap() const
Definition: VPlan.h:836
bool isDisjoint() const
Definition: VPlan.h:847
VPIRFlags(FastMathFlags FMFs)
Definition: VPlan.h:704
VPIRFlags(NonNegFlagsTy NonNegFlags)
Definition: VPlan.h:709
VPIRFlags(CmpInst::Predicate Pred)
Definition: VPlan.h:698
bool isNonNeg() const
Definition: VPlan.h:819
GEPNoWrapFlags getGEPNoWrapFlags() const
Definition: VPlan.h:806
bool hasPredicate() const
Returns true if the recipe has a comparison predicate.
Definition: VPlan.h:809
DisjointFlagsTy DisjointFlags
Definition: VPlan.h:656
unsigned AllFlags
Definition: VPlan.h:661
void setPredicate(CmpInst::Predicate Pred)
Definition: VPlan.h:800
bool hasNoUnsignedWrap() const
Definition: VPlan.h:825
NonNegFlagsTy NonNegFlags
Definition: VPlan.h:659
void dropPoisonGeneratingFlags()
Drop all poison-generating flags.
Definition: VPlan.h:722
void applyFlags(Instruction &I) const
Apply the IR flags to I.
Definition: VPlan.h:757
VPIRFlags(GEPNoWrapFlags GEPFlags)
Definition: VPlan.h:712
VPIRFlags(Instruction &I)
Definition: VPlan.h:667
A recipe to wrap on original IR instruction not to be modified during execution, except for PHIs.
Definition: VPlan.h:1329
Instruction & getInstruction() const
Definition: VPlan.h:1360
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first part of operand Op.
Definition: VPlan.h:1374
~VPIRInstruction() override=default
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
void extractLastLaneOfFirstOperand(VPBuilder &Builder)
Update the recipes first operand to the last lane of the operand using Builder.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1380
VPIRInstruction * clone() override
Clone the current recipe.
Definition: VPlan.h:1347
static LLVM_ABI_FOR_TEST VPIRInstruction * create(Instruction &I)
Create a new VPIRPhi for \I , if it is a PHINode, otherwise create a VPIRInstruction.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPIRInstruction.
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:1368
VPIRInstruction(Instruction &I)
VPIRInstruction::create() should be used to create VPIRInstructions, as subclasses may need to be cre...
Definition: VPlan.h:1335
Helper to manage IR metadata for recipes.
Definition: VPlan.h:926
VPIRMetadata(Instruction &I)
Adds metatadata that can be preserved from the original instruction I.
Definition: VPlan.h:934
void intersect(const VPIRMetadata &MD)
Intersect this VPIRMetada object with MD, keeping only metadata nodes that are common to both.
VPIRMetadata & operator=(const VPIRMetadata &Other)
Definition: VPlan.h:943
VPIRMetadata(const VPIRMetadata &Other)
Copy constructor for cloning.
Definition: VPlan.h:941
void addMetadata(unsigned Kind, MDNode *Node)
Add metadata with kind Kind and Node.
Definition: VPlan.h:952
void applyMetadata(Instruction &I) const
Add all metadata to I.
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition: VPlan.h:1172
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInstruction.
Definition: VPlan.h:1216
static bool classof(const VPUser *R)
Definition: VPlan.h:1200
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:1182
Type * getResultType() const
Definition: VPlan.h:1222
VPInstructionWithType(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags, DebugLoc DL, const Twine &Name="")
Definition: VPlan.h:1177
VPInstruction * clone() override
Clone the current recipe.
Definition: VPlan.h:1204
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the instruction.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition: VPlan.h:967
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition: VPlan.h:1040
@ ComputeAnyOfResult
Compute the final result of a AnyOf reduction with select(cmp(),x,y), where one of (x,...
Definition: VPlan.h:996
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
Definition: VPlan.h:1030
@ ExtractPenultimateElement
Definition: VPlan.h:1006
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
Definition: VPlan.h:1043
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition: VPlan.h:1034
@ BuildVector
Creates a fixed-width vector containing all operands.
Definition: VPlan.h:993
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
Definition: VPlan.h:990
@ VScale
Returns the value for vscale.
Definition: VPlan.h:1045
@ CanonicalIVIncrementForPart
Definition: VPlan.h:983
@ ComputeReductionResult
Definition: VPlan.h:998
@ CalculateTripCountMinusVF
Definition: VPlan.h:981
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Definition: VPlan.h:1085
bool hasResult() const
Definition: VPlan.h:1124
StringRef getName() const
Returns the symbolic name assigned to the VPInstruction.
Definition: VPlan.h:1164
unsigned getOpcode() const
Definition: VPlan.h:1104
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
Definition: VPlan.h:2443
bool onlyFirstLaneUsed(const VPValue *Op) const override
The recipe only uses the first lane of the address.
Definition: VPlan.h:2529
~VPInterleaveRecipe() override=default
VPValue * getMask() const
Return the mask used by this recipe.
Definition: VPlan.h:2493
VPInterleaveRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2479
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
Definition: VPlan.h:2500
Instruction * getInsertPos() const
Definition: VPlan.h:2535
const InterleaveGroup< Instruction > * getInterleaveGroup()
Definition: VPlan.h:2520
unsigned getNumStoreOperands() const
Returns the number of stored operands of this interleave group.
Definition: VPlan.h:2524
VPInterleaveRecipe(const InterleaveGroup< Instruction > *IG, VPValue *Addr, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
Definition: VPlan.h:2455
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
Definition: VPlanHelpers.h:125
A recipe for forming partial reductions.
Definition: VPlan.h:2628
VPPartialReductionRecipe(Instruction *ReductionInst, VPValue *Op0, VPValue *Op1, VPValue *Cond, unsigned VFScaleFactor)
Definition: VPlan.h:2636
VPPartialReductionRecipe(unsigned Opcode, VPValue *Op0, VPValue *Op1, VPValue *Cond, unsigned ScaleFactor, Instruction *ReductionInst=nullptr)
Definition: VPlan.h:2640
~VPPartialReductionRecipe() override=default
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by.
Definition: VPlan.h:2674
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:2671
VPPartialReductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2655
Helper type to provide functions to access incoming values and blocks for phi-like recipes.
Definition: VPlan.h:1233
virtual const VPRecipeBase * getAsRecipe() const =0
Return a VPRecipeBase* to the current object.
VPUser::const_operand_range incoming_values() const
Returns an interator range over the incoming values.
Definition: VPlan.h:1255
virtual unsigned getNumIncoming() const
Returns the number of incoming values, also number of incoming blocks.
Definition: VPlan.h:1250
void removeIncomingValueFor(VPBlockBase *IncomingBlock) const
Removes the incoming value for IncomingBlock, which must be a predecessor.
const VPBasicBlock * getIncomingBlock(unsigned Idx) const
Returns the incoming block with index Idx.
Definition: VPlan.h:3783
detail::zippy< llvm::detail::zip_first, VPUser::const_operand_range, const_incoming_blocks_range > incoming_values_and_blocks() const
Returns an iterator range over pairs of incoming values and corresponding incoming blocks.
Definition: VPlan.h:1275
VPValue * getIncomingValue(unsigned Idx) const
Returns the incoming VPValue with index Idx.
Definition: VPlan.h:1242
virtual ~VPPhiAccessors()=default
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the recipe.
iterator_range< mapped_iterator< detail::index_iterator, std::function< const VPBasicBlock *(size_t)> > > const_incoming_blocks_range
Definition: VPlan.h:1261
const_incoming_blocks_range incoming_blocks() const
Returns an iterator range over the incoming blocks.
Definition: VPlan.h:1264
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition: VPlan.h:2966
~VPPredInstPHIRecipe() override=default
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2998
VPPredInstPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2974
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPredInstPHIRecipe.
Definition: VPlan.h:2985
VPPredInstPHIRecipe(VPValue *PredV, DebugLoc DL)
Construct a VPPredInstPHIRecipe given PredInst whose value needs a phi nodes after merging back from ...
Definition: VPlan.h:2970
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition: VPlan.h:391
bool mayReadOrWriteMemory() const
Returns true if the recipe may read from or write to memory.
Definition: VPlan.h:474
void setDebugLoc(DebugLoc NewDL)
Set the recipe's debug location to NewDL.
Definition: VPlan.h:485
virtual ~VPRecipeBase()=default
VPBasicBlock * getParent()
Definition: VPlan.h:412
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition: VPlan.h:479
virtual void execute(VPTransformState &State)=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
static bool classof(const VPDef *D)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:454
virtual VPRecipeBase * clone()=0
Clone the current recipe.
const VPBasicBlock * getParent() const
Definition: VPlan.h:413
static bool classof(const VPUser *U)
Definition: VPlan.h:459
VPRecipeBase(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:402
A recipe to represent inloop reduction operations with vector-predication intrinsics,...
Definition: VPlan.h:2687
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2719
VPValue * getEVL() const
The VPValue of the explicit vector length.
Definition: VPlan.h:2716
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:2689
VPReductionEVLRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2700
~VPReductionEVLRecipe() override=default
A recipe for handling reduction phis.
Definition: VPlan.h:2302
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
Definition: VPlan.h:2359
VPReductionPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2328
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by.
Definition: VPlan.h:2342
~VPReductionPHIRecipe() 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:2365
VPReductionPHIRecipe(PHINode *Phi, RecurKind Kind, VPValue &Start, bool IsInLoop=false, bool IsOrdered=false, unsigned VFScaleFactor=1)
Create a new VPReductionPHIRecipe for the reduction Phi.
Definition: VPlan.h:2318
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Definition: VPlan.h:2353
bool isInLoop() const
Returns true, if the phi is part of an in-loop reduction.
Definition: VPlan.h:2362
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.
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
Definition: VPlan.h:2356
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
Definition: VPlan.h:2541
bool isConditional() const
Return true if the in-loop reduction is conditional.
Definition: VPlan.h:2613
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:2585
VPReductionRecipe(const RecurKind RdxKind, FastMathFlags FMFs, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, bool IsOrdered, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:2570
VPValue * getVecOp() const
The VPValue of the vector value to be reduced.
Definition: VPlan.h:2617
VPValue * getCondOp() const
The VPValue of the condition for the block.
Definition: VPlan.h:2619
RecurKind getRecurrenceKind() const
Return the recurrence kind for the in-loop reduction.
Definition: VPlan.h:2609
bool isOrdered() const
Return true if the in-loop reduction is ordered.
Definition: VPlan.h:2611
~VPReductionRecipe() override=default
VPValue * getChainOp() const
The VPValue of the scalar Chain being accumulated.
Definition: VPlan.h:2615
VPReductionRecipe(RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, bool IsOrdered, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:2563
VPReductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2579
VPReductionRecipe(const unsigned char SC, RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, bool IsOrdered, DebugLoc DL)
Definition: VPlan.h:2549
static bool classof(const VPUser *U)
Definition: VPlan.h:2590
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition: VPlan.h:3827
const VPBlockBase * getEntry() const
Definition: VPlan.h:3863
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition: VPlan.h:3895
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
Definition: VPlan.h:3880
VPBlockBase * getExiting()
Definition: VPlan.h:3876
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
Definition: VPlan.h:3868
const VPBlockBase * getExiting() const
Definition: VPlan.h:3875
VPBlockBase * getEntry()
Definition: VPlan.h:3864
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
Definition: VPlan.h:3888
~VPRegionBlock() override
Definition: VPlan.h:3856
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition: VPlan.h:3859
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition: VPlan.h:2731
VPReplicateRecipe(Instruction *I, ArrayRef< VPValue * > Operands, bool IsSingleScalar, VPValue *Mask=nullptr, VPIRMetadata Metadata={})
Definition: VPlan.h:2739
bool isSingleScalar() const
Definition: VPlan.h:2776
~VPReplicateRecipe() 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:2781
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition: VPlan.h:2788
bool isPredicated() const
Definition: VPlan.h:2778
VPReplicateRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2751
unsigned getOpcode() const
Definition: VPlan.h:2805
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
Definition: VPlan.h:2800
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition: VPlan.h:3529
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3584
VPValue * getStepValue() const
Definition: VPlan.h:3581
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPScalarIVStepsRecipe.
Definition: VPlan.h:3569
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:3540
bool isPart0() const
Return true if this VPScalarIVStepsRecipe corresponds to part 0.
Definition: VPlan.h:3561
VPScalarIVStepsRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3552
VPScalarIVStepsRecipe(VPValue *IV, VPValue *Step, VPValue *VF, Instruction::BinaryOps Opcode, FastMathFlags FMFs, DebugLoc DL)
Definition: VPlan.h:3533
~VPScalarIVStepsRecipe() override=default
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Definition: VPlan.h:518
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, Value *UV, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:524
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
Definition: VPlan.h:582
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:528
const Instruction * getUnderlyingInstr() const
Definition: VPlan.h:585
static bool classof(const VPUser *U)
Definition: VPlan.h:574
LLVM_DUMP_METHOD void dump() const
Print this VPSingleDefRecipe to dbgs() (for debugging).
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:520
virtual VPSingleDefRecipe * clone() override=0
Clone the current recipe.
This class can be used to assign names to VPValues.
Definition: VPlanHelpers.h:382
Helper to access the operand that contains the unroll part for this recipe after unrolling.
Definition: VPlan.h:914
unsigned getUnrollPart(const 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:197
operand_range operands()
Definition: VPlanValue.h:265
void setOperand(unsigned I, VPValue *New)
Definition: VPlanValue.h:241
unsigned getNumOperands() const
Definition: VPlanValue.h:235
VPValue * getOperand(unsigned N) const
Definition: VPlanValue.h:236
iterator_range< const_operand_iterator > const_operand_range
Definition: VPlanValue.h:259
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
Definition: VPlan.cpp:1400
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition: VPlan.cpp:125
Value * getLiveInIRValue() const
Returns the underlying IR value, if this VPValue is defined outside the scope of VPlan.
Definition: VPlanValue.h:174
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition: VPlanValue.h:85
unsigned getNumUsers() const
Definition: VPlanValue.h:113
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
Definition: VPlanValue.h:169
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition: VPlan.h:1817
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:1854
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1840
VPVectorEndPointerRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1861
const VPValue * getVFValue() const
Definition: VPlan.h:1836
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 VPVectorPointerRecipe.
Definition: VPlan.h:1847
VPVectorEndPointerRecipe(VPValue *Ptr, VPValue *VF, Type *IndexedTy, int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition: VPlan.h:1825
A recipe to compute the pointers for widened memory accesses of IndexTy.
Definition: VPlan.h:1876
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool isFirstPart() const
Return true if this VPVectorPointerRecipe corresponds to part 0.
Definition: VPlan.h:1911
VPVectorPointerRecipe(VPValue *Ptr, Type *IndexedTy, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition: VPlan.h:1880
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:1897
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition: VPlan.h:1890
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHeaderPHIRecipe.
Definition: VPlan.h:1914
VPVectorPointerRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1904
A recipe for widening Call instructions using library calls.
Definition: VPlan.h:1613
const_operand_range args() const
Definition: VPlan.h:1652
VPWidenCallRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1633
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1620
operand_range args()
Definition: VPlan.h:1651
Function * getCalledScalarFunction() const
Definition: VPlan.h:1647
~VPWidenCallRecipe() override=default
A Recipe for widening the canonical induction variable of the vector loop.
Definition: VPlan.h:3424
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:3444
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3431
VPWidenCanonicalIVRecipe(VPCanonicalIVPHIRecipe *CanonicalIV)
Definition: VPlan.h:3426
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition: VPlan.h:1467
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, CastInst &UI)
Definition: VPlan.h:1475
Instruction::CastOps getOpcode() const
Definition: VPlan.h:1517
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1483
Type * getResultType() const
Returns the result type of the cast.
Definition: VPlan.h:1520
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:1494
A recipe for handling GEP instructions.
Definition: VPlan.h:1753
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:1803
VPWidenGEPRecipe(GetElementPtrInst *GEP, ArrayRef< VPValue * > Operands)
Definition: VPlan.h:1769
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenGEPRecipe.
Definition: VPlan.h:1790
VPWidenGEPRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1779
~VPWidenGEPRecipe() override=default
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
Definition: VPlan.h:2013
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2075
static bool classof(const VPValue *V)
Definition: VPlan.h:2029
void setStepValue(VPValue *V)
Update the step value of the recipe.
Definition: VPlan.h:2045
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
Definition: VPlan.h:2060
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Definition: VPlan.h:2053
PHINode * getPHINode() const
Definition: VPlan.h:2055
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, DebugLoc DL)
Definition: VPlan.h:2017
VPValue * getStepValue()
Returns the step value of the induction.
Definition: VPlan.h:2041
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition: VPlan.h:2058
VPRecipeBase & getBackedgeRecipe() override
Returns the backedge value as a recipe.
Definition: VPlan.h:2067
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:2024
static bool classof(const VPHeaderPHIRecipe *R)
Definition: VPlan.h:2034
const VPValue * getVFValue() const
Definition: VPlan.h:2048
const VPValue * getStepValue() const
Definition: VPlan.h:2042
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:2088
const TruncInst * getTruncInst() const
Definition: VPlan.h:2153
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition: VPlan.h:2128
~VPWidenIntOrFpInductionRecipe() override=default
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, TruncInst *Trunc, DebugLoc DL)
Definition: VPlan.h:2104
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2120
TruncInst * getTruncInst()
Returns the first defined value as TruncInst, if it is one or nullptr otherwise.
Definition: VPlan.h:2152
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, DebugLoc DL)
Definition: VPlan.h:2095
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
Definition: VPlan.h:2169
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Definition: VPlan.h:2148
Type * getScalarType() const
Returns the scalar type of the induction.
Definition: VPlan.h:2161
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:1524
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1550
Intrinsic::ID getVectorIntrinsicID() const
Return the ID of the intrinsic.
Definition: VPlan.h:1585
bool mayReadFromMemory() const
Returns true if the intrinsic may read from memory.
Definition: VPlan.h:1594
StringRef getIntrinsicName() const
Return to name of the intrinsic as string.
VPWidenIntrinsicRecipe(CallInst &CI, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:1541
bool mayHaveSideEffects() const
Returns true if the intrinsic may have side-effects.
Definition: VPlan.h:1600
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1567
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
Definition: VPlan.h:1597
~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:1588
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.
A common base class for widening memory operations.
Definition: VPlan.h:3008
bool Reverse
Whether the consecutive accessed addresses are in reverse order.
Definition: VPlan.h:3016
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
Definition: VPlan.h:3056
static bool classof(const VPUser *U)
Definition: VPlan.h:3050
void execute(VPTransformState &State) override
Generate the wide load/store.
Definition: VPlan.h:3076
Instruction & Ingredient
Definition: VPlan.h:3010
VPWidenMemoryRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3039
Instruction & getIngredient() const
Definition: VPlan.h:3084
bool Consecutive
Whether the accessed addresses are consecutive.
Definition: VPlan.h:3013
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:3043
VPValue * getMask() const
Return the mask used by this recipe.
Definition: VPlan.h:3070
bool isMasked() const
Returns true if the recipe is masked.
Definition: VPlan.h:3066
VPWidenMemoryRecipe(const char unsigned SC, Instruction &I, std::initializer_list< VPValue * > Operands, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
Definition: VPlan.h:3029
void setMask(VPValue *Mask)
Definition: VPlan.h:3021
VPValue * getAddr() const
Return the address accessed by this recipe.
Definition: VPlan.h:3063
bool isReverse() const
Return whether the consecutive loaded/stored addresses are in reverse order.
Definition: VPlan.h:3060
A recipe for widened phis.
Definition: VPlan.h:2224
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition: VPlan.h:2229
VPWidenPHIRecipe(PHINode *Phi, VPValue *Start=nullptr, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new VPWidenPHIRecipe for Phi with start value Start and debug location DL.
Definition: VPlan.h:2234
VPWidenPHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2242
~VPWidenPHIRecipe() override=default
VPWidenPointerInductionRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2193
~VPWidenPointerInductionRecipe() override=default
bool onlyScalarsGenerated(bool IsScalable)
Returns true if only scalar values will be generated.
void execute(VPTransformState &State) override
Generate vector values for the pointer induction.
Definition: VPlan.h:2203
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step, VPValue *NumUnrolledElems, const InductionDescriptor &IndDesc, bool IsScalarAfterVectorization, DebugLoc DL)
Create a new VPWidenPointerInductionRecipe for Phi with start value Start and the number of elements ...
Definition: VPlan.h:2181
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:1424
VPWidenRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1440
VPWidenRecipe(Instruction &I, ArrayRef< VPValue * > Operands)
Definition: VPlan.h:1434
VPWidenRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL)
Definition: VPlan.h:1428
~VPWidenRecipe() override=default
unsigned getOpcode() const
Definition: VPlan.h:1457
VPlanPrinter prints a given VPlan to a given output stream.
Definition: VPlanHelpers.h:416
Class that maps (parts of) an existing VPlan to trees of combined VPInstructions.
Definition: VPlanSLP.h:74
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition: VPlan.h:3930
void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition: VPlan.cpp:1132
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition: VPlan.cpp:1108
bool hasVF(ElementCount VF) const
Definition: VPlan.h:4139
LLVMContext & getContext() const
Definition: VPlan.h:4127
VPBasicBlock * getEntry()
Definition: VPlan.h:4029
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:4270
VPValue & getVectorTripCount()
The vector trip count.
Definition: VPlan.h:4119
void setName(const Twine &newName)
Definition: VPlan.h:4177
bool hasScalableVF() const
Definition: VPlan.h:4140
VPValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition: VPlan.h:4125
VPValue & getVF()
Returns the VF of the vector loop region.
Definition: VPlan.h:4122
VPValue * getTripCount() const
The trip count of the original loop.
Definition: VPlan.h:4091
VPValue * getTrue()
Return a VPValue wrapping i1 true.
Definition: VPlan.h:4196
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
Definition: VPlan.h:4112
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition: VPlan.h:4146
VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and a tr...
Definition: VPlan.h:4010
VPIRBasicBlock * getExitBlock(BasicBlock *IRBB) const
Return the VPIRBasicBlock corresponding to IRBB.
Definition: VPlan.cpp:940
LLVM_ABI_FOR_TEST ~VPlan()
Definition: VPlan.cpp:917
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition: VPlan.cpp:948
const VPBasicBlock * getEntry() const
Definition: VPlan.h:4030
unsigned getUF() const
Definition: VPlan.h:4159
VPRegionBlock * createVPRegionBlock(const std::string &Name="")
Create a new loop VPRegionBlock with Name and entry and exiting blocks set to nullptr.
Definition: VPlan.h:4281
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition: VPlan.cpp:1246
void addSCEVExpansion(const SCEV *S, VPValue *V)
Definition: VPlan.h:4248
bool hasUF(unsigned UF) const
Definition: VPlan.h:4157
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition: VPlan.h:4081
void setVF(ElementCount VF)
Definition: VPlan.h:4133
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition: VPlan.h:4172
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition: VPlan.cpp:1037
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
Definition: VPlan.h:4302
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition: VPlan.cpp:1019
const VPBasicBlock * getMiddleBlock() const
Definition: VPlan.h:4067
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
Definition: VPlan.h:4098
void resetTripCount(VPValue *NewTripCount)
Resets the trip count for the VPlan.
Definition: VPlan.h:4105
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
Definition: VPlan.h:4054
void setEntry(VPBasicBlock *VPBB)
Definition: VPlan.h:4018
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition: VPlan.h:4260
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition: VPlan.cpp:1252
VPValue * getFalse()
Return a VPValue wrapping i1 false.
Definition: VPlan.h:4202
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:4181
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition: VPlan.cpp:1138
bool hasScalarVFOnly() const
Definition: VPlan.h:4150
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition: VPlan.h:4072
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition: VPlan.cpp:955
ArrayRef< VPValue * > getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
Definition: VPlan.h:4211
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the vector loop.
Definition: VPlan.h:4235
void print(raw_ostream &O) const
Print this VPlan to O.
Definition: VPlan.cpp:1091
void addVF(ElementCount VF)
Definition: VPlan.h:4131
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition: VPlan.h:4077
VPValue * getLiveIn(Value *V) const
Return the live-in VPValue for V, if there is one or nullptr otherwise.
Definition: VPlan.h:4208
VPValue * getSCEVExpansion(const SCEV *S) const
Definition: VPlan.h:4244
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition: VPlan.cpp:1053
VPBasicBlock * getVectorPreheader()
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition: VPlan.h:4034
void setUF(unsigned UF)
Definition: VPlan.h:4164
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop.
Definition: VPlan.h:4313
VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
Definition: VPlan.cpp:1179
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:172
An ilist node that can access its parent list.
Definition: ilist_node.h:327
Increasing range of size_t indices.
Definition: STLExtras.h:2444
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:53
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:81
LLVM_ABI AttributeSet getFnAttributes(LLVMContext &C, ID id)
Return the function attributes for an intrinsic.
Definition: Intrinsics.cpp:743
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition: STLExtras.h:860
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:1744
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition: STLExtras.h:870
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2491
SDValue getStoredValue(SDValue Op)
LLVM_ABI void getMetadataToPropagate(Instruction *Inst, SmallVectorImpl< std::pair< unsigned, MDNode * > > &Metadata)
Add metadata from Inst to Metadata, if it can be preserved after vectorization.
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 map_range(ContainerTy &&C, FuncTy F)
Definition: STLExtras.h:386
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:1751
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
std::unique_ptr< VPlan > VPlanPtr
Definition: VPlan.h:77
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition: STLExtras.h:345
@ Other
Any other memory.
RecurKind
These are the kinds of recurrences that we support.
Definition: IVDescriptors.h:34
@ Mul
Product of integers.
@ Add
Sum of integers.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:1973
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:312
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition: STLExtras.h:1980
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:565
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1916
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
#define N
Support casting from VPRecipeBase -> VPPhiAccessors, by down-casting to the recipe types implementing...
Definition: VPlan.h:3602
static VPPhiAccessors * doCastIfPossible(SrcTy f)
doCastIfPossible is used by dyn_cast<>.
Definition: VPlan.h:3623
static VPPhiAccessors * doCast(SrcTy R)
doCast is used by cast<>.
Definition: VPlan.h:3607
This struct provides a method for customizing the way a cast is performed.
Definition: Casting.h:476
static bool isPossible(const VPRecipeBase *f)
Definition: VPlan.h:3594
This struct provides a way to check if a given cast is possible.
Definition: Casting.h:253
static bool isPossible(const From &f)
Definition: Casting.h:254
Struct to hold various analysis needed for cost computations.
Definition: VPlanHelpers.h:344
A recipe for handling first-order recurrence phis.
Definition: VPlan.h:2267
void execute(VPTransformState &State) override
Generate the phi nodes.
VPFirstOrderRecurrencePHIRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:2273
VPFirstOrderRecurrencePHIRecipe(PHINode *Phi, VPValue &Start)
Definition: VPlan.h:2268
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this first-order recurrence phi recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:2291
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
DisjointFlagsTy(bool IsDisjoint)
Definition: VPlan.h:626
NonNegFlagsTy(bool IsNonNeg)
Definition: VPlan.h:631
TruncFlagsTy(bool HasNUW, bool HasNSW)
Definition: VPlan.h:621
WrapFlagsTy(bool HasNUW, bool HasNSW)
Definition: VPlan.h:614
An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use cast/dyn_cast/isa and exec...
Definition: VPlan.h:1397
PHINode & getIRPhi()
Definition: VPlan.h:1405
VPIRPhi(PHINode &PN)
Definition: VPlan.h:1398
static bool classof(const VPRecipeBase *U)
Definition: VPlan.h:1400
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition: VPlan.h:1416
static bool classof(const VPUser *U)
Definition: VPlan.h:1293
VPPhi * clone() override
Clone the current recipe.
Definition: VPlan.h:1308
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition: VPlan.h:1323
VPPhi(ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
Definition: VPlan.h:1290
static bool classof(const VPSingleDefRecipe *SDR)
Definition: VPlan.h:1303
static bool classof(const VPValue *V)
Definition: VPlan.h:1298
A pure-virtual common base class for recipes defining a single VPValue and using IR flags.
Definition: VPlan.h:865
static bool classof(const VPRecipeBase *R)
Definition: VPlan.h:879
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, Instruction &I)
Definition: VPlan.h:870
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:874
std::optional< InstructionCost > getCostForRecipeWithOpcode(unsigned Opcode, ElementCount VF, VPCostContext &Ctx) const
Compute the cost for this recipe for VF, using Opcode and Ctx.
static bool classof(const VPValue *V)
Definition: VPlan.h:899
void execute(VPTransformState &State) override=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
static bool classof(const VPUser *U)
Definition: VPlan.h:894
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition: VPlan.h:866
VPTransformState holds information passed down when "executing" a VPlan, needed for generating the ou...
Definition: VPlanHelpers.h:205
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition: VPlan.h:3130
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:3143
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenLoadEVLRecipe(VPWidenLoadRecipe &L, VPValue *Addr, VPValue &EVL, VPValue *Mask)
Definition: VPlan.h:3131
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3159
A recipe for widening load operations, using the address to load from and an optional mask.
Definition: VPlan.h:3090
VP_CLASSOF_IMPL(VPDef::VPWidenLoadSC)
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3118
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
Definition: VPlan.h:3091
VPWidenLoadRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3100
A recipe for widening select instructions.
Definition: VPlan.h:1707
bool isInvariantCond() const
Definition: VPlan.h:1740
VPWidenSelectRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:1714
VPWidenSelectRecipe(SelectInst &I, ArrayRef< VPValue * > Operands)
Definition: VPlan.h:1708
VPValue * getCond() const
Definition: VPlan.h:1736
unsigned getOpcode() const
Definition: VPlan.h:1734
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:1745
~VPWidenSelectRecipe() override=default
A recipe for widening store operations with vector-predication intrinsics, using the value to store,...
Definition: VPlan.h:3212
VPValue * getStoredValue() const
Return the address accessed by this recipe.
Definition: VPlan.h:3224
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:3243
VPWidenStoreEVLRecipe(VPWidenStoreRecipe &S, VPValue *Addr, VPValue &EVL, VPValue *Mask)
Definition: VPlan.h:3213
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
Definition: VPlan.h:3227
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition: VPlan.h:3170
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition: VPlan.h:3200
VP_CLASSOF_IMPL(VPDef::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
Definition: VPlan.h:3188
VPWidenStoreRecipe * clone() override
Clone the current recipe.
Definition: VPlan.h:3179
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
Definition: VPlan.h:3171