Thanks to visit codestin.com
Credit goes to llvm.org

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