LLVM 24.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 "VPlanValue.h"
28#include "llvm/ADT/Bitfields.h"
29#include "llvm/ADT/MapVector.h"
32#include "llvm/ADT/Twine.h"
33#include "llvm/ADT/ilist.h"
34#include "llvm/ADT/ilist_node.h"
38#include "llvm/IR/DebugLoc.h"
39#include "llvm/IR/FMF.h"
40#include "llvm/IR/Operator.h"
44#include <cassert>
45#include <cstddef>
46#include <functional>
47#include <optional>
48#include <string>
49#include <utility>
50#include <variant>
51
52namespace llvm {
53
54class BasicBlock;
55class DominatorTree;
57class IRBuilderBase;
58struct VPTransformState;
59class raw_ostream;
61class SCEV;
62class SCEVPredicate;
63class Type;
64class VPBasicBlock;
65class VPBuilder;
66class VPDominatorTree;
67class VPRegionBlock;
68class VPlan;
69class VPLane;
71class Value;
73
74struct VPCostContext;
75
76using VPlanPtr = std::unique_ptr<VPlan>;
77
78/// \enum UncountableExitStyle
79/// Different methods of handling early exits.
80///
82 /// No side effects to worry about, so we can process any uncountable exits
83 /// in the loop and branch either to the middle block if the trip count was
84 /// reached, or an early exitblock to determine which exit was taken.
86 /// All memory operations other than the load(s) required to determine whether
87 /// an uncountable exit occurre will be masked based on that condition. If an
88 /// uncountable exit is taken, then all lanes before the exiting lane will
89 /// complete, leaving just the final lane to execute in the scalar tail.
91};
92
93/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
94/// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
96 friend class VPBlockUtils;
97
98protected:
99 /// An enumeration for keeping track of the concrete subclass of VPBlockBase
100 /// that are actually instantiated. Values of this enumeration are kept in the
101 /// SubclassID field of the VPBlockBase objects. They are used for concrete
102 /// type identification.
103 using VPBlockTy = enum : unsigned char {
104 VPRegionBlockSC,
105 VPBasicBlockSC,
106 VPIRBasicBlockSC
107 };
108
109private:
110 /// An optional name for the block.
111 std::string Name;
112
113 /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if
114 /// it is a topmost VPBlockBase.
115 VPRegionBlock *Parent = nullptr;
116
117 /// List of predecessor blocks.
119
120 /// List of successor blocks.
122
123 /// VPlan containing the block. Can only be set on the entry block of the
124 /// plan.
125 VPlan *Plan = nullptr;
126
127 /// Subclass identifier (for isa/dyn_cast).
128 const VPBlockTy SubclassID;
129
130 /// Unique number, used as node number in the dominator tree.
131 unsigned Number;
132
133 /// Add \p Successor as the last successor to this block.
134 void appendSuccessor(VPBlockBase *Successor) {
135 assert(Successor && "Cannot add nullptr successor!");
136 Successors.push_back(Successor);
137 }
138
139 /// Add \p Predecessor as the last predecessor to this block.
140 void appendPredecessor(VPBlockBase *Predecessor) {
141 assert(Predecessor && "Cannot add nullptr predecessor!");
142 Predecessors.push_back(Predecessor);
143 }
144
145 /// Remove \p Predecessor from the predecessors of this block.
146 void removePredecessor(VPBlockBase *Predecessor) {
147 auto Pos = find(Predecessors, Predecessor);
148 assert(Pos && "Predecessor does not exist");
149 Predecessors.erase(Pos);
150 }
151
152 /// Remove \p Successor from the successors of this block.
153 void removeSuccessor(VPBlockBase *Successor) {
154 auto Pos = find(Successors, Successor);
155 assert(Pos && "Successor does not exist");
156 Successors.erase(Pos);
157 }
158
159 /// This function replaces one predecessor with another, useful when
160 /// trying to replace an old block in the CFG with a new one.
161 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
162 auto I = find(Predecessors, Old);
163 assert(I != Predecessors.end());
164 assert(Old->getParent() == New->getParent() &&
165 "replaced predecessor must have the same parent");
166 *I = New;
167 }
168
169 /// This function replaces one successor with another, useful when
170 /// trying to replace an old block in the CFG with a new one.
171 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
172 auto I = find(Successors, Old);
173 assert(I != Successors.end());
174 assert(Old->getParent() == New->getParent() &&
175 "replaced successor must have the same parent");
176 *I = New;
177 }
178
179public:
181
182 virtual ~VPBlockBase() = default;
183
184 const std::string &getName() const { return Name; }
185
186 void setName(const Twine &newName) { Name = newName.str(); }
187
188 /// \return an ID for the concrete type of this object.
189 /// This is used to implement the classof checks. This should not be used
190 /// for any other purpose, as the values may change as LLVM evolves.
191 unsigned getVPBlockID() const { return SubclassID; }
192
193 VPRegionBlock *getParent() { return Parent; }
194 const VPRegionBlock *getParent() const { return Parent; }
195
196 /// \return A pointer to the plan containing the current block.
197 VPlan *getPlan();
198 const VPlan *getPlan() const;
199
200 /// Sets the pointer of the plan containing the block. The block must be the
201 /// entry block into the VPlan.
202 void setPlan(VPlan *ParentPlan);
203
204 void setParent(VPRegionBlock *P) { Parent = P; }
205
206 /// \return the VPBasicBlock that is the entry of this VPBlockBase,
207 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
208 /// VPBlockBase is a VPBasicBlock, it is returned.
209 const VPBasicBlock *getEntryBasicBlock() const;
210 VPBasicBlock *getEntryBasicBlock();
211
212 /// \return the VPBasicBlock that is the exiting this VPBlockBase,
213 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
214 /// VPBlockBase is a VPBasicBlock, it is returned.
215 const VPBasicBlock *getExitingBasicBlock() const;
216 VPBasicBlock *getExitingBasicBlock();
217
218 const VPBlocksTy &getSuccessors() const { return Successors; }
219 VPBlocksTy &getSuccessors() { return Successors; }
220
221 /// Returns true if this block has any successors.
222 bool hasSuccessors() const { return !Successors.empty(); }
223 /// Returns true if this block has any predecessors.
224 bool hasPredecessors() const { return !Predecessors.empty(); }
225
228
229 const VPBlocksTy &getPredecessors() const { return Predecessors; }
230 VPBlocksTy &getPredecessors() { return Predecessors; }
231
232 /// \return the successor of this VPBlockBase if it has a single successor.
233 /// Otherwise return a null pointer.
235 return (Successors.size() == 1 ? *Successors.begin() : nullptr);
236 }
237
238 /// \return the predecessor of this VPBlockBase if it has a single
239 /// predecessor. Otherwise return a null pointer.
241 return (Predecessors.size() == 1 ? *Predecessors.begin() : nullptr);
242 }
243
244 size_t getNumSuccessors() const { return Successors.size(); }
245 size_t getNumPredecessors() const { return Predecessors.size(); }
246
247 /// An Enclosing Block of a block B is any block containing B, including B
248 /// itself. \return the closest enclosing block starting from "this", which
249 /// has successors. \return the root enclosing block if all enclosing blocks
250 /// have no successors.
251 VPBlockBase *getEnclosingBlockWithSuccessors();
252
253 /// \return the closest enclosing block starting from "this", which has
254 /// predecessors. \return the root enclosing block if all enclosing blocks
255 /// have no predecessors.
256 VPBlockBase *getEnclosingBlockWithPredecessors();
257
258 /// \return the successors either attached directly to this VPBlockBase or, if
259 /// this VPBlockBase is the exit block of a VPRegionBlock and has no
260 /// successors of its own, search recursively for the first enclosing
261 /// VPRegionBlock that has successors and return them. If no such
262 /// VPRegionBlock exists, return the (empty) successors of the topmost
263 /// VPBlockBase reached.
265 return getEnclosingBlockWithSuccessors()->getSuccessors();
266 }
267
268 /// \return the predecessors either attached directly to this VPBlockBase or,
269 /// if this VPBlockBase is the entry block of a VPRegionBlock and has no
270 /// predecessors of its own, search recursively for the first enclosing
271 /// VPRegionBlock that has predecessors and return them. If no such
272 /// VPRegionBlock exists, return the (empty) predecessors of the topmost
273 /// VPBlockBase reached.
275 return getEnclosingBlockWithPredecessors()->getPredecessors();
276 }
277
278 /// \return the hierarchical predecessor of this VPBlockBase if it has a
279 /// single hierarchical predecessor. Otherwise return a null pointer.
283
284 /// Set a given VPBlockBase \p Successor as the single successor of this
285 /// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor.
286 /// This VPBlockBase must have no successors.
288 assert(Successors.empty() && "Setting one successor when others exist.");
289 assert(Successor->getParent() == getParent() &&
290 "connected blocks must have the same parent");
291 appendSuccessor(Successor);
292 }
293
294 /// Set two given VPBlockBases \p IfTrue and \p IfFalse to be the two
295 /// successors of this VPBlockBase. This VPBlockBase is not added as
296 /// predecessor of \p IfTrue or \p IfFalse. This VPBlockBase must have no
297 /// successors.
298 void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse) {
299 assert(Successors.empty() && "Setting two successors when others exist.");
300 appendSuccessor(IfTrue);
301 appendSuccessor(IfFalse);
302 }
303
304 /// Set each VPBasicBlock in \p NewPreds as predecessor of this VPBlockBase.
305 /// This VPBlockBase must have no predecessors. This VPBlockBase is not added
306 /// as successor of any VPBasicBlock in \p NewPreds.
308 assert(Predecessors.empty() && "Block predecessors already set.");
309 for (auto *Pred : NewPreds)
310 appendPredecessor(Pred);
311 }
312
313 /// Set each VPBasicBlock in \p NewSuccss as successor of this VPBlockBase.
314 /// This VPBlockBase must have no successors. This VPBlockBase is not added
315 /// as predecessor of any VPBasicBlock in \p NewSuccs.
317 assert(Successors.empty() && "Block successors already set.");
318 for (auto *Succ : NewSuccs)
319 appendSuccessor(Succ);
320 }
321
322 /// Remove all the predecessor of this block.
323 void clearPredecessors() { Predecessors.clear(); }
324
325 /// Remove all the successors of this block.
326 void clearSuccessors() { Successors.clear(); }
327
328 /// Swap predecessors of the block. The block must have exactly 2
329 /// predecessors.
331 assert(Predecessors.size() == 2 && "must have 2 predecessors to swap");
332 std::swap(Predecessors[0], Predecessors[1]);
333 }
334
335 /// Swap successors of the block. The block must have exactly 2 successors.
336 // TODO: This should be part of introducing conditional branch recipes rather
337 // than being independent.
339 assert(Successors.size() == 2 && "must have 2 successors to swap");
340 std::swap(Successors[0], Successors[1]);
341 }
342
343 /// Returns the index for \p Pred in the blocks predecessors list.
344 unsigned getIndexForPredecessor(const VPBlockBase *Pred) const {
345 assert(count(Predecessors, Pred) == 1 &&
346 "must have Pred exactly once in Predecessors");
347 return std::distance(Predecessors.begin(), find(Predecessors, Pred));
348 }
349
350 /// Returns the index for \p Succ in the blocks successor list.
351 unsigned getIndexForSuccessor(const VPBlockBase *Succ) const {
352 assert(count(Successors, Succ) == 1 &&
353 "must have Succ exactly once in Successors");
354 return std::distance(Successors.begin(), find(Successors, Succ));
355 }
356
357 /// Return the unique number of the block.
358 unsigned getNumber() const { return Number; }
359
360 /// Set the unique number of the block, used for dominator tree.
361 void setNumber(unsigned N) { Number = N; }
362
363 /// The method which generates the output IR that correspond to this
364 /// VPBlockBase, thereby "executing" the VPlan.
365 virtual void execute(VPTransformState *State) = 0;
366
367 /// Return the cost of the block.
369
370#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
371 void printAsOperand(raw_ostream &OS, bool PrintType = false) const {
372 OS << getName();
373 }
374
375 /// Print plain-text dump of this VPBlockBase to \p O, prefixing all lines
376 /// with \p Indent. \p SlotTracker is used to print unnamed VPValue's using
377 /// consequtive numbers.
378 ///
379 /// Note that the numbering is applied to the whole VPlan, so printing
380 /// individual blocks is consistent with the whole VPlan printing.
381 virtual void print(raw_ostream &O, const Twine &Indent,
382 VPSlotTracker &SlotTracker) const = 0;
383
384 /// Print plain-text dump of this VPlan to \p O.
385 void print(raw_ostream &O) const;
386
387 /// Print the successors of this block to \p O, prefixing all lines with \p
388 /// Indent.
389 void printSuccessors(raw_ostream &O, const Twine &Indent) const;
390
391 /// Dump this VPBlockBase to dbgs().
392 LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
393#endif
394
395 /// Clone the current block and it's recipes without updating the operands of
396 /// the cloned recipes, including all blocks in the single-entry single-exit
397 /// region for VPRegionBlocks.
398 virtual VPBlockBase *clone() = 0;
399
400protected:
401 VPBlockBase(VPBlockTy SC, const std::string &N) : Name(N), SubclassID(SC) {}
402};
403
404/// VPRecipeBase is a base class modeling a sequence of one or more output IR
405/// instructions. VPRecipeBase owns the VPValues it defines through VPDef
406/// and is responsible for deleting its defined values. Single-value
407/// recipes must inherit from VPSingleDef instead of inheriting from both
408/// VPRecipeBase and VPValue separately.
410 : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
411 public VPDef,
412 public VPUser {
413 friend VPBasicBlock;
414 friend class VPBlockUtils;
415
416 /// Each VPRecipe belongs to a single VPBasicBlock.
417 VPBasicBlock *Parent = nullptr;
418
419 /// The debug location for the recipe.
420 DebugLoc DL;
421
422public:
423 /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
424 /// that is actually instantiated. Values of this enumeration are kept in the
425 /// SubclassID field of the VPRecipeBase objects. They are used for concrete
426 /// type identification.
427 using VPRecipeTy = enum : unsigned char {
428 VPBranchOnMaskSC,
429 VPDerivedIVSC,
430 VPExpandSCEVSC,
431 VPExpressionSC,
432 VPIRInstructionSC,
433 VPInstructionSC,
434 VPInterleaveEVLSC,
435 VPInterleaveSC,
436 VPReductionEVLSC,
437 VPReductionSC,
438 VPReplicateSC,
439 VPScalarIVStepsSC,
440 VPVectorPointerSC,
441 VPVectorEndPointerSC,
442 VPWidenCallSC,
443 VPWidenCanonicalIVSC,
444 VPWidenCastSC,
445 VPWidenGEPSC,
446 VPWidenIntrinsicSC,
447 VPWidenMemIntrinsicSC,
448 VPWidenLoadEVLSC,
449 VPWidenLoadSC,
450 VPWidenStoreEVLSC,
451 VPWidenStoreSC,
452 VPWidenSC,
453 VPBlendSC,
454 VPHistogramSC,
455 // START: Phi-like recipes. Need to be kept together.
456 VPWidenPHISC,
457 VPPredInstPHISC,
458 // START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
459 // VPHeaderPHIRecipe need to be kept together.
460 VPCurrentIterationPHISC,
461 VPActiveLaneMaskPHISC,
462 VPFirstOrderRecurrencePHISC,
463 VPWidenIntOrFpInductionSC,
464 VPWidenPointerInductionSC,
465 VPReductionPHISC,
466 // END: SubclassID for recipes that inherit VPHeaderPHIRecipe
467 // END: Phi-like recipes
468 VPFirstPHISC = VPWidenPHISC,
469 VPFirstHeaderPHISC = VPCurrentIterationPHISC,
470 VPLastHeaderPHISC = VPReductionPHISC,
471 VPLastPHISC = VPReductionPHISC,
472 };
473
476 : VPDef(), VPUser(Operands), DL(DL), SubclassID(SC) {}
477
478 ~VPRecipeBase() override = default;
479
480 /// Clone the current recipe.
481 virtual VPRecipeBase *clone() = 0;
482
483 /// \return the VPBasicBlock which this VPRecipe belongs to.
484 VPBasicBlock *getParent() { return Parent; }
485 const VPBasicBlock *getParent() const { return Parent; }
486
487 /// \return the VPRegionBlock which the recipe belongs to.
488 VPRegionBlock *getRegion();
489 const VPRegionBlock *getRegion() const;
490
491 /// The method which generates the output IR instructions that correspond to
492 /// this VPRecipe, thereby "executing" the VPlan.
493 virtual void execute(VPTransformState &State) = 0;
494
495 /// Return the cost of this recipe, taking into account if the cost
496 /// computation should be skipped and the ForceTargetInstructionCost flag.
497 /// Also takes care of printing the cost for debugging.
499
500 /// Insert an unlinked recipe into a basic block immediately before
501 /// the specified recipe.
502 void insertBefore(VPRecipeBase *InsertPos);
503 /// Insert an unlinked recipe into \p BB immediately before the insertion
504 /// point \p IP;
505 void insertBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator IP);
506
507 /// Insert an unlinked Recipe into a basic block immediately after
508 /// the specified Recipe.
509 void insertAfter(VPRecipeBase *InsertPos);
510
511 /// Unlink this recipe from its current VPBasicBlock and insert it into
512 /// the VPBasicBlock that MovePos lives in, right after MovePos.
513 void moveAfter(VPRecipeBase *MovePos);
514
515 /// Unlink this recipe and insert into BB before I.
516 ///
517 /// \pre I is a valid iterator into BB.
518 void moveBefore(VPBasicBlock &BB, iplist<VPRecipeBase>::iterator I);
519
520 /// This method unlinks 'this' from the containing basic block, but does not
521 /// delete it.
522 void removeFromParent();
523
524 /// This method unlinks 'this' from the containing basic block and deletes it.
525 ///
526 /// \returns an iterator pointing to the element after the erased one
528
529 /// \return an ID for the concrete type of this object.
530 VPRecipeTy getVPRecipeID() const { return SubclassID; }
531
532 /// Method to support type inquiry through isa, cast, and dyn_cast.
533 static inline bool classof(const VPDef *D) {
534 // All VPDefs are also VPRecipeBases.
535 return true;
536 }
537
538 static inline bool classof(const VPUser *U) { return true; }
539
540 /// Returns true if the recipe may have side-effects.
541 bool mayHaveSideEffects() const;
542
543 /// Return true if we can safely execute this recipe unconditionally even if
544 /// it is masked originally.
545 bool isSafeToSpeculativelyExecute() const;
546
547 /// Returns true for PHI-like recipes.
548 bool isPhi() const;
549
550 /// Returns true if the recipe may read from memory.
551 bool mayReadFromMemory() const;
552
553 /// Returns true if the recipe may write to memory.
554 bool mayWriteToMemory() const;
555
556 /// Returns true if the recipe may read from or write to memory.
557 bool mayReadOrWriteMemory() const {
559 }
560
561 /// Returns the debug location of the recipe.
562 DebugLoc getDebugLoc() const { return DL; }
563
564 /// Set the recipe's debug location to \p NewDL.
565 void setDebugLoc(DebugLoc NewDL) { DL = NewDL; }
566
567#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
568 /// Dump the recipe to stderr (for debugging).
569 LLVM_ABI_FOR_TEST void dump() const;
570
571 /// Print the recipe, delegating to printRecipe().
572 void print(raw_ostream &O, const Twine &Indent,
574#endif
575
576private:
577 /// Subclass identifier (for isa/dyn_cast).
578 const VPRecipeTy SubclassID;
579
580protected:
581 /// Compute the cost of this recipe either using a recipe's specialized
582 /// implementation or using the legacy cost model and the underlying
583 /// instructions.
584 virtual InstructionCost computeCost(ElementCount VF,
585 VPCostContext &Ctx) const;
586
587#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
588 /// Each concrete VPRecipe prints itself, without printing common information,
589 /// like debug info or metadata.
590 virtual void printRecipe(raw_ostream &O, const Twine &Indent,
591 VPSlotTracker &SlotTracker) const = 0;
592#endif
593};
594
595// Helper macro to define common classof implementations for recipes.
596#define VP_CLASSOF_IMPL(VPRecipeID) \
597 static inline bool classof(const VPRecipeBase *R) { \
598 return R->getVPRecipeID() == VPRecipeID; \
599 } \
600 static inline bool classof(const VPValue *V) { \
601 auto *R = V->getDefiningRecipe(); \
602 return R && R->getVPRecipeID() == VPRecipeID; \
603 } \
604 static inline bool classof(const VPUser *U) { \
605 auto *R = dyn_cast<VPRecipeBase>(U); \
606 return R && R->getVPRecipeID() == VPRecipeID; \
607 } \
608 static inline bool classof(const VPSingleDefRecipe *R) { \
609 return R->getVPRecipeID() == VPRecipeID; \
610 }
611
612/// Compute the scalar result type for an IR \p Opcode given \p Operands.
613LLVM_ABI Type *computeScalarTypeForInstruction(unsigned Opcode,
615
616/// VPSingleDefRecipe is a base class for recipes that model a sequence of one
617/// or more output IR that define a single result VPValue. Note that
618/// VPSingleDefRecipe must inherit from VPRecipeBase before VPSingleDefValue.
620 public VPSingleDefValue {
621public:
625
628 : VPRecipeBase(SC, Operands, DL), VPSingleDefValue(this, UV) {}
629
631 Value *UV = nullptr, DebugLoc DL = DebugLoc::getUnknown())
632 : VPRecipeBase(SC, Operands, DL), VPSingleDefValue(this, UV, ResultTy) {}
633
634 static inline bool classof(const VPRecipeBase *R) {
635 switch (R->getVPRecipeID()) {
636 case VPRecipeBase::VPDerivedIVSC:
637 case VPRecipeBase::VPExpandSCEVSC:
638 case VPRecipeBase::VPExpressionSC:
639 case VPRecipeBase::VPInstructionSC:
640 case VPRecipeBase::VPReductionEVLSC:
641 case VPRecipeBase::VPReductionSC:
642 case VPRecipeBase::VPReplicateSC:
643 case VPRecipeBase::VPScalarIVStepsSC:
644 case VPRecipeBase::VPVectorPointerSC:
645 case VPRecipeBase::VPVectorEndPointerSC:
646 case VPRecipeBase::VPWidenCallSC:
647 case VPRecipeBase::VPWidenCanonicalIVSC:
648 case VPRecipeBase::VPWidenCastSC:
649 case VPRecipeBase::VPWidenGEPSC:
650 case VPRecipeBase::VPWidenIntrinsicSC:
651 case VPRecipeBase::VPWidenMemIntrinsicSC:
652 case VPRecipeBase::VPWidenSC:
653 case VPRecipeBase::VPBlendSC:
654 case VPRecipeBase::VPPredInstPHISC:
655 case VPRecipeBase::VPCurrentIterationPHISC:
656 case VPRecipeBase::VPActiveLaneMaskPHISC:
657 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
658 case VPRecipeBase::VPWidenPHISC:
659 case VPRecipeBase::VPWidenIntOrFpInductionSC:
660 case VPRecipeBase::VPWidenPointerInductionSC:
661 case VPRecipeBase::VPReductionPHISC:
662 case VPRecipeBase::VPWidenLoadEVLSC:
663 case VPRecipeBase::VPWidenLoadSC:
664 return true;
665 case VPRecipeBase::VPBranchOnMaskSC:
666 case VPRecipeBase::VPInterleaveEVLSC:
667 case VPRecipeBase::VPInterleaveSC:
668 case VPRecipeBase::VPIRInstructionSC:
669 case VPRecipeBase::VPWidenStoreEVLSC:
670 case VPRecipeBase::VPWidenStoreSC:
671 case VPRecipeBase::VPHistogramSC:
672 return false;
673 }
674 llvm_unreachable("Unhandled VPRecipeID");
675 }
676
677 static inline bool classof(const VPValue *V) {
678 auto *R = V->getDefiningRecipe();
679 return R && classof(R);
680 }
681
682 static inline bool classof(const VPUser *U) {
683 auto *R = dyn_cast<VPRecipeBase>(U);
684 return R && classof(R);
685 }
686
687 VPSingleDefRecipe *clone() override = 0;
688
689 /// Returns the underlying instruction.
696
697#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
698 /// Print this VPSingleDefRecipe to dbgs() (for debugging).
700#endif
701};
702
703/// Class to record and manage LLVM IR flags.
706 enum class OperationType : unsigned char {
707 Cmp,
708 FCmp,
709 OverflowingBinOp,
710 Trunc,
711 DisjointOp,
712 PossiblyExactOp,
713 GEPOp,
714 FPMathOp,
715 NonNegOp,
716 ReductionOp,
717 Other
718 };
719
720public:
721 struct WrapFlagsTy {
722 char HasNUW : 1;
723 char HasNSW : 1;
724
727 };
728
730 char HasNUW : 1;
731 char HasNSW : 1;
732
734 };
735
740
742 char NonNeg : 1;
743 NonNegFlagsTy(bool IsNonNeg) : NonNeg(IsNonNeg) {}
744 };
745
746private:
747 struct ExactFlagsTy {
748 char IsExact : 1;
749 ExactFlagsTy(bool Exact) : IsExact(Exact) {}
750 };
751 struct FastMathFlagsTy {
752 char AllowReassoc : 1;
753 char NoNaNs : 1;
754 char NoInfs : 1;
755 char NoSignedZeros : 1;
756 char AllowReciprocal : 1;
757 char AllowContract : 1;
758 char ApproxFunc : 1;
759
760 LLVM_ABI_FOR_TEST FastMathFlagsTy(const FastMathFlags &FMF);
761 };
762 /// Holds both the predicate and fast-math flags for floating-point
763 /// comparisons.
764 struct FCmpFlagsTy {
765 uint8_t CmpPredStorage;
766 FastMathFlagsTy FMFs;
767 };
768 /// Holds reduction-specific flags: RecurKind, IsOrdered, IsInLoop, and FMFs.
769 struct ReductionFlagsTy {
770 // RecurKind has ~26 values, needs 5 bits but uses 6 bits to account for
771 // additional kinds.
772 unsigned char Kind : 6;
773 // TODO: Derive order/in-loop from plan and remove here.
774 unsigned char IsOrdered : 1;
775 unsigned char IsInLoop : 1;
776 FastMathFlagsTy FMFs;
777
778 ReductionFlagsTy(RecurKind Kind, bool IsOrdered, bool IsInLoop,
779 FastMathFlags FMFs)
780 : Kind(static_cast<unsigned char>(Kind)), IsOrdered(IsOrdered),
781 IsInLoop(IsInLoop), FMFs(FMFs) {}
782 };
783
784 OperationType OpType;
785
786 union {
791 ExactFlagsTy ExactFlags;
794 FastMathFlagsTy FMFs;
795 FCmpFlagsTy FCmpFlags;
796 ReductionFlagsTy ReductionFlags;
798 };
799
800public:
801 VPIRFlags() : OpType(OperationType::Other), AllFlags() {}
802
804 if (auto *FCmp = dyn_cast<FCmpInst>(&I)) {
805 OpType = OperationType::FCmp;
807 FCmp->getPredicate());
808 assert(getPredicate() == FCmp->getPredicate() && "predicate truncated");
809 FCmpFlags.FMFs = FCmp->getFastMathFlags();
810 } else if (auto *Op = dyn_cast<CmpInst>(&I)) {
811 OpType = OperationType::Cmp;
813 Op->getPredicate());
814 assert(getPredicate() == Op->getPredicate() && "predicate truncated");
815 } else if (auto *Op = dyn_cast<PossiblyDisjointInst>(&I)) {
816 OpType = OperationType::DisjointOp;
817 DisjointFlags.IsDisjoint = Op->isDisjoint();
818 } else if (auto *Op = dyn_cast<OverflowingBinaryOperator>(&I)) {
819 OpType = OperationType::OverflowingBinOp;
820 WrapFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
821 } else if (auto *Op = dyn_cast<TruncInst>(&I)) {
822 OpType = OperationType::Trunc;
823 TruncFlags = {Op->hasNoUnsignedWrap(), Op->hasNoSignedWrap()};
824 } else if (auto *Op = dyn_cast<PossiblyExactOperator>(&I)) {
825 OpType = OperationType::PossiblyExactOp;
826 ExactFlags.IsExact = Op->isExact();
827 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
828 OpType = OperationType::GEPOp;
829 GEPFlagsStorage = GEP->getNoWrapFlags().getRaw();
830 assert(getGEPNoWrapFlags() == GEP->getNoWrapFlags() &&
831 "wrap flags truncated");
832 } else if (auto *PNNI = dyn_cast<PossiblyNonNegInst>(&I)) {
833 OpType = OperationType::NonNegOp;
834 NonNegFlags.NonNeg = PNNI->hasNonNeg();
835 } else if (auto *Op = dyn_cast<FPMathOperator>(&I)) {
836 OpType = OperationType::FPMathOp;
837 FMFs = Op->getFastMathFlags();
838 }
839 }
840
841 VPIRFlags(CmpInst::Predicate Pred) : OpType(OperationType::Cmp), AllFlags() {
843 assert(getPredicate() == Pred && "predicate truncated");
844 }
845
847 : OpType(OperationType::FCmp), AllFlags() {
849 assert(getPredicate() == Pred && "predicate truncated");
850 FCmpFlags.FMFs = FMFs;
851 }
852
854 : OpType(OperationType::OverflowingBinOp), AllFlags() {
855 this->WrapFlags = WrapFlags;
856 }
857
859 : OpType(OperationType::Trunc), AllFlags() {
860 this->TruncFlags = TruncFlags;
861 }
862
863 VPIRFlags(FastMathFlags FMFs) : OpType(OperationType::FPMathOp), AllFlags() {
864 this->FMFs = FMFs;
865 }
866
868 : OpType(OperationType::DisjointOp), AllFlags() {
869 this->DisjointFlags = DisjointFlags;
870 }
871
873 : OpType(OperationType::NonNegOp), AllFlags() {
874 this->NonNegFlags = NonNegFlags;
875 }
876
877 VPIRFlags(ExactFlagsTy ExactFlags)
878 : OpType(OperationType::PossiblyExactOp), AllFlags() {
879 this->ExactFlags = ExactFlags;
880 }
881
883 : OpType(OperationType::GEPOp), AllFlags() {
884 GEPFlagsStorage = GEPFlags.getRaw();
885 }
886
887 VPIRFlags(RecurKind Kind, bool IsOrdered, bool IsInLoop, FastMathFlags FMFs)
888 : OpType(OperationType::ReductionOp), AllFlags() {
889 ReductionFlags = ReductionFlagsTy(Kind, IsOrdered, IsInLoop, FMFs);
890 }
891
893 OpType = Other.OpType;
894 AllFlags[0] = Other.AllFlags[0];
895 AllFlags[1] = Other.AllFlags[1];
896 }
897
898 /// Only keep flags also present in \p Other. \p Other must have the same
899 /// OpType as the current object.
900 void intersectFlags(const VPIRFlags &Other);
901
902 /// Drop all poison-generating flags.
904 // NOTE: This needs to be kept in-sync with
905 // Instruction::dropPoisonGeneratingFlags.
906 switch (OpType) {
907 case OperationType::OverflowingBinOp:
908 WrapFlags.HasNUW = false;
909 WrapFlags.HasNSW = false;
910 break;
911 case OperationType::Trunc:
912 TruncFlags.HasNUW = false;
913 TruncFlags.HasNSW = false;
914 break;
915 case OperationType::DisjointOp:
916 DisjointFlags.IsDisjoint = false;
917 break;
918 case OperationType::PossiblyExactOp:
919 ExactFlags.IsExact = false;
920 break;
921 case OperationType::GEPOp:
922 GEPFlagsStorage = 0;
923 break;
924 case OperationType::FPMathOp:
925 case OperationType::FCmp:
926 case OperationType::ReductionOp:
927 getFMFsRef().NoNaNs = false;
928 getFMFsRef().NoInfs = false;
929 break;
930 case OperationType::NonNegOp:
931 NonNegFlags.NonNeg = false;
932 break;
933 case OperationType::Cmp:
934 case OperationType::Other:
935 break;
936 }
937 }
938
939 /// Apply the IR flags to \p I.
940 void applyFlags(Instruction &I) const {
941 switch (OpType) {
942 case OperationType::OverflowingBinOp:
943 I.setHasNoUnsignedWrap(WrapFlags.HasNUW);
944 I.setHasNoSignedWrap(WrapFlags.HasNSW);
945 break;
946 case OperationType::Trunc:
947 I.setHasNoUnsignedWrap(TruncFlags.HasNUW);
948 I.setHasNoSignedWrap(TruncFlags.HasNSW);
949 break;
950 case OperationType::DisjointOp:
951 cast<PossiblyDisjointInst>(&I)->setIsDisjoint(DisjointFlags.IsDisjoint);
952 break;
953 case OperationType::PossiblyExactOp:
954 I.setIsExact(ExactFlags.IsExact);
955 break;
956 case OperationType::GEPOp:
957 cast<GetElementPtrInst>(&I)->setNoWrapFlags(
959 break;
960 case OperationType::FPMathOp:
961 case OperationType::FCmp: {
962 const FastMathFlagsTy &F = getFMFsRef();
963 I.setHasAllowReassoc(F.AllowReassoc);
964 I.setHasNoNaNs(F.NoNaNs);
965 I.setHasNoInfs(F.NoInfs);
966 I.setHasNoSignedZeros(F.NoSignedZeros);
967 I.setHasAllowReciprocal(F.AllowReciprocal);
968 I.setHasAllowContract(F.AllowContract);
969 I.setHasApproxFunc(F.ApproxFunc);
970 break;
971 }
972 case OperationType::NonNegOp:
973 I.setNonNeg(NonNegFlags.NonNeg);
974 break;
975 case OperationType::ReductionOp:
976 llvm_unreachable("reduction ops should not use applyFlags");
977 case OperationType::Cmp:
978 case OperationType::Other:
979 break;
980 }
981 }
982
984 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
985 "recipe doesn't have a compare predicate");
986 uint8_t Storage = OpType == OperationType::FCmp ? FCmpFlags.CmpPredStorage
989 }
990
992 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
993 "recipe doesn't have a compare predicate");
994 if (OpType == OperationType::FCmp)
996 else
998 assert(getPredicate() == Pred && "predicate truncated");
999 }
1000
1004
1005 /// Returns true if the recipe has a comparison predicate.
1006 bool hasPredicate() const {
1007 return OpType == OperationType::Cmp || OpType == OperationType::FCmp;
1008 }
1009
1010 /// Returns true if the recipe has fast-math flags.
1011 bool hasFastMathFlags() const {
1012 return OpType == OperationType::FPMathOp || OpType == OperationType::FCmp ||
1013 OpType == OperationType::ReductionOp;
1014 }
1015
1017
1018 bool isNonNeg() const {
1019 assert(OpType == OperationType::NonNegOp &&
1020 "recipe doesn't have a NNEG flag");
1021 return NonNegFlags.NonNeg;
1022 }
1023
1024 bool hasNoUnsignedWrap() const {
1025 switch (OpType) {
1026 case OperationType::OverflowingBinOp:
1027 return WrapFlags.HasNUW;
1028 case OperationType::Trunc:
1029 return TruncFlags.HasNUW;
1030 default:
1031 llvm_unreachable("recipe doesn't have a NUW flag");
1032 }
1033 }
1034
1035 bool hasNoSignedWrap() const {
1036 switch (OpType) {
1037 case OperationType::OverflowingBinOp:
1038 return WrapFlags.HasNSW;
1039 case OperationType::Trunc:
1040 return TruncFlags.HasNSW;
1041 default:
1042 llvm_unreachable("recipe doesn't have a NSW flag");
1043 }
1044 }
1045
1047 switch (OpType) {
1048 case OperationType::OverflowingBinOp:
1049 case OperationType::Trunc:
1050 return {hasNoUnsignedWrap(), hasNoSignedWrap()};
1051 default:
1052 return {};
1053 }
1054 }
1055
1057 return {hasNoUnsignedWrap(), hasNoSignedWrap()};
1058 }
1059
1060 bool isDisjoint() const {
1061 assert(OpType == OperationType::DisjointOp &&
1062 "recipe cannot have a disjoing flag");
1063 return DisjointFlags.IsDisjoint;
1064 }
1065
1067 assert(OpType == OperationType::ReductionOp &&
1068 "recipe doesn't have reduction flags");
1069 return static_cast<RecurKind>(ReductionFlags.Kind);
1070 }
1071
1072 bool isReductionOrdered() const {
1073 assert(OpType == OperationType::ReductionOp &&
1074 "recipe doesn't have reduction flags");
1075 return ReductionFlags.IsOrdered;
1076 }
1077
1078 bool isReductionInLoop() const {
1079 assert(OpType == OperationType::ReductionOp &&
1080 "recipe doesn't have reduction flags");
1081 return ReductionFlags.IsInLoop;
1082 }
1083
1084private:
1085 /// Get a reference to the fast-math flags for FPMathOp, FCmp or ReductionOp.
1086 FastMathFlagsTy &getFMFsRef() {
1087 if (OpType == OperationType::FCmp)
1088 return FCmpFlags.FMFs;
1089 if (OpType == OperationType::ReductionOp)
1090 return ReductionFlags.FMFs;
1091 return FMFs;
1092 }
1093 const FastMathFlagsTy &getFMFsRef() const {
1094 if (OpType == OperationType::FCmp)
1095 return FCmpFlags.FMFs;
1096 if (OpType == OperationType::ReductionOp)
1097 return ReductionFlags.FMFs;
1098 return FMFs;
1099 }
1100
1101public:
1102 /// Returns default flags for \p Opcode and scalar \p ResultTy for opcodes
1103 /// that support it, asserts otherwise. Opcodes not supporting default flags
1104 /// include compares and ComputeReductionResult.
1105 static VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy = nullptr);
1106
1107#if !defined(NDEBUG)
1108 /// Returns true if the set flags are valid for \p Opcode.
1109 LLVM_ABI_FOR_TEST bool flagsValidForOpcode(unsigned Opcode) const;
1110
1111 /// Returns true if \p Opcode with scalar result type \p ResultTy has its
1112 /// required flags set.
1113 LLVM_ABI_FOR_TEST bool hasRequiredFlagsForOpcode(unsigned Opcode,
1114 Type *ResultTy) const;
1115#endif
1116
1117#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1118 void printFlags(raw_ostream &O) const;
1119#endif
1120};
1122
1123static_assert(sizeof(VPIRFlags) <= 3, "VPIRFlags should not grow");
1124
1125/// A pure-virtual common base class for recipes defining a single VPValue and
1126/// using IR flags.
1129 const VPIRFlags &Flags,
1131 : VPSingleDefRecipe(SC, Operands, DL), VPIRFlags(Flags) {}
1132
1134 Type *ResultTy, const VPIRFlags &Flags,
1136 : VPSingleDefRecipe(SC, Operands, ResultTy, /*UV=*/nullptr, DL),
1137 VPIRFlags(Flags) {}
1138
1139 static inline bool classof(const VPRecipeBase *R) {
1140 return R->getVPRecipeID() == VPRecipeBase::VPBlendSC ||
1141 R->getVPRecipeID() == VPRecipeBase::VPInstructionSC ||
1142 R->getVPRecipeID() == VPRecipeBase::VPWidenSC ||
1143 R->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC ||
1144 R->getVPRecipeID() == VPRecipeBase::VPWidenCallSC ||
1145 R->getVPRecipeID() == VPRecipeBase::VPWidenCastSC ||
1146 R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
1147 R->getVPRecipeID() == VPRecipeBase::VPWidenMemIntrinsicSC ||
1148 R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
1149 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC ||
1150 R->getVPRecipeID() == VPRecipeBase::VPReplicateSC ||
1151 R->getVPRecipeID() == VPRecipeBase::VPVectorEndPointerSC ||
1152 R->getVPRecipeID() == VPRecipeBase::VPVectorPointerSC ||
1153 R->getVPRecipeID() == VPRecipeBase::VPWidenCanonicalIVSC ||
1154 R->getVPRecipeID() == VPRecipeBase::VPDerivedIVSC;
1155 }
1156
1157 static inline bool classof(const VPUser *U) {
1158 auto *R = dyn_cast<VPRecipeBase>(U);
1159 return R && classof(R);
1160 }
1161
1162 static inline bool classof(const VPValue *V) {
1163 auto *R = V->getDefiningRecipe();
1164 return R && classof(R);
1165 }
1166
1168
1169 static inline bool classof(const VPSingleDefRecipe *R) {
1170 return classof(static_cast<const VPRecipeBase *>(R));
1171 }
1172
1173 void execute(VPTransformState &State) override = 0;
1174
1175 /// Compute the cost for this recipe for \p VF, using \p Opcode and \p Ctx.
1177 VPCostContext &Ctx) const;
1178};
1179
1180/// Helper to manage IR metadata for recipes. It filters out metadata that
1181/// cannot be propagated.
1184
1185 /// Name of the VPlan-internal metadata kind holding the execution frequency.
1186 static constexpr StringLiteral ExecutionFrequencyMDName =
1187 "vplan.execution.frequency";
1188
1189 /// Returns the ID of the metadata kind named \p Kind, taking the context from
1190 /// any attached node; all belong to the context of the VPlan's function.
1191 unsigned getMDKindID(StringRef Kind) const {
1192 assert(!Metadata.empty() && "no node to take the context from");
1193 return Metadata.front().second->getContext().getMDKindID(Kind);
1194 }
1195
1196public:
1197 VPIRMetadata() = default;
1198
1199 /// Adds metatadata that can be preserved from the original instruction
1200 /// \p I.
1202 getMetadataToPropagate(&I, Metadata);
1203 // Retain the branch weights of terminators. They are used to compute the
1204 // frequencies with which the blocks of the original loop execute.
1205 if (I.isTerminator())
1206 if (MDNode *BW = I.getMetadata(LLVMContext::MD_prof))
1207 Metadata.emplace_back(LLVMContext::MD_prof, BW);
1208 }
1209
1210 /// Copy constructor for cloning.
1212
1214
1215 /// Add all metadata to \p I.
1216 void applyMetadata(Instruction &I) const;
1217
1218 /// Set metadata with kind \p Kind to \p Node. If metadata with \p Kind
1219 /// already exists, it will be replaced. Otherwise, it will be added.
1220 void setMetadata(unsigned Kind, MDNode *Node) {
1221 auto It =
1222 llvm::find_if(Metadata, [Kind](const std::pair<unsigned, MDNode *> &P) {
1223 return P.first == Kind;
1224 });
1225 if (It != Metadata.end())
1226 It->second = Node;
1227 else
1228 Metadata.emplace_back(Kind, Node);
1229 }
1230
1231 /// Intersect this VPIRMetadata object with \p MD, keeping only metadata
1232 /// nodes that are common to both.
1233 void intersect(const VPIRMetadata &MD);
1234
1235 /// Get metadata of kind \p Kind. Returns nullptr if not found.
1236 MDNode *getMetadata(unsigned Kind) const {
1237 auto It =
1238 find_if(Metadata, [Kind](const auto &P) { return P.first == Kind; });
1239 return It != Metadata.end() ? It->second : nullptr;
1240 }
1241
1242 /// Record that the recipe executes with frequency \p Freq, relative to the
1243 /// entry of the loop region; see vputils::AlwaysExecutesFreq.
1244 void setExecutionFrequency(std::optional<BlockFrequency> Freq,
1245 LLVMContext &Ctx);
1246
1247 /// Returns the frequency recorded by setExecutionFrequency, if any.
1248 std::optional<BlockFrequency> getExecutionFrequency() const;
1249
1250 /// Drop the frequency recorded by setExecutionFrequency, if any.
1251 void clearExecutionFrequency();
1252
1253#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1254 /// Print metadata with node IDs.
1255 void print(raw_ostream &O, VPSlotTracker &SlotTracker) const;
1256#endif
1257};
1258
1259/// This is a concrete Recipe that models a single VPlan-level instruction.
1260/// While as any Recipe it may generate a sequence of IR instructions when
1261/// executed, these instructions would always form a single-def expression as
1262/// the VPInstruction is also a single def-use vertex. Most VPInstruction
1263/// opcodes can take an optional mask. Masks may be assigned during
1264/// predication.
1266 public VPIRMetadata {
1267public:
1268 /// VPlan opcodes, extending LLVM IR with idiomatics instructions.
1269 enum {
1271 Instruction::OtherOpsEnd + 1, // Combines the incoming and previous
1272 // values of a first-order recurrence.
1274 // Creates a mask where each lane is active (true) whilst the current
1275 // counter (first operand + index) is less than the second operand. i.e.
1276 // mask[i] = icmpt ult (op0 + i), op1
1277 // ActiveLaneMask is used for early-exit loops with stores, plus tail
1278 // folding for all styles except DataAndControlFlow. The size of the
1279 // mask returned is VF. When unrolled, ActiveLaneMask is duplicated.
1281 // As above, but takes an additional operand (Multiplier). The size of
1282 // the mask returned is VF * Multiplier (UF, op2).
1283 // WideActiveLaneMask is used for control flow and is unrolled by widening,
1284 // with one extract vector created per unroll part.
1286 // Extracts each unrolled part of a (VF * UF) widened vector/mask.
1289 // Represents the incoming loop-invariant alias-mask. All memory accesses
1290 // in the loop must stay within the active lanes.
1292 // Increment the canonical IV separately for each unrolled part.
1294 // Abstract instruction that compares two values and branches. This is
1295 // lowered to ICmp + BranchOnCond during VPlan to VPlan transformation.
1298 // Branch with 2 boolean condition operands and 3 successors. If condition
1299 // 0 is true, branches to successor 0; if condition 1 is true, branches to
1300 // successor 1; otherwise branches to successor 2. Expanded after region
1301 // dissolution into: (1) an OR of the two conditions branching to
1302 // middle.split or successor 2, and (2) middle.split branching to successor
1303 // 0 or successor 1 based on condition 0.
1306 /// Given operands of (the same) struct type, creates a struct of fixed-
1307 /// width vectors each containing a struct field of all operands. The
1308 /// number of operands matches the element count of every vector.
1310 /// Creates a fixed-width vector containing all operands. The number of
1311 /// operands matches the vector element count.
1313 /// Extracts all lanes from its (non-scalable) vector operand. This is an
1314 /// abstract VPInstruction whose single defined VPValue represents VF
1315 /// scalars extracted from a vector, to be replaced by VF ExtractElement
1316 /// VPInstructions.
1318 /// Reduce the operands to the final reduction result using the operation
1319 /// specified via the operation's VPIRFlags.
1321 // Extracts the last part of its operand. Removed during unrolling.
1323 // Extracts the last lane of its vector operand, per part.
1325 // Extracts the second-to-last lane from its operand or the second-to-last
1326 // part if it is scalar. In the latter case, the recipe will be removed
1327 // during unrolling.
1329 LogicalAnd, // Non-poison propagating logical And.
1330 LogicalOr, // Non-poison propagating logical Or.
1331 NumActiveLanes, // Counts the number of active lanes in a mask.
1332 // Add an offset in bytes (second operand) to a base pointer (first
1333 // operand). Only generates scalar values (either for the first lane only or
1334 // for all lanes, depending on its uses).
1336 // Add a vector offset in bytes (second operand) to a scalar base pointer
1337 // (first operand).
1339 // Returns a scalar boolean value, which is true if any lane of its
1340 // (boolean) vector operands is true. It produces the reduced value across
1341 // all unrolled iterations. Unrolling will add all copies of its original
1342 // operand as additional operands. AnyOf is poison-safe as all operands
1343 // will be frozen.
1345 // Calculates the first active lane index of the vector predicate operands.
1346 // It produces the lane index across all unrolled iterations. Unrolling will
1347 // add all copies of its original operand as additional operands.
1348 // Implemented with @llvm.experimental.cttz.elts, but returns the expected
1349 // result even with operands that are all zeroes.
1351 // Calculates the last active lane index of the vector predicate operands.
1352 // The predicates must be prefix-masks (all 1s before all 0s). Used when
1353 // tail-folding to extract the correct live-out value from the last active
1354 // iteration. It produces the lane index across all unrolled iterations.
1355 // Unrolling will add all copies of its original operand as additional
1356 // operands.
1358 // Returns a reversed vector for the operand.
1360 /// Start vector for reductions with 3 operands: the original start value,
1361 /// the identity value for the reduction and an integer indicating the
1362 /// scaling factor.
1364 /// Extracts a single lane (first operand) from a set of vector operands.
1365 /// The lane specifies an index into a vector formed by combining all vector
1366 /// operands (all operands after the first one).
1368 /// Explicit user for the resume phi of the canonical induction in the main
1369 /// VPlan, used by the epilogue vector loop.
1371 /// Extracts the last active lane from a set of vectors. The first operand
1372 /// is the default value if no lanes in the masks are active. Conceptually,
1373 /// this concatenates all data vectors (odd operands), concatenates all
1374 /// masks (even operands -- ignoring the default value), and returns the
1375 /// last active value from the combined data vector using the combined mask.
1377 /// Compute the exiting value of a wide induction after vectorization, that
1378 /// is the value of the last lane of the induction increment (i.e. its
1379 /// backedge value). Has the wide induction recipe as operand.
1382
1383 // The opcodes below are used for VPInstructionWithType.
1384 // NOTE: VPInstructionWithType classes are also used for:
1385 // 1. All CastInst variants - see createVPInstructionsForVPBB, and other
1386 // cases where createScalarCast, createScalarZExtOrTrunc and
1387 // createScalarSExtOrTrunc are invoked.
1388 // 2. Scalar load instructions - see createVPInstructionsForVPBB.
1389
1390 /// Scale the first operand (vector step) by the second operand
1391 /// (scalar-step). Casts both operands to the result type if needed.
1393 // Creates a step vector starting from 0 to VF with a step of 1.
1395 /// Calls a scalar intrinsic. The intrinsic ID is the last operand.
1397
1399 };
1400
1401 /// Returns true if this recipe produces scalar values for all VF lanes.
1402 bool doesGeneratePerAllLanes() const;
1403
1404 /// Return the number of operands determined by the opcode of the
1405 /// VPInstruction, excluding mask. Returns -1u if the number of operands
1406 /// cannot be determined directly by the opcode.
1407 unsigned getNumOperandsForOpcode() const;
1408
1409private:
1410 typedef unsigned char OpcodeTy;
1411 OpcodeTy Opcode;
1412
1413 /// An optional name that can be used for the generated IR instruction.
1414 std::string Name;
1415
1416 /// Returns true if we can generate a scalar for the first lane only if
1417 /// needed.
1418 bool canGenerateScalarForFirstLane() const;
1419
1420 /// Utility methods serving execute(): generates a single vector instance of
1421 /// the modeled instruction. \returns the generated value. . In some cases an
1422 /// existing value is returned rather than a generated one.
1423 Value *generate(VPTransformState &State);
1424
1425 /// Returns true if the VPInstruction does not need masking.
1426 bool alwaysUnmasked() const {
1427 if (Opcode == VPInstruction::MaskedCond)
1428 return false;
1429
1430 // For now only VPInstructions with underlying values use masks.
1431 // TODO: provide masks to VPInstructions w/o underlying values.
1432 if (!getUnderlyingValue())
1433 return true;
1434
1435 return Instruction::isCast(Opcode) || Opcode == Instruction::PHI ||
1436 Opcode == Instruction::GetElementPtr;
1437 }
1438
1439public:
1440 VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands,
1441 const VPIRFlags &Flags = {}, const VPIRMetadata &MD = {},
1442 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "",
1443 Type *ResultTy = nullptr);
1444
1445 VP_CLASSOF_IMPL(VPRecipeBase::VPInstructionSC)
1446
1447 VPInstruction *clone() override {
1449 }
1450
1452 Type *ResultTy = nullptr) {
1453 auto *New = new VPInstruction(Opcode, NewOperands, *this, *this,
1454 getDebugLoc(), Name, ResultTy);
1455 if (getUnderlyingValue())
1456 New->setUnderlyingValue(getUnderlyingInstr());
1457 return New;
1458 }
1459
1460 unsigned getOpcode() const { return Opcode; }
1461
1462 /// Add \p Op as operand of this VPInstruction. Only supported for AnyOf,
1463 /// ComputeReductionResult, BuildVector, BuildStructVector, ExtractLane,
1464 /// ExtractLastActive, FirstActiveLane, LastActiveLane.
1465 void addOperand(VPValue *Op);
1466
1467 /// Generate the instruction.
1468 /// TODO: We currently execute only per-part unless a specific instance is
1469 /// provided.
1470 void execute(VPTransformState &State) override;
1471
1472 /// Return the cost of this VPInstruction.
1473 InstructionCost computeCost(ElementCount VF,
1474 VPCostContext &Ctx) const override;
1475
1476#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1477 /// Print the VPInstruction to dbgs() (for debugging).
1478 LLVM_DUMP_METHOD void dump() const;
1479#endif
1480
1481 bool hasResult() const {
1482 // CallInst may or may not have a result, depending on the called function.
1483 // Conservatively return calls have results for now.
1484 switch (getOpcode()) {
1485 case Instruction::Ret:
1486 case Instruction::UncondBr:
1487 case Instruction::CondBr:
1488 case Instruction::Store:
1489 case Instruction::Switch:
1490 case Instruction::IndirectBr:
1491 case Instruction::Resume:
1492 case Instruction::CatchRet:
1493 case Instruction::Unreachable:
1494 case Instruction::Fence:
1495 case Instruction::AtomicRMW:
1499 return false;
1500 default:
1501 return true;
1502 }
1503 }
1504
1505 /// Returns true if the VPInstruction has a mask operand.
1506 bool isMasked() const {
1507 unsigned NumOpsForOpcode = getNumOperandsForOpcode();
1508 // VPInstructions without a fixed number of operands cannot be masked.
1509 if (NumOpsForOpcode == -1u)
1510 return false;
1511 return NumOpsForOpcode + 1 == getNumOperands();
1512 }
1513
1514 /// Returns the number of operands, excluding the mask if the VPInstruction is
1515 /// masked.
1516 unsigned getNumOperandsWithoutMask() const {
1517 return getNumOperands() - isMasked();
1518 }
1519
1520 /// Add mask \p Mask to an unmasked VPInstruction, if it needs masking.
1521 void addMask(VPValue *Mask) {
1522 assert(!isMasked() && "recipe is already masked");
1523 if (alwaysUnmasked())
1524 return;
1525 assert(Mask->getScalarType()->isIntegerTy(1) &&
1526 "Mask must be an i1 (vector)");
1527 VPUser::addOperand(Mask);
1528 }
1529
1530 /// Returns the mask for the VPInstruction. Returns nullptr for unmasked
1531 /// VPInstructions.
1532 VPValue *getMask() const {
1533 return isMasked() ? getOperand(getNumOperands() - 1) : nullptr;
1534 }
1535
1536 /// Returns an iterator range over the operands excluding the mask operand
1537 /// if present.
1544
1545 /// Returns true if the underlying opcode may read from or write to memory.
1546 bool opcodeMayReadOrWriteFromMemory() const;
1547
1548 /// Returns true if the recipe only uses the first lane of operand \p Op.
1549 bool usesFirstLaneOnly(const VPValue *Op) const override;
1550
1551 /// Returns true if the recipe only uses the first part of operand \p Op.
1552 bool usesFirstPartOnly(const VPValue *Op) const override;
1553
1554 /// Returns true if this VPInstruction produces a scalar value from a vector,
1555 /// e.g. by performing a reduction or extracting a lane.
1556 bool isVectorToScalar() const;
1557
1558 /// Returns true if the recipe produces a single scalar value.
1559 bool isSingleScalar() const;
1560
1561 /// Returns the symbolic name assigned to the VPInstruction.
1562 StringRef getName() const { return Name; }
1563
1564 /// Set the symbolic name for the VPInstruction.
1565 void setName(StringRef NewName) { Name = NewName.str(); }
1566
1567protected:
1568#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1569 /// Print the VPInstruction to \p O.
1570 void printRecipe(raw_ostream &O, const Twine &Indent,
1571 VPSlotTracker &SlotTracker) const override;
1572#endif
1573};
1574
1575/// A specialization of VPInstruction augmenting it with a dedicated result
1576/// type, to be used when the opcode and operands of the VPInstruction don't
1577/// directly determine the result type. Note that there is no separate recipe ID
1578/// for VPInstructionWithType; it shares the same ID as VPInstruction and is
1579/// distinguished purely by the opcode.
1580/// TODO: Merge with VPInstruction, now that VPRecipeValue provides the type.
1582public:
1584 Type *ResultTy, const VPIRFlags &Flags = {},
1585 const VPIRMetadata &Metadata = {},
1587 const Twine &Name = "", Value *UV = nullptr)
1588 : VPInstruction(Opcode, Operands, Flags, Metadata, DL, Name, ResultTy) {
1590 }
1591
1592 static inline bool classof(const VPRecipeBase *R) {
1593 // VPInstructionWithType are VPInstructions with specific opcodes requiring
1594 // type information.
1595 auto *VPI = dyn_cast<VPInstruction>(R);
1596 if (!VPI)
1597 return false;
1598 unsigned Opc = VPI->getOpcode();
1600 return true;
1601 switch (Opc) {
1605 case Instruction::Load:
1606 return true;
1607 default:
1608 return false;
1609 }
1610 }
1611
1612 static inline bool classof(const VPUser *R) {
1614 }
1615
1616 VPInstruction *clone() override {
1617 auto *New =
1619 *this, *this, getDebugLoc(), getName());
1620 New->setUnderlyingValue(getUnderlyingValue());
1621 return New;
1622 }
1623
1624 void execute(VPTransformState &State) override;
1625
1626 /// Return the cost of this VPInstruction.
1628 VPCostContext &Ctx) const override;
1629
1630 Type *getResultType() const { return getScalarType(); }
1631
1632 /// Cast recipes always use scalars of their operand.
1633 bool usesScalars(const VPValue *Op) const override {
1635 return true;
1637 }
1638
1639protected:
1640#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1641 /// Print the recipe.
1642 void printRecipe(raw_ostream &O, const Twine &Indent,
1643 VPSlotTracker &SlotTracker) const override;
1644#endif
1645};
1646
1647/// Helper type to provide functions to access incoming values and blocks for
1648/// phi-like recipes.
1650protected:
1651 /// Return a VPRecipeBase* to the current object.
1652 virtual const VPRecipeBase *getAsRecipe() const = 0;
1653
1654public:
1655 virtual ~VPPhiAccessors() = default;
1656
1657 /// Returns the incoming VPValue with index \p Idx.
1658 VPValue *getIncomingValue(unsigned Idx) const {
1659 return getAsRecipe()->getOperand(Idx);
1660 }
1661
1662 /// Returns the incoming block with index \p Idx.
1663 const VPBasicBlock *getIncomingBlock(unsigned Idx) const;
1664
1665 /// Returns the incoming value for \p VPBB. \p VPBB must be an incoming block.
1666 VPValue *getIncomingValueForBlock(const VPBasicBlock *VPBB) const;
1667
1668 /// Sets the incoming value for \p VPBB to \p V. \p VPBB must be an incoming
1669 /// block.
1670 void setIncomingValueForBlock(const VPBasicBlock *VPBB, VPValue *V) const;
1671
1672 /// Returns the number of incoming values, also number of incoming blocks.
1673 virtual unsigned getNumIncoming() const {
1674 return getAsRecipe()->getNumOperands();
1675 }
1676
1677 /// Returns an interator range over the incoming values.
1679 return make_range(getAsRecipe()->op_begin(),
1680 getAsRecipe()->op_begin() + getNumIncoming());
1681 }
1682
1684 detail::index_iterator, std::function<const VPBasicBlock *(size_t)>>>;
1685
1686 /// Returns an iterator range over the incoming blocks.
1688 std::function<const VPBasicBlock *(size_t)> GetBlock = [this](size_t Idx) {
1689 return getIncomingBlock(Idx);
1690 };
1691 return map_range(index_range(0, getNumIncoming()), GetBlock);
1692 }
1693
1694 /// Returns an iterator range over pairs of incoming values and corresponding
1695 /// incoming blocks.
1701
1702 /// Removes the incoming value for \p IncomingBlock, which must be a
1703 /// predecessor.
1704 void removeIncomingValueFor(VPBlockBase *IncomingBlock) const;
1705
1706 /// Append \p IncomingV as an incoming value to the phi-like recipe.
1707 void addIncoming(VPValue *IncomingV) {
1708 auto *R = const_cast<VPRecipeBase *>(getAsRecipe());
1709 assert((R->getNumOperands() == 0 ||
1710 IncomingV->getScalarType() == R->getOperand(0)->getScalarType()) &&
1711 "all incoming values must have the same type");
1712 R->addOperand(IncomingV);
1713 }
1714
1715#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1716 /// Print the recipe.
1718#endif
1719};
1720
1723 const Twine &Name = "", Type *ResultTy = nullptr)
1724 : VPInstruction(Instruction::PHI, Operands, Flags, {}, DL, Name,
1725 ResultTy) {}
1726
1727 static inline bool classof(const VPUser *U) {
1728 auto *VPI = dyn_cast<VPInstruction>(U);
1729 return VPI && VPI->getOpcode() == Instruction::PHI;
1730 }
1731
1732 static inline bool classof(const VPValue *V) {
1733 auto *VPI = dyn_cast<VPInstruction>(V);
1734 return VPI && VPI->getOpcode() == Instruction::PHI;
1735 }
1736
1737 static inline bool classof(const VPSingleDefRecipe *SDR) {
1738 auto *VPI = dyn_cast<VPInstruction>(SDR);
1739 return VPI && VPI->getOpcode() == Instruction::PHI;
1740 }
1741
1742 VPPhi *clone() override {
1743 auto *PhiR = new VPPhi(operands(), *this, getDebugLoc(), getName());
1744 PhiR->setUnderlyingValue(getUnderlyingValue());
1745 return PhiR;
1746 }
1747
1748 void execute(VPTransformState &State) override;
1749
1750protected:
1751#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1752 /// Print the recipe.
1753 void printRecipe(raw_ostream &O, const Twine &Indent,
1754 VPSlotTracker &SlotTracker) const override;
1755#endif
1756
1757 const VPRecipeBase *getAsRecipe() const override { return this; }
1758};
1759
1760/// A recipe to wrap on original IR instruction not to be modified during
1761/// execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
1762/// Expect PHIs, VPIRInstructions cannot have any operands.
1764 Instruction &I;
1765
1766protected:
1767 /// VPIRInstruction::create() should be used to create VPIRInstructions, as
1768 /// subclasses may need to be created, e.g. VPIRPhi.
1770 : VPRecipeBase(VPRecipeBase::VPIRInstructionSC, {}), I(I) {}
1771
1772public:
1773 ~VPIRInstruction() override = default;
1774
1775 /// Create a new VPIRPhi for \p \I, if it is a PHINode, otherwise create a
1776 /// VPIRInstruction.
1778
1779 VP_CLASSOF_IMPL(VPRecipeBase::VPIRInstructionSC)
1780
1782 auto *R = create(I);
1783 for (auto *Op : operands())
1784 R->addOperand(Op);
1785 return R;
1786 }
1787
1788 void execute(VPTransformState &State) override;
1789
1790 /// Return the cost of this VPIRInstruction.
1792 computeCost(ElementCount VF, VPCostContext &Ctx) const override;
1793
1794 Instruction &getInstruction() const { return I; }
1795
1796 bool usesScalars(const VPValue *Op) const override {
1798 "Op must be an operand of the recipe");
1799 return true;
1800 }
1801
1802 bool usesFirstPartOnly(const VPValue *Op) const override {
1804 "Op must be an operand of the recipe");
1805 return true;
1806 }
1807
1808 bool usesFirstLaneOnly(const VPValue *Op) const override {
1810 "Op must be an operand of the recipe");
1811 return true;
1812 }
1813
1814protected:
1815#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1816 /// Print the recipe.
1817 void printRecipe(raw_ostream &O, const Twine &Indent,
1818 VPSlotTracker &SlotTracker) const override;
1819#endif
1820};
1821
1822/// An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
1823/// cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
1824/// allowed, and it is used to add a new incoming value for the single
1825/// predecessor VPBB.
1827 public VPPhiAccessors {
1829
1830 static inline bool classof(const VPRecipeBase *U) {
1831 auto *R = dyn_cast<VPIRInstruction>(U);
1832 return R && isa<PHINode>(R->getInstruction());
1833 }
1834
1835 static inline bool classof(const VPUser *U) {
1836 auto *R = dyn_cast<VPRecipeBase>(U);
1837 return R && classof(R);
1838 }
1839
1841
1842 void execute(VPTransformState &State) override;
1843
1844protected:
1845#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1846 /// Print the recipe.
1847 void printRecipe(raw_ostream &O, const Twine &Indent,
1848 VPSlotTracker &SlotTracker) const override;
1849#endif
1850
1851 const VPRecipeBase *getAsRecipe() const override { return this; }
1852};
1853
1854/// VPWidenRecipe is a recipe for producing a widened instruction using the
1855/// opcode and operands of the recipe. This recipe covers most of the
1856/// traditional vectorization cases where each recipe transforms into a
1857/// vectorized version of itself.
1859 public VPIRMetadata {
1860 unsigned Opcode;
1861
1862public:
1864 const VPIRFlags &Flags = {}, const VPIRMetadata &Metadata = {},
1865 DebugLoc DL = {})
1866 : VPWidenRecipe(I.getOpcode(), Operands, Flags, Metadata, DL) {
1867 setUnderlyingValue(&I);
1868 }
1869
1871 const VPIRFlags &Flags = {}, const VPIRMetadata &Metadata = {},
1872 DebugLoc DL = {})
1873 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenSC, Operands,
1875 Flags, DL),
1876 VPIRMetadata(Metadata), Opcode(Opcode) {
1877 assert(flagsValidForOpcode(Opcode) &&
1878 "Set flags not supported for the provided opcode");
1879 assert(hasRequiredFlagsForOpcode(Opcode, getScalarType()) &&
1880 "Opcode requires specific flags to be set");
1881 }
1882
1883 ~VPWidenRecipe() override = default;
1884
1886
1888 if (auto *UV = getUnderlyingValue())
1889 return new VPWidenRecipe(*cast<Instruction>(UV), NewOperands, *this,
1890 *this, getDebugLoc());
1891 return new VPWidenRecipe(Opcode, NewOperands, *this, *this, getDebugLoc());
1892 }
1893
1894 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenSC)
1895
1896 /// Produce a widened instruction using the opcode and operands of the recipe,
1897 /// processing State.VF elements.
1898 void execute(VPTransformState &State) override;
1899
1900 /// Return the cost of this VPWidenRecipe.
1901 InstructionCost computeCost(ElementCount VF,
1902 VPCostContext &Ctx) const override;
1903
1904 unsigned getOpcode() const { return Opcode; }
1905
1906protected:
1907#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1908 /// Print the recipe.
1909 void printRecipe(raw_ostream &O, const Twine &Indent,
1910 VPSlotTracker &SlotTracker) const override;
1911#endif
1912
1913 /// Returns true if the recipe only uses the first lane of operand \p Op.
1914 bool usesFirstLaneOnly(const VPValue *Op) const override {
1916 "Op must be an operand of the recipe");
1917 return Opcode == Instruction::Select && Op == getOperand(0) &&
1919 }
1920};
1921
1922/// VPWidenCastRecipe is a recipe to create vector cast instructions.
1923/// TODO: Merge with VPWidenRecipe now that type is associated to every
1924/// VPRecipeValue.
1926 /// Cast instruction opcode.
1927 Instruction::CastOps Opcode;
1928
1929public:
1931 CastInst *CI = nullptr, const VPIRFlags &Flags = {},
1932 const VPIRMetadata &Metadata = {},
1934 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCastSC, Op, ResultTy, Flags,
1935 DL),
1936 VPIRMetadata(Metadata), Opcode(Opcode) {
1937 assert(flagsValidForOpcode(Opcode) &&
1938 "Set flags not supported for the provided opcode");
1939 assert(hasRequiredFlagsForOpcode(Opcode, ResultTy) &&
1940 "Opcode requires specific flags to be set");
1942 }
1943
1944 ~VPWidenCastRecipe() override = default;
1945
1947 return new VPWidenCastRecipe(Opcode, getOperand(0), getScalarType(),
1949 *this, *this, getDebugLoc());
1950 }
1951
1952 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenCastSC)
1953
1954 /// Produce widened copies of the cast.
1955 LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override;
1956
1957 /// Return the cost of this VPWidenCastRecipe.
1959 computeCost(ElementCount VF, VPCostContext &Ctx) const override;
1960
1961 Instruction::CastOps getOpcode() const { return Opcode; }
1962
1963protected:
1964#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1965 /// Print the recipe.
1966 LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent,
1967 VPSlotTracker &SlotTracker) const override;
1968#endif
1969};
1970
1971/// A recipe for widening vector intrinsics.
1973 /// ID of the vector intrinsic to widen.
1974 Intrinsic::ID VectorIntrinsicID;
1975
1976 /// True if the intrinsic may read from memory.
1977 bool MayReadFromMemory;
1978
1979 /// True if the intrinsic may read write to memory.
1980 bool MayWriteToMemory;
1981
1982 /// True if the intrinsic may have side-effects.
1983 bool MayHaveSideEffects;
1984
1985protected:
1987 ArrayRef<VPValue *> CallArguments, Type *Ty,
1988 const VPIRFlags &Flags = {},
1989 const VPIRMetadata &MD = {},
1991 : VPRecipeWithIRFlags(SC, CallArguments, Ty, Flags, DL), VPIRMetadata(MD),
1992 VectorIntrinsicID(VectorIntrinsicID) {
1993 LLVMContext &Ctx = Ty->getContext();
1994 AttributeSet Attrs = Intrinsic::getFnAttributes(Ctx, VectorIntrinsicID);
1995 MemoryEffects ME = Attrs.getMemoryEffects();
1996 MayReadFromMemory = !ME.onlyWritesMemory();
1997 MayWriteToMemory = !ME.onlyReadsMemory();
1998 MayHaveSideEffects = MayWriteToMemory ||
1999 !Attrs.hasAttribute(Attribute::NoUnwind) ||
2000 !Attrs.hasAttribute(Attribute::WillReturn);
2001 }
2002
2003 /// Helper function to produce the widened intrinsic call.
2004 CallInst *createVectorCall(VPTransformState &State);
2005
2006public:
2008 ArrayRef<VPValue *> CallArguments, Type *Ty,
2009 const VPIRFlags &Flags = {},
2010 const VPIRMetadata &MD = {},
2012 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenIntrinsicSC, CallArguments, Ty,
2013 Flags, DL),
2014 VPIRMetadata(MD), VectorIntrinsicID(VectorIntrinsicID),
2015 MayReadFromMemory(CI.mayReadFromMemory()),
2016 MayWriteToMemory(CI.mayWriteToMemory()),
2017 MayHaveSideEffects(CI.mayHaveSideEffects()) {
2018 setUnderlyingValue(&CI);
2019 }
2020
2022 ArrayRef<VPValue *> CallArguments, Type *Ty,
2023 const VPIRFlags &Flags = {},
2024 const VPIRMetadata &Metadata = {},
2026 : VPWidenIntrinsicRecipe(VPRecipeBase::VPWidenIntrinsicSC,
2027 VectorIntrinsicID, CallArguments, Ty, Flags,
2028 Metadata, DL) {}
2029
2030 ~VPWidenIntrinsicRecipe() override = default;
2031
2033 if (Value *CI = getUnderlyingValue())
2034 return new VPWidenIntrinsicRecipe(*cast<CallInst>(CI), VectorIntrinsicID,
2035 operands(), getScalarType(), *this,
2036 *this, getDebugLoc());
2037 return new VPWidenIntrinsicRecipe(VectorIntrinsicID, operands(),
2038 getScalarType(), *this, *this,
2039 getDebugLoc());
2040 }
2041
2042 static inline bool classof(const VPRecipeBase *R) {
2043 return R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
2044 R->getVPRecipeID() == VPRecipeBase::VPWidenMemIntrinsicSC;
2045 }
2046
2047 static inline bool classof(const VPUser *U) {
2048 auto *R = dyn_cast<VPRecipeBase>(U);
2049 return R && classof(R);
2050 }
2051
2052 static inline bool classof(const VPValue *V) {
2053 auto *R = V->getDefiningRecipe();
2054 return R && classof(R);
2055 }
2056
2057 static inline bool classof(const VPSingleDefRecipe *R) {
2058 return classof(static_cast<const VPRecipeBase *>(R));
2059 }
2060
2061 /// Produce a widened version of the vector intrinsic.
2062 LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override;
2063
2064 /// Compute the cost of a vector intrinsic with \p ID and \p Operands.
2067 const VPRecipeWithIRFlags &R,
2068 ElementCount VF, VPCostContext &Ctx);
2069
2070 /// Return the cost of this vector intrinsic.
2072 computeCost(ElementCount VF, VPCostContext &Ctx) const override;
2073
2074 /// Return the ID of the intrinsic.
2075 Intrinsic::ID getVectorIntrinsicID() const { return VectorIntrinsicID; }
2076
2077 /// Return to name of the intrinsic as string.
2079
2080 /// Returns true if the intrinsic may read from memory.
2081 bool mayReadFromMemory() const { return MayReadFromMemory; }
2082
2083 /// Returns true if the intrinsic may write to memory.
2084 bool mayWriteToMemory() const { return MayWriteToMemory; }
2085
2086 /// Returns true if the intrinsic may have side-effects.
2087 bool mayHaveSideEffects() const { return MayHaveSideEffects; }
2088
2089 LLVM_ABI_FOR_TEST bool usesFirstLaneOnly(const VPValue *Op) const override;
2090
2091protected:
2092#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2093 /// Print the recipe.
2094 LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent,
2095 VPSlotTracker &SlotTracker) const override;
2096#endif
2097};
2098
2099/// A recipe for widening vector memory intrinsics.
2101 /// Alignment information for this memory access.
2102 Align Alignment;
2103
2104public:
2106 ArrayRef<VPValue *> CallArguments, Type *Ty,
2107 Align Alignment, const VPIRMetadata &MD = {},
2109 : VPWidenIntrinsicRecipe(VPRecipeBase::VPWidenMemIntrinsicSC,
2110 VectorIntrinsicID, CallArguments, Ty, {}, MD,
2111 DL),
2112 Alignment(Alignment) {
2113 assert((VectorIntrinsicID == Intrinsic::experimental_vp_strided_load ||
2114 VectorIntrinsicID == Intrinsic::experimental_vp_strided_store) &&
2115 "Unexpected intrinsic");
2116 }
2117
2118 ~VPWidenMemIntrinsicRecipe() override = default;
2119
2122 getScalarType(), Alignment, *this,
2123 getDebugLoc());
2124 }
2125
2126 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenMemIntrinsicSC)
2127
2128 /// Produce a widened version of the vector memory intrinsic.
2129 void execute(VPTransformState &State) override;
2130
2131 /// Helper function for computing the cost of vector memory intrinsic.
2133 bool IsMasked, Align Alignment,
2134 VPCostContext &Ctx);
2135
2136 /// Return the cost of this vector memory intrinsic.
2138 VPCostContext &Ctx) const override;
2139};
2140
2141/// A recipe for widening Call instructions using library calls.
2143 public VPIRMetadata {
2144 /// Variant stores a pointer to the chosen function. There is a 1:1 mapping
2145 /// between a given VF and the chosen vectorized variant, so there will be a
2146 /// different VPlan for each VF with a valid variant.
2147 Function *Variant;
2148
2149public:
2151 ArrayRef<VPValue *> CallArguments,
2152 const VPIRFlags &Flags = {},
2153 const VPIRMetadata &Metadata = {}, DebugLoc DL = {})
2154 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCallSC, CallArguments,
2155 toScalarizedTy(Variant->getReturnType()), Flags,
2156 DL),
2157 VPIRMetadata(Metadata), Variant(Variant) {
2158 setUnderlyingValue(UV);
2159 assert(
2160 isa<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue()) &&
2161 "last operand must be the called function");
2162 assert(cast<Function>(CallArguments.back()->getLiveInIRValue())
2163 ->getReturnType() == getScalarType() &&
2164 "Scalar type must match return type of called scalar function");
2165 }
2166
2167 ~VPWidenCallRecipe() override = default;
2168
2170 return new VPWidenCallRecipe(getUnderlyingValue(), Variant, operands(),
2171 *this, *this, getDebugLoc());
2172 }
2173
2174 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenCallSC)
2175
2176 /// Produce a widened version of the call instruction.
2177 void execute(VPTransformState &State) override;
2178
2179 /// Return the cost of this VPWidenCallRecipe.
2180 InstructionCost computeCost(ElementCount VF,
2181 VPCostContext &Ctx) const override;
2182
2183 /// Return the cost of widening a call using the vector function \p Variant.
2184 static InstructionCost computeCallCost(Function *Variant, VPCostContext &Ctx);
2185
2189
2192
2193 /// Returns true if the recipe only uses the first lane of operand \p Op.
2194 bool usesFirstLaneOnly(const VPValue *Op) const override;
2195
2196protected:
2197#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2198 /// Print the recipe.
2199 void printRecipe(raw_ostream &O, const Twine &Indent,
2200 VPSlotTracker &SlotTracker) const override;
2201#endif
2202};
2203
2204/// A recipe representing a sequence of load -> update -> store as part of
2205/// a histogram operation. This means there may be aliasing between vector
2206/// lanes, which is handled by the llvm.experimental.vector.histogram family
2207/// of intrinsics. The only update operations currently supported are
2208/// 'add' and 'sub' where the other term is loop-invariant.
2210 /// Opcode of the update operation, currently either add or sub.
2211 unsigned Opcode;
2212
2213public:
2214 VPHistogramRecipe(unsigned Opcode, ArrayRef<VPValue *> Operands,
2215 const VPIRMetadata &Metadata = {},
2217 : VPRecipeBase(VPRecipeBase::VPHistogramSC, Operands, DL),
2218 VPIRMetadata(Metadata), Opcode(Opcode) {}
2219
2220 ~VPHistogramRecipe() override = default;
2221
2223 return new VPHistogramRecipe(Opcode, operands(), *this, getDebugLoc());
2224 }
2225
2226 VP_CLASSOF_IMPL(VPRecipeBase::VPHistogramSC);
2227
2228 /// Produce a vectorized histogram operation.
2229 void execute(VPTransformState &State) override;
2230
2231 /// Return the cost of this VPHistogramRecipe.
2233 VPCostContext &Ctx) const override;
2234
2235 unsigned getOpcode() const { return Opcode; }
2236
2237 /// Return the mask operand if one was provided, or a null pointer if all
2238 /// lanes should be executed unconditionally.
2239 VPValue *getMask() const {
2240 return getNumOperands() == 3 ? getOperand(2) : nullptr;
2241 }
2242
2243protected:
2244#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2245 /// Print the recipe
2246 void printRecipe(raw_ostream &O, const Twine &Indent,
2247 VPSlotTracker &SlotTracker) const override;
2248#endif
2249};
2250
2251/// A recipe for handling GEP instructions.
2253 Type *SourceElementTy;
2254
2255public:
2257 const VPIRFlags &Flags = {},
2259 GetElementPtrInst *UV = nullptr)
2260 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenGEPSC, Operands,
2261 Operands[0]->getScalarType(), Flags, DL),
2262 SourceElementTy(SourceElementTy) {
2263 if (UV) {
2264 setUnderlyingValue(UV);
2267 assert(Metadata.empty() && "unexpected metadata on GEP");
2268 }
2269 }
2270
2271 ~VPWidenGEPRecipe() override = default;
2272
2278
2279 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenGEPSC)
2280
2281 /// This recipe generates a GEP instruction.
2282 unsigned getOpcode() const { return Instruction::GetElementPtr; }
2283
2284 /// Generate the gep nodes.
2285 void execute(VPTransformState &State) override;
2286
2287 Type *getSourceElementType() const { return SourceElementTy; }
2288
2289 /// Return the cost of this VPWidenGEPRecipe.
2291 VPCostContext &Ctx) const override {
2292 // TODO: Compute accurate cost after retiring the legacy cost model.
2293 return 0;
2294 }
2295
2296 /// Returns true if the recipe only uses the first lane of operand \p Op.
2297 bool usesFirstLaneOnly(const VPValue *Op) const override;
2298
2299protected:
2300#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2301 /// Print the recipe.
2302 void printRecipe(raw_ostream &O, const Twine &Indent,
2303 VPSlotTracker &SlotTracker) const override;
2304#endif
2305};
2306
2307/// A recipe to compute a pointer to the last element of each part of a widened
2308/// memory access for widened memory accesses of SourceElementTy. Used for
2309/// VPWidenMemoryRecipes or VPInterleaveRecipes that are reversed. An extra
2310/// Offset operand is added by convertToConcreteRecipes when UF = 1, and by the
2311/// unroller otherwise.
2313 Type *SourceElementTy;
2314
2315 /// The constant stride of the pointer computed by this recipe, expressed in
2316 /// units of SourceElementTy.
2317 int64_t Stride;
2318
2319public:
2320 VPVectorEndPointerRecipe(VPValue *Ptr, VPValue *VF, Type *SourceElementTy,
2321 int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
2322 : VPRecipeWithIRFlags(VPRecipeBase::VPVectorEndPointerSC, {Ptr, VF},
2323 Ptr->getScalarType(), GEPFlags, DL),
2324 SourceElementTy(SourceElementTy), Stride(Stride) {
2325 assert(Stride < 0 && "Stride must be negative");
2326 }
2327
2328 VP_CLASSOF_IMPL(VPRecipeBase::VPVectorEndPointerSC)
2329
2330 Type *getSourceElementType() const { return SourceElementTy; }
2331 int64_t getStride() const { return Stride; }
2332 VPValue *getPointer() const { return getOperand(0); }
2333 VPValue *getVFValue() const { return getOperand(1); }
2335 return getNumOperands() == 3 ? getOperand(2) : nullptr;
2336 }
2337
2338 /// Adds the offset operand to the recipe.
2339 /// Offset = Stride * (VF - 1) + Part * Stride * VF.
2340 void materializeOffset(unsigned Part = 0);
2341
2342 /// Append \p Offset as the offset operand. The offset is an integer index
2343 /// expressed in units of SourceElementTy.
2345 assert(Offset->getScalarType()->isIntegerTy() &&
2346 "offset must be an integer index");
2348 }
2349
2350 void execute(VPTransformState &State) override;
2351
2352 bool usesFirstLaneOnly(const VPValue *Op) const override {
2354 "Op must be an operand of the recipe");
2355 return true;
2356 }
2357
2358 /// Return the cost of this VPVectorPointerRecipe.
2360 VPCostContext &Ctx) const override {
2361 // TODO: Compute accurate cost after retiring the legacy cost model.
2362 return 0;
2363 }
2364
2365 /// Returns true if the recipe only uses the first part of operand \p Op.
2366 bool usesFirstPartOnly(const VPValue *Op) const override {
2368 "Op must be an operand of the recipe");
2369 assert(getNumOperands() <= 2 && "must have at most two operands");
2370 return true;
2371 }
2372
2374 auto *VEPR = new VPVectorEndPointerRecipe(
2377 if (auto *Offset = getOffset())
2378 VEPR->addOffset(Offset);
2379 return VEPR;
2380 }
2381
2382protected:
2383#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2384 /// Print the recipe.
2385 void printRecipe(raw_ostream &O, const Twine &Indent,
2386 VPSlotTracker &SlotTracker) const override;
2387#endif
2388};
2389
2390/// A recipe to compute the pointers for widened memory accesses of \p
2391/// SourceElementTy, with the \p Stride expressed in units of \p
2392/// SourceElementTy. Unrolling adds an extra \p VFxPart operand for unrolled
2393/// parts > 0 and it produces `GEP SourceElementTy Ptr, VFxPart * Stride`.
2395 Type *SourceElementTy;
2396
2397public:
2398 VPVectorPointerRecipe(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
2399 GEPNoWrapFlags GEPFlags, DebugLoc DL)
2400 : VPRecipeWithIRFlags(VPRecipeBase::VPVectorPointerSC,
2401 ArrayRef<VPValue *>({Ptr, Stride}),
2402 Ptr->getScalarType(), GEPFlags, DL),
2403 SourceElementTy(SourceElementTy) {}
2404
2405 VP_CLASSOF_IMPL(VPRecipeBase::VPVectorPointerSC)
2406
2407 VPValue *getStride() const { return getOperand(1); }
2408
2410 return getNumOperands() > 2 ? getOperand(2) : nullptr;
2411 }
2412
2413 /// Add the per-part offset (VFxPart) used for unrolled parts > 0.
2414 void addPerPartOffset(VPValue *VFxPart) {
2415 assert(VFxPart->getScalarType()->isIntegerTy() &&
2416 "per-part offset must be an integer index");
2417 VPUser::addOperand(VFxPart);
2418 }
2419
2420 void execute(VPTransformState &State) override;
2421
2422 Type *getSourceElementType() const { return SourceElementTy; }
2423
2424 bool usesFirstLaneOnly(const VPValue *Op) const override {
2426 "Op must be an operand of the recipe");
2427 return true;
2428 }
2429
2430 /// Returns true if the recipe only uses the first part of operand \p Op.
2431 bool usesFirstPartOnly(const VPValue *Op) const override {
2433 "Op must be an operand of the recipe");
2434 assert(getNumOperands() <= 2 && "must have at most two operands");
2435 return true;
2436 }
2437
2439 auto *Clone =
2440 new VPVectorPointerRecipe(getOperand(0), SourceElementTy, getStride(),
2442 if (auto *VFxPart = getVFxPart())
2443 Clone->addPerPartOffset(VFxPart);
2444 return Clone;
2445 }
2446
2447 /// Return the cost of this VPHeaderPHIRecipe.
2449 VPCostContext &Ctx) const override {
2450 // TODO: Compute accurate cost after retiring the legacy cost model.
2451 return 0;
2452 }
2453
2454protected:
2455#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2456 /// Print the recipe.
2457 void printRecipe(raw_ostream &O, const Twine &Indent,
2458 VPSlotTracker &SlotTracker) const override;
2459#endif
2460};
2461
2462/// A pure virtual base class for all recipes modeling header phis, including
2463/// phis for first order recurrences, pointer inductions and reductions. The
2464/// start value is the first operand of the recipe and the incoming value from
2465/// the backedge is the second operand.
2466///
2467/// Inductions are modeled using the following sub-classes:
2468/// * VPWidenIntOrFpInductionRecipe: Generates vector values for integer and
2469/// floating point inductions with arbitrary start and step values. Produces
2470/// a vector PHI per-part.
2471/// * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
2472/// pointer induction. Produces either a vector PHI per-part or scalar values
2473/// per-lane based on the canonical induction.
2474/// * VPFirstOrderRecurrencePHIRecipe
2475/// * VPReductionPHIRecipe
2476/// * VPActiveLaneMaskPHIRecipe
2477/// * VPEVLBasedIVPHIRecipe
2478///
2479/// Note that the canonical IV is modeled as a VPRegionValue associated with
2480/// its loop region.
2482 public VPPhiAccessors {
2483protected:
2484 VPHeaderPHIRecipe(VPRecipeTy VPRecipeID, Instruction *UnderlyingInstr,
2485 VPValue *Start, DebugLoc DL = DebugLoc::getUnknown())
2486 : VPHeaderPHIRecipe(VPRecipeID, UnderlyingInstr, Start,
2487 Start->getScalarType(), DL) {}
2488
2489 VPHeaderPHIRecipe(VPRecipeTy VPRecipeID, Instruction *UnderlyingInstr,
2490 VPValue *Start, Type *ResultTy, DebugLoc DL)
2491 : VPSingleDefRecipe(VPRecipeID, Start, ResultTy, UnderlyingInstr, DL) {}
2492
2493 const VPRecipeBase *getAsRecipe() const override { return this; }
2494
2495public:
2496 ~VPHeaderPHIRecipe() override = default;
2497
2498 /// Method to support type inquiry through isa, cast, and dyn_cast.
2499 static inline bool classof(const VPRecipeBase *R) {
2500 return R->getVPRecipeID() >= VPRecipeBase::VPFirstHeaderPHISC &&
2501 R->getVPRecipeID() <= VPRecipeBase::VPLastHeaderPHISC;
2502 }
2503 static inline bool classof(const VPValue *V) {
2504 return isa<VPHeaderPHIRecipe>(V->getDefiningRecipe());
2505 }
2506 static inline bool classof(const VPSingleDefRecipe *R) {
2507 return isa<VPHeaderPHIRecipe>(static_cast<const VPRecipeBase *>(R));
2508 }
2509
2510 /// Generate the phi nodes.
2511 void execute(VPTransformState &State) override = 0;
2512
2513 /// Return the cost of this header phi recipe.
2515 VPCostContext &Ctx) const override;
2516
2517 /// Returns the start value of the phi, if one is set.
2519 return getNumOperands() == 0 ? nullptr : getOperand(0);
2520 }
2522 return getNumOperands() == 0 ? nullptr : getOperand(0);
2523 }
2524
2525 /// Update the start value of the recipe.
2527
2528 /// Returns the incoming value from the loop backedge.
2529 virtual VPValue *getBackedgeValue() { return getOperand(1); }
2530
2531 /// Update the incoming value from the loop backedge.
2533
2534 /// Add \p V as the incoming value from the loop backedge.
2536 assert(getNumOperands() == 1 &&
2537 "backedge value must be appended right after construction");
2538 assert(V->getScalarType() == getScalarType() &&
2539 "backedge value must have the same type as the start value");
2541 }
2542
2543protected:
2544#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2545 /// Print the recipe.
2546 void printRecipe(raw_ostream &O, const Twine &Indent,
2547 VPSlotTracker &SlotTracker) const override = 0;
2548#endif
2549};
2550
2551/// Base class for widened induction (VPWidenIntOrFpInductionRecipe and
2552/// VPWidenPointerInductionRecipe), providing shared functionality, including
2553/// retrieving the step value, induction descriptor and original phi node.
2555 InductionDescriptor IndDesc;
2556
2557public:
2559 VPValue *Step, const InductionDescriptor &IndDesc,
2560 DebugLoc DL)
2561 : VPWidenInductionRecipe(Kind, IV, Start, Step, IndDesc,
2562 Start->getScalarType(), DL) {}
2563
2565 VPValue *Step, const InductionDescriptor &IndDesc,
2566 Type *ResultTy, DebugLoc DL)
2567 : VPHeaderPHIRecipe(Kind, IV, Start, ResultTy, DL), IndDesc(IndDesc) {
2568 addOperand(Step);
2569 }
2570
2571 /// After unrolling, append the splat-VF step (`VF * step`) and the value of
2572 /// the induction at the last unrolled part.
2573 void addUnrolledPartOperands(VPValue *SplatVFStep, VPValue *LastPart) {
2574 assert(LastPart->getScalarType() == getScalarType() &&
2575 "last-part value must match the induction recipe's scalar type");
2577 ? SplatVFStep->getScalarType()->isIntegerTy()
2578 : SplatVFStep->getScalarType() == getScalarType()) &&
2579 "splat-step must match the induction type for non-pointer "
2580 "inductions, or be an integer index for pointer inductions");
2581 VPUser::addOperand(SplatVFStep);
2582 VPUser::addOperand(LastPart);
2583 }
2584
2585 static inline bool classof(const VPRecipeBase *R) {
2586 return R->getVPRecipeID() == VPRecipeBase::VPWidenIntOrFpInductionSC ||
2587 R->getVPRecipeID() == VPRecipeBase::VPWidenPointerInductionSC;
2588 }
2589
2590 static inline bool classof(const VPValue *V) {
2591 auto *R = V->getDefiningRecipe();
2592 return R && classof(R);
2593 }
2594
2595 static inline bool classof(const VPSingleDefRecipe *R) {
2596 return classof(static_cast<const VPRecipeBase *>(R));
2597 }
2598
2599 void execute(VPTransformState &State) override = 0;
2600
2601 /// Returns the start value of the induction.
2602 VPValue *getStartValue() const { return getOperand(0); }
2603
2604 /// Returns the step value of the induction.
2606 const VPValue *getStepValue() const { return getOperand(1); }
2607
2608 /// Update the step value of the recipe.
2609 void setStepValue(VPValue *V) { setOperand(1, V); }
2610
2612 const VPValue *getVFValue() const { return getOperand(2); }
2613
2614 /// Returns the number of incoming values, also number of incoming blocks.
2615 /// Note that at the moment, VPWidenPointerInductionRecipe only has a single
2616 /// incoming value, its start value.
2617 unsigned getNumIncoming() const override { return 1; }
2618
2619 /// Returns the underlying PHINode if one exists, or null otherwise.
2623
2624 /// Returns the induction descriptor for the recipe.
2625 const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2626
2627 /// Returns the SCEV predicates associated with this induction.
2629 return IndDesc.getNoWrapPredicates();
2630 }
2631
2633 // TODO: All operands of base recipe must exist and be at same index in
2634 // derived recipe.
2636 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2637 }
2638
2639 /// Returns true if the recipe only uses the first lane of operand \p Op.
2640 bool usesFirstLaneOnly(const VPValue *Op) const override {
2642 "Op must be an operand of the recipe");
2643 // The recipe creates its own wide start value, so it only requests the
2644 // first lane of the operand.
2645 // TODO: Remove once creating the start value is modeled separately.
2646 return Op == getStartValue() || Op == getStepValue();
2647 }
2648};
2649
2650/// A recipe for handling phi nodes of integer and floating-point inductions,
2651/// producing their vector values. This is an abstract recipe and must be
2652/// converted to concrete recipes before executing.
2654 public VPIRFlags {
2655 TruncInst *Trunc;
2656
2657 // If this recipe is unrolled it will have 2 additional operands.
2658 bool isUnrolled() const { return getNumOperands() == 5; }
2659
2660public:
2662 VPValue *VF, const InductionDescriptor &IndDesc,
2663 const VPIRFlags &Flags, DebugLoc DL)
2664 : VPWidenInductionRecipe(VPRecipeBase::VPWidenIntOrFpInductionSC, IV,
2665 Start, Step, IndDesc, DL),
2666 VPIRFlags(Flags), Trunc(nullptr) {
2667 addOperand(VF);
2668 }
2669
2671 VPValue *VF, const InductionDescriptor &IndDesc,
2672 TruncInst *Trunc, const VPIRFlags &Flags,
2673 DebugLoc DL)
2675 VPRecipeBase::VPWidenIntOrFpInductionSC, IV, Start, Step, IndDesc,
2676 Trunc ? Trunc->getType() : Start->getScalarType(), DL),
2677 VPIRFlags(Flags), Trunc(Trunc) {
2678 addOperand(VF);
2680 if (Trunc)
2682 assert(Metadata.empty() && "unexpected metadata on Trunc");
2683 }
2684
2686
2692
2693 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenIntOrFpInductionSC)
2694
2695 void execute(VPTransformState &State) override {
2696 llvm_unreachable("cannot execute this recipe, should be expanded via "
2697 "expandVPWidenIntOrFpInductionRecipe");
2698 }
2699
2700 /// If the recipe has been unrolled, return the VPValue for the induction
2701 /// increment, otherwise return null.
2703 return isUnrolled() ? getOperand(getNumOperands() - 2) : nullptr;
2704 }
2705
2706 /// Returns the number of incoming values, also number of incoming blocks.
2707 /// Note that at the moment, VPWidenIntOrFpInductionRecipes only have a single
2708 /// incoming value, its start value.
2709 unsigned getNumIncoming() const override { return 1; }
2710
2711 /// Returns the first defined value as TruncInst, if it is one or nullptr
2712 /// otherwise.
2713 TruncInst *getTruncInst() { return Trunc; }
2714 const TruncInst *getTruncInst() const { return Trunc; }
2715
2716 /// Return the cost of this VPWidenIntOrFpInductionRecipe.
2718 VPCostContext &Ctx) const override;
2719
2720 /// Returns true if the induction is canonical, i.e. starting at 0 and
2721 /// incremented by UF * VF (= the original IV is incremented by 1) and has the
2722 /// same type as the canonical induction.
2723 bool isCanonical() const;
2724
2725 /// Returns the VPValue representing the value of this induction at
2726 /// the last unrolled part, if it exists. Returns itself if unrolling did not
2727 /// take place.
2729 return isUnrolled() ? getOperand(getNumOperands() - 1) : this;
2730 }
2731
2732protected:
2733#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2734 /// Print the recipe.
2735 void printRecipe(raw_ostream &O, const Twine &Indent,
2736 VPSlotTracker &SlotTracker) const override;
2737#endif
2738};
2739
2741public:
2742 /// Create a new VPWidenPointerInductionRecipe for \p Phi with start value \p
2743 /// Start and the number of elements unrolled \p NumUnrolledElems, typically
2744 /// VF*UF.
2746 VPValue *NumUnrolledElems,
2747 const InductionDescriptor &IndDesc, DebugLoc DL)
2748 : VPWidenInductionRecipe(VPRecipeBase::VPWidenPointerInductionSC, Phi,
2749 Start, Step, IndDesc, DL) {
2750 addOperand(NumUnrolledElems);
2751 }
2752
2754
2760
2761 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenPointerInductionSC)
2762
2763 /// Generate vector values for the pointer induction.
2764 void execute(VPTransformState &State) override {
2765 llvm_unreachable("cannot execute this recipe, should be expanded via "
2766 "expandVPWidenPointerInduction");
2767 };
2768
2769 /// Returns true if only scalar values will be generated.
2770 bool onlyScalarsGenerated(bool IsScalable);
2771
2772protected:
2773#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2774 /// Print the recipe.
2775 void printRecipe(raw_ostream &O, const Twine &Indent,
2776 VPSlotTracker &SlotTracker) const override;
2777#endif
2778};
2779
2780/// A recipe for widened phis. Incoming values are operands of the recipe and
2781/// their operand index corresponds to the incoming predecessor block. If the
2782/// recipe is placed in an entry block to a (non-replicate) region, it must have
2783/// exactly 2 incoming values, the first from the predecessor of the region and
2784/// the second from the exiting block of the region.
2786 public VPPhiAccessors {
2787 /// Name to use for the generated IR instruction for the widened phi.
2788 std::string Name;
2789
2790public:
2791 /// Create a new VPWidenPHIRecipe with incoming values \p IncomingValues,
2792 /// debug location \p DL and \p Name.
2794 DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "")
2795 : VPSingleDefRecipe(VPRecipeBase::VPWidenPHISC, IncomingValues,
2796 IncomingValues[0]->getScalarType(),
2797 /*UV=*/nullptr, DL),
2798 Name(Name.str()) {
2799 assert(all_of(IncomingValues,
2800 [this](VPValue *VPV) {
2801 return VPV->getScalarType() == getScalarType();
2802 }) &&
2803 "all incoming values must have the same type");
2804 }
2805
2807 return new VPWidenPHIRecipe(operands(), getDebugLoc(), Name);
2808 }
2809
2810 ~VPWidenPHIRecipe() override = default;
2811
2812 /// This recipe generates a PHI.
2813 unsigned getOpcode() const { return Instruction::PHI; }
2814
2815 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenPHISC)
2816
2817 /// Generate the phi/select nodes.
2818 void execute(VPTransformState &State) override;
2819
2820 /// Return the cost of this VPWidenPHIRecipe.
2821 InstructionCost computeCost(ElementCount VF,
2822 VPCostContext &Ctx) const override;
2823
2824protected:
2825#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2826 /// Print the recipe.
2827 void printRecipe(raw_ostream &O, const Twine &Indent,
2828 VPSlotTracker &SlotTracker) const override;
2829#endif
2830
2831 const VPRecipeBase *getAsRecipe() const override { return this; }
2832};
2833
2834/// A recipe for handling first-order recurrence phis. The start value is the
2835/// first operand of the recipe and the incoming value from the backedge is the
2836/// second operand.
2839 VPValue &BackedgeValue)
2840 : VPHeaderPHIRecipe(VPRecipeBase::VPFirstOrderRecurrencePHISC, Phi,
2841 &Start) {
2842 addOperand(&BackedgeValue);
2843 }
2844
2845 VP_CLASSOF_IMPL(VPRecipeBase::VPFirstOrderRecurrencePHISC)
2846
2851
2852 void execute(VPTransformState &State) override;
2853
2854 /// Return the cost of this first-order recurrence phi recipe.
2856 VPCostContext &Ctx) const override;
2857
2858 /// Returns true if the recipe only uses the first lane of operand \p Op.
2859 bool usesFirstLaneOnly(const VPValue *Op) const override {
2861 "Op must be an operand of the recipe");
2862 return Op == getStartValue();
2863 }
2864
2865protected:
2866#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2867 /// Print the recipe.
2868 void printRecipe(raw_ostream &O, const Twine &Indent,
2869 VPSlotTracker &SlotTracker) const override;
2870#endif
2871};
2872
2873/// Possible variants of a reduction.
2874
2875/// This reduction is ordered and in-loop.
2876struct RdxOrdered {};
2877/// This reduction is in-loop.
2878struct RdxInLoop {};
2879/// This reduction is unordered with the partial result scaled down by some
2880/// factor.
2883};
2884using ReductionStyle = std::variant<RdxOrdered, RdxInLoop, RdxUnordered>;
2885
2886inline ReductionStyle getReductionStyle(bool InLoop, bool Ordered,
2887 unsigned ScaleFactor) {
2888 assert((!Ordered || InLoop) && "Ordered implies in-loop");
2889 if (Ordered)
2890 return RdxOrdered{};
2891 if (InLoop)
2892 return RdxInLoop{};
2893 return RdxUnordered{/*VFScaleFactor=*/ScaleFactor};
2894}
2895
2896/// A recipe for handling reduction phis. The start value is the first operand
2897/// of the recipe and the incoming value from the backedge is the second
2898/// operand.
2900 /// The recurrence kind of the reduction.
2901 const RecurKind Kind;
2902
2903 ReductionStyle Style;
2904
2905 /// The phi is part of a multi-use reduction (e.g., used in FindIV
2906 /// patterns for argmin/argmax).
2907 /// TODO: Also support cases where the phi itself has a single use, but its
2908 /// compare has multiple uses.
2909 bool HasUsesOutsideReductionChain;
2910
2911public:
2912 /// Create a new VPReductionPHIRecipe for the reduction \p Phi.
2914 VPValue &BackedgeValue, ReductionStyle Style,
2915 const VPIRFlags &Flags,
2916 bool HasUsesOutsideReductionChain = false)
2917 : VPHeaderPHIRecipe(VPRecipeBase::VPReductionPHISC, Phi, &Start),
2918 VPIRFlags(Flags), Kind(Kind), Style(Style),
2919 HasUsesOutsideReductionChain(HasUsesOutsideReductionChain) {
2920 addOperand(&BackedgeValue);
2921 }
2922
2923 ~VPReductionPHIRecipe() override = default;
2924
2926 VPValue *BackedgeValue) {
2927 return new VPReductionPHIRecipe(
2929 *Start, *BackedgeValue, Style, *this, HasUsesOutsideReductionChain);
2930 }
2931
2935
2936 VP_CLASSOF_IMPL(VPRecipeBase::VPReductionPHISC)
2937
2938 /// Generate the phi/select nodes.
2939 void execute(VPTransformState &State) override;
2940
2941 /// Get the factor that the VF of this recipe's output should be scaled by, or
2942 /// 1 if it isn't scaled.
2943 unsigned getVFScaleFactor() const {
2944 auto *Partial = std::get_if<RdxUnordered>(&Style);
2945 return Partial ? Partial->VFScaleFactor : 1;
2946 }
2947
2948 /// Set the VFScaleFactor for this reduction phi. Can only be set to a factor
2949 /// > 1.
2950 void setVFScaleFactor(unsigned ScaleFactor) {
2951 assert(ScaleFactor > 1 && "must set to scale factor > 1");
2952 Style = RdxUnordered{ScaleFactor};
2953 }
2954
2955 /// Returns the recurrence kind of the reduction.
2956 RecurKind getRecurrenceKind() const { return Kind; }
2957
2958 /// Returns true, if the phi is part of an ordered reduction.
2959 bool isOrdered() const { return std::holds_alternative<RdxOrdered>(Style); }
2960
2961 /// Returns true if the phi is part of an in-loop reduction.
2962 bool isInLoop() const {
2963 return std::holds_alternative<RdxInLoop>(Style) ||
2964 std::holds_alternative<RdxOrdered>(Style);
2965 }
2966
2967 /// Returns true if the reduction outputs a vector with a scaled down VF.
2968 bool isPartialReduction() const { return getVFScaleFactor() > 1; }
2969
2970 /// Returns true, if the phi is part of a multi-use reduction.
2972 return HasUsesOutsideReductionChain;
2973 }
2974
2975 /// Returns true if the recipe only uses the first lane of operand \p Op.
2976 bool usesFirstLaneOnly(const VPValue *Op) const override {
2978 "Op must be an operand of the recipe");
2979 return isOrdered() || isInLoop();
2980 }
2981
2982protected:
2983#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2984 /// Print the recipe.
2985 void printRecipe(raw_ostream &O, const Twine &Indent,
2986 VPSlotTracker &SlotTracker) const override;
2987#endif
2988};
2989
2990/// A recipe for vectorizing a phi-node as a sequence of mask-based select
2991/// instructions.
2993public:
2994 /// The blend operation is a User of the incoming values and of their
2995 /// respective masks, ordered [I0, M0, I1, M1, I2, M2, ...]. Note that M0 can
2996 /// be omitted (implied by passing an odd number of operands) in which case
2997 /// all other incoming values are merged into it.
2999 const VPIRFlags &Flags, DebugLoc DL)
3001 Operands[0]->getScalarType(), Flags, DL) {
3002 assert(Operands.size() >= 2 && "Expected at least two operands!");
3004 [this](unsigned I) {
3005 return getIncomingValue(I)->getScalarType() ==
3006 getScalarType();
3007 }) &&
3008 "all incoming values must have the same type");
3010 [this](unsigned I) {
3011 return getMask(I)->getScalarType()->isIntegerTy(1);
3012 }) &&
3013 "masks must be a bool");
3014 assert(hasRequiredFlagsForOpcode(Instruction::PHI, getScalarType()) &&
3015 "blends require the flags of the phi they replace");
3016 setUnderlyingValue(Phi);
3017 }
3018
3020
3023 NewOperands, *this, getDebugLoc());
3024 }
3025
3026 VP_CLASSOF_IMPL(VPRecipeBase::VPBlendSC)
3027
3028 /// A normalized blend is one that has an odd number of operands, whereby the
3029 /// first operand does not have an associated mask.
3030 bool isNormalized() const { return getNumOperands() % 2; }
3031
3032 /// Return the number of incoming values, taking into account when normalized
3033 /// the first incoming value will have no mask.
3034 unsigned getNumIncomingValues() const {
3035 return (getNumOperands() + isNormalized()) / 2;
3036 }
3037
3038 /// Return incoming value number \p Idx.
3039 VPValue *getIncomingValue(unsigned Idx) const {
3040 return Idx == 0 ? getOperand(0) : getOperand(Idx * 2 - isNormalized());
3041 }
3042
3043 /// Return mask number \p Idx.
3044 VPValue *getMask(unsigned Idx) const {
3045 assert((Idx > 0 || !isNormalized()) && "First index has no mask!");
3046 return Idx == 0 ? getOperand(1) : getOperand(Idx * 2 + !isNormalized());
3047 }
3048
3049 /// Set mask number \p Idx to \p V.
3050 void setMask(unsigned Idx, VPValue *V) {
3051 assert((Idx > 0 || !isNormalized()) && "First index has no mask!");
3052 assert(V->getScalarType()->isIntegerTy(1) && "Mask must be an i1 (vector)");
3053 Idx == 0 ? setOperand(1, V) : setOperand(Idx * 2 + !isNormalized(), V);
3054 }
3055
3056 void execute(VPTransformState &State) override {
3057 llvm_unreachable("VPBlendRecipe should be expanded by simplifyBlends");
3058 }
3059
3060 /// Return the cost of this VPWidenMemoryRecipe.
3061 InstructionCost computeCost(ElementCount VF,
3062 VPCostContext &Ctx) const override;
3063
3064 /// Returns true if the recipe only uses the first lane of operand \p Op.
3065 bool usesFirstLaneOnly(const VPValue *Op) const override;
3066
3067protected:
3068#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3069 /// Print the recipe.
3070 void printRecipe(raw_ostream &O, const Twine &Indent,
3071 VPSlotTracker &SlotTracker) const override;
3072#endif
3073};
3074
3075/// A common base class for interleaved memory operations.
3076/// An Interleaved memory operation is a memory access method that combines
3077/// multiple strided loads/stores into a single wide load/store with shuffles.
3078/// The first operand is the start address. The optional operands are, in order,
3079/// the stored values and the mask.
3081 public VPIRMetadata {
3083
3084 /// Indicates if the interleave group is in a conditional block and requires a
3085 /// mask.
3086 bool HasMask = false;
3087
3088 /// Indicates if gaps between members of the group need to be masked out or if
3089 /// unusued gaps can be loaded speculatively.
3090 bool NeedsMaskForGaps = false;
3091
3092protected:
3094 ArrayRef<VPValue *> Operands,
3095 ArrayRef<VPValue *> StoredValues, VPValue *Mask,
3096 bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
3097 : VPRecipeBase(SC, Operands, DL), VPIRMetadata(MD), IG(IG),
3098 NeedsMaskForGaps(NeedsMaskForGaps) {
3099 // TODO: extend the masked interleaved-group support to reversed access.
3100 assert((!Mask || !IG->isReverse()) &&
3101 "Reversed masked interleave-group not supported.");
3102 if (StoredValues.empty()) {
3103 for (Instruction *Inst : IG->members()) {
3104 assert(!Inst->getType()->isVoidTy() && "must have result");
3105 new VPMultiDefValue(this, Inst, Inst->getType());
3106 }
3107 } else {
3108 for (auto *SV : StoredValues)
3109 addOperand(SV);
3110 }
3111 if (Mask) {
3112 HasMask = true;
3113 addOperand(Mask);
3114 }
3115 }
3116
3117public:
3118 VPInterleaveBase *clone() override = 0;
3119
3120 static inline bool classof(const VPRecipeBase *R) {
3121 return R->getVPRecipeID() == VPRecipeBase::VPInterleaveSC ||
3122 R->getVPRecipeID() == VPRecipeBase::VPInterleaveEVLSC;
3123 }
3124
3125 static inline bool classof(const VPUser *U) {
3126 auto *R = dyn_cast<VPRecipeBase>(U);
3127 return R && classof(R);
3128 }
3129
3130 /// Return the address accessed by this recipe.
3131 VPValue *getAddr() const {
3132 return getOperand(0); // Address is the 1st, mandatory operand.
3133 }
3134
3135 /// Return the mask used by this recipe. Note that a full mask is represented
3136 /// by a nullptr.
3137 VPValue *getMask() const {
3138 // Mask is optional and the last operand.
3139 return HasMask ? getOperand(getNumOperands() - 1) : nullptr;
3140 }
3141
3142 /// Return true if the access needs a mask because of the gaps.
3143 bool needsMaskForGaps() const { return NeedsMaskForGaps; }
3144
3146
3147 Instruction *getInsertPos() const { return IG->getInsertPos(); }
3148
3149 void execute(VPTransformState &State) override {
3150 llvm_unreachable("VPInterleaveBase should not be instantiated.");
3151 }
3152
3153 /// Return the cost of this recipe.
3154 InstructionCost computeCost(ElementCount VF,
3155 VPCostContext &Ctx) const override;
3156
3157 /// Returns true if the recipe only uses the first lane of operand \p Op.
3158 bool usesFirstLaneOnly(const VPValue *Op) const override = 0;
3159
3160 /// Returns the number of stored operands of this interleave group. Returns 0
3161 /// for load interleave groups.
3162 virtual unsigned getNumStoreOperands() const = 0;
3163
3164 /// Return the VPValues stored by this interleave group. If it is a load
3165 /// interleave group, return an empty ArrayRef.
3167 return {op_end() - (getNumStoreOperands() + (HasMask ? 1 : 0)),
3169 }
3170};
3171
3172/// VPInterleaveRecipe is a recipe for transforming an interleave group of load
3173/// or stores into one wide load/store and shuffles. The first operand of a
3174/// VPInterleave recipe is the address, followed by the stored values, followed
3175/// by an optional mask.
3177public:
3179 ArrayRef<VPValue *> StoredValues, VPValue *Mask,
3180 bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
3181 : VPInterleaveBase(VPRecipeBase::VPInterleaveSC, IG, Addr, StoredValues,
3182 Mask, NeedsMaskForGaps, MD, DL) {}
3183
3184 ~VPInterleaveRecipe() override = default;
3185
3189 needsMaskForGaps(), *this, getDebugLoc());
3190 }
3191
3192 VP_CLASSOF_IMPL(VPRecipeBase::VPInterleaveSC)
3193
3194 /// Generate the wide load or store, and shuffles.
3195 void execute(VPTransformState &State) override;
3196
3197 bool usesFirstLaneOnly(const VPValue *Op) const override {
3199 "Op must be an operand of the recipe");
3200 return Op == getAddr() && !llvm::is_contained(getStoredValues(), Op);
3201 }
3202
3203 unsigned getNumStoreOperands() const override {
3204 return getNumOperands() - (getMask() ? 2 : 1);
3205 }
3206
3207protected:
3208#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3209 /// Print the recipe.
3210 void printRecipe(raw_ostream &O, const Twine &Indent,
3211 VPSlotTracker &SlotTracker) const override;
3212#endif
3213};
3214
3215/// A recipe for interleaved memory operations with vector-predication
3216/// intrinsics. The first operand is the address, the second operand is the
3217/// explicit vector length. Stored values and mask are optional operands.
3219public:
3221 : VPInterleaveBase(VPRecipeBase::VPInterleaveEVLSC,
3222 R.getInterleaveGroup(), {R.getAddr(), &EVL},
3223 R.getStoredValues(), Mask, R.needsMaskForGaps(), R,
3224 R.getDebugLoc()) {
3225 assert(!getInterleaveGroup()->isReverse() &&
3226 "Reversed interleave-group with tail folding is not supported.");
3227 assert(!needsMaskForGaps() && "Interleaved access with gap mask is not "
3228 "supported for scalable vector.");
3229 }
3230
3231 ~VPInterleaveEVLRecipe() override = default;
3232
3234 llvm_unreachable("cloning not implemented yet");
3235 }
3236
3237 VP_CLASSOF_IMPL(VPRecipeBase::VPInterleaveEVLSC)
3238
3239 /// The VPValue of the explicit vector length.
3240 VPValue *getEVL() const { return getOperand(1); }
3241
3242 /// Generate the wide load or store, and shuffles.
3243 void execute(VPTransformState &State) override;
3244
3245 /// The recipe only uses the first lane of the address, and EVL operand.
3246 bool usesFirstLaneOnly(const VPValue *Op) const override {
3248 "Op must be an operand of the recipe");
3249 return (Op == getAddr() && !llvm::is_contained(getStoredValues(), Op)) ||
3250 Op == getEVL();
3251 }
3252
3253 unsigned getNumStoreOperands() const override {
3254 return getNumOperands() - (getMask() ? 3 : 2);
3255 }
3256
3257protected:
3258#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3259 /// Print the recipe.
3260 void printRecipe(raw_ostream &O, const Twine &Indent,
3261 VPSlotTracker &SlotTracker) const override;
3262#endif
3263};
3264
3265/// A recipe to represent inloop, ordered or partial reduction operations. It
3266/// performs a reduction on a vector operand into a scalar (vector in the case
3267/// of a partial reduction) value, and adds the result to a chain. The Operands
3268/// are {ChainOp, VecOp, [Condition]}.
3270
3271 /// The recurrence kind for the reduction in question.
3272 RecurKind RdxKind;
3273 /// Whether the reduction is conditional.
3274 bool IsConditional = false;
3275 ReductionStyle Style;
3276
3277protected:
3280 VPValue *CondOp, ReductionStyle Style, DebugLoc DL)
3282 DL),
3283 RdxKind(RdxKind), Style(Style) {
3285 [this](VPValue *VPV) {
3286 return VPV->getScalarType() == getScalarType() ||
3287 (isa<VPInstruction>(VPV) &&
3288 cast<VPInstruction>(VPV)->getOpcode() ==
3290 }) &&
3291 "all incoming values must have the same type");
3292 if (CondOp) {
3293 assert(CondOp->getScalarType()->isIntegerTy(1) &&
3294 "CondOp must be a bool");
3295 IsConditional = true;
3296 addOperand(CondOp);
3297 }
3299 }
3300
3301public:
3303 VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp,
3305 : VPReductionRecipe(VPRecipeBase::VPReductionSC, RdxKind, FMFs, I,
3306 {ChainOp, VecOp}, CondOp, Style, DL) {}
3307
3309 VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp,
3311 : VPReductionRecipe(VPRecipeBase::VPReductionSC, RdxKind, FMFs, nullptr,
3312 {ChainOp, VecOp}, CondOp, Style, DL) {}
3313
3314 ~VPReductionRecipe() override = default;
3315
3317 return new VPReductionRecipe(RdxKind, getFastMathFlagsOrNone(),
3319 getCondOp(), Style, getDebugLoc());
3320 }
3321
3322 static inline bool classof(const VPRecipeBase *R) {
3323 return R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
3324 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC;
3325 }
3326
3327 static inline bool classof(const VPUser *U) {
3328 auto *R = dyn_cast<VPRecipeBase>(U);
3329 return R && classof(R);
3330 }
3331
3332 static inline bool classof(const VPValue *VPV) {
3333 const VPRecipeBase *R = VPV->getDefiningRecipe();
3334 return R && classof(R);
3335 }
3336
3337 static inline bool classof(const VPSingleDefRecipe *R) {
3338 return classof(static_cast<const VPRecipeBase *>(R));
3339 }
3340
3341 /// Generate the reduction in the loop.
3342 void execute(VPTransformState &State) override;
3343
3344 /// Return the cost of VPReductionRecipe.
3345 InstructionCost computeCost(ElementCount VF,
3346 VPCostContext &Ctx) const override;
3347
3348 /// Return the recurrence kind for the in-loop reduction.
3349 RecurKind getRecurrenceKind() const { return RdxKind; }
3350 /// Return true if the in-loop reduction is ordered.
3351 bool isOrdered() const { return std::holds_alternative<RdxOrdered>(Style); };
3352 /// Return true if the in-loop reduction is conditional.
3353 bool isConditional() const { return IsConditional; };
3354 /// Returns true if the reduction outputs a vector with a scaled down VF.
3355 bool isPartialReduction() const {
3356 return std::holds_alternative<RdxUnordered>(Style);
3357 }
3358 /// Returns true if the reduction is in-loop.
3359 bool isInLoop() const {
3360 return std::holds_alternative<RdxInLoop>(Style) ||
3361 std::holds_alternative<RdxOrdered>(Style);
3362 }
3363 /// The VPValue of the scalar Chain being accumulated.
3364 VPValue *getChainOp() const { return getOperand(0); }
3365 /// The VPValue of the vector value to be reduced.
3366 VPValue *getVecOp() const { return getOperand(1); }
3367 /// The VPValue of the condition for the block.
3369 return isConditional() ? getOperand(getNumOperands() - 1) : nullptr;
3370 }
3371 /// Get the factor that the VF of this recipe's output should be scaled by, or
3372 /// 1 if it isn't scaled.
3373 unsigned getVFScaleFactor() const {
3374 auto *Partial = std::get_if<RdxUnordered>(&Style);
3375 return Partial ? Partial->VFScaleFactor : 1;
3376 }
3377
3378protected:
3379#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3380 /// Print the recipe.
3381 void printRecipe(raw_ostream &O, const Twine &Indent,
3382 VPSlotTracker &SlotTracker) const override;
3383#endif
3384};
3385
3386/// A recipe to represent inloop reduction operations with vector-predication
3387/// intrinsics, performing a reduction on a vector operand with the explicit
3388/// vector length (EVL) into a scalar value, and adding the result to a chain.
3389/// The Operands are {ChainOp, VecOp, EVL, [Condition]}.
3391public:
3394 : VPReductionRecipe(VPRecipeBase::VPReductionEVLSC, R.getRecurrenceKind(),
3397 {R.getChainOp(), R.getVecOp(), &EVL}, CondOp,
3398 getReductionStyle(R.isInLoop(), R.isOrdered(),
3399 R.getVFScaleFactor()),
3400 DL) {}
3401
3402 ~VPReductionEVLRecipe() override = default;
3403
3405 llvm_unreachable("cloning not implemented yet");
3406 }
3407
3408 VP_CLASSOF_IMPL(VPRecipeBase::VPReductionEVLSC)
3409
3410 /// Generate the reduction in the loop
3411 void execute(VPTransformState &State) override;
3412
3413 /// The VPValue of the explicit vector length.
3414 VPValue *getEVL() const { return getOperand(2); }
3415
3416 /// Returns true if the recipe only uses the first lane of operand \p Op.
3417 bool usesFirstLaneOnly(const VPValue *Op) const override {
3419 "Op must be an operand of the recipe");
3420 return Op == getEVL();
3421 }
3422
3423protected:
3424#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3425 /// Print the recipe.
3426 void printRecipe(raw_ostream &O, const Twine &Indent,
3427 VPSlotTracker &SlotTracker) const override;
3428#endif
3429};
3430
3431/// VPReplicateRecipe replicates a given instruction producing multiple scalar
3432/// copies of the original scalar type, one per lane, instead of producing a
3433/// single copy of widened type for all lanes. If the instruction is known to be
3434/// a single scalar, only one copy will be generated.
3436 public VPIRMetadata {
3437 /// Indicator if only a single replica per lane is needed.
3438 bool IsSingleScalar;
3439
3440 /// Indicator if the replicas are also predicated.
3441 bool IsPredicated;
3442
3443public:
3445 bool IsSingleScalar, VPValue *Mask = nullptr,
3446 const VPIRFlags &Flags = {}, VPIRMetadata Metadata = {},
3447 DebugLoc DL = DebugLoc::getUnknown())
3448 : VPRecipeWithIRFlags(VPRecipeBase::VPReplicateSC, Operands,
3449 computeScalarType(I, Operands), Flags, DL),
3450 VPIRMetadata(Metadata), IsSingleScalar(IsSingleScalar),
3451 IsPredicated(Mask) {
3452 assert((!IsSingleScalar || !I->isCast()) &&
3453 "single-scalar casts should use VPInstructionWithType");
3454 setUnderlyingValue(I);
3455 if (Mask)
3456 addOperand(Mask);
3457 }
3458
3459 ~VPReplicateRecipe() override = default;
3460
3461 /// Compute the scalar result type for a VPReplicateRecipe wrapping \p I with
3462 /// \p Operands (excluding any predicate mask).
3463 static Type *computeScalarType(const Instruction *I,
3465
3467
3469 auto *Copy = new VPReplicateRecipe(
3470 getUnderlyingInstr(), NewOperands, IsSingleScalar,
3471 isPredicated() ? getMask() : nullptr, *this, *this, getDebugLoc());
3472 Copy->transferFlags(*this);
3473 return Copy;
3474 }
3475
3476 VP_CLASSOF_IMPL(VPRecipeBase::VPReplicateSC)
3477
3478 /// Generate replicas of the desired Ingredient. Replicas will be generated
3479 /// for all parts and lanes unless a specific part and lane are specified in
3480 /// the \p State.
3481 void execute(VPTransformState &State) override;
3482
3483 /// Return the cost of this VPReplicateRecipe.
3484 InstructionCost computeCost(ElementCount VF,
3485 VPCostContext &Ctx) const override;
3486
3487 /// Return the cost of scalarizing a call to \p CalledFn with argument
3488 /// operands \p ArgOps for a given \p VF.
3489 static InstructionCost computeCallCost(Function *CalledFn, Type *ResultTy,
3491 bool IsSingleScalar, ElementCount VF,
3492 VPCostContext &Ctx);
3493
3494 /// Returns true if the recipe produces a single scalar value.
3495 bool isSingleScalar() const { return IsSingleScalar; }
3496
3497 /// Returns true if the recipe produces scalar values for all VF lanes.
3498 bool doesGeneratePerAllLanes() const { return !IsSingleScalar; }
3499
3500 bool isPredicated() const { return IsPredicated; }
3501
3502 /// Returns true if the recipe only uses the first lane of operand \p Op.
3503 bool usesFirstLaneOnly(const VPValue *Op) const override {
3505 "Op must be an operand of the recipe");
3506 return isSingleScalar();
3507 }
3508
3509 /// Returns true if the recipe uses scalars of operand \p Op.
3510 bool usesScalars(const VPValue *Op) const override {
3512 "Op must be an operand of the recipe");
3513 return true;
3514 }
3515
3516 /// Return the mask of a predicated VPReplicateRecipe.
3518 assert(isPredicated() && "Trying to get the mask of a unpredicated recipe");
3519 return getOperand(getNumOperands() - 1);
3520 }
3521
3522 /// Return the recipe's operands, excluding the mask of a predicated recipe.
3526
3527 /// Returns the number of operands, excluding the mask if the recipe is
3528 /// predicated.
3529 unsigned getNumOperandsWithoutMask() const {
3530 return getNumOperands() - isPredicated();
3531 }
3532
3533 unsigned getOpcode() const { return getUnderlyingInstr()->getOpcode(); }
3534
3535protected:
3536#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3537 /// Print the recipe.
3538 void printRecipe(raw_ostream &O, const Twine &Indent,
3539 VPSlotTracker &SlotTracker) const override;
3540#endif
3541};
3542
3543/// A recipe for generating conditional branches on the bits of a mask.
3545 public VPIRMetadata {
3546public:
3548 const VPIRMetadata &Metadata = {})
3549 : VPRecipeBase(VPRecipeBase::VPBranchOnMaskSC, {BlockInMask}, DL),
3550 VPIRMetadata(Metadata) {}
3551
3553 return new VPBranchOnMaskRecipe(getOperand(0), getDebugLoc(), *this);
3554 }
3555
3556 VP_CLASSOF_IMPL(VPRecipeBase::VPBranchOnMaskSC)
3557
3558 /// Generate the extraction of the appropriate bit from the block mask and the
3559 /// conditional branch.
3560 void execute(VPTransformState &State) override;
3561
3562 /// Return the cost of this VPBranchOnMaskRecipe.
3563 InstructionCost computeCost(ElementCount VF,
3564 VPCostContext &Ctx) const override;
3565
3566#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3567 /// Print the recipe.
3568 void printRecipe(raw_ostream &O, const Twine &Indent,
3569 VPSlotTracker &SlotTracker) const override {
3570 O << Indent << "BRANCH-ON-MASK ";
3572 }
3573#endif
3574
3575 /// Returns true if the recipe uses scalars of operand \p Op.
3576 bool usesScalars(const VPValue *Op) const override {
3578 "Op must be an operand of the recipe");
3579 return true;
3580 }
3581};
3582
3583/// A recipe to combine multiple recipes into a single 'expression' recipe,
3584/// which should be considered a single entity for cost-modeling and transforms.
3585/// The recipe needs to be 'decomposed', i.e. replaced by its individual
3586/// expression recipes, before execute. The individual expression recipes are
3587/// completely disconnected from the def-use graph of other recipes not part of
3588/// the expression. Def-use edges between pairs of expression recipes remain
3589/// intact, whereas every edge between an expression recipe and a recipe outside
3590/// the expression is elevated to connect the non-expression recipe with the
3591/// VPExpressionRecipe itself.
3593 /// Recipes included in this VPExpressionRecipe. This could contain
3594 /// duplicates.
3595 SmallVector<VPSingleDefRecipe *> ExpressionRecipes;
3596
3597 /// Temporary VPValues used for external operands of the expression, i.e.
3598 /// operands not defined by recipes in the expression.
3599 SmallVector<VPValue *> LiveInPlaceholders;
3600
3601 enum class ExpressionTypes {
3602 /// Represents an inloop extended reduction operation, performing a
3603 /// reduction on an extended vector operand into a scalar value, and adding
3604 /// the result to a chain.
3605 ExtendedReduction,
3606 /// Represents an inloop extended reduction operation, which is negated,
3607 /// then reduced before adding the result to a chain.
3608 NegatedExtendedReduction,
3609 /// Represent an inloop multiply-accumulate reduction, multiplying the
3610 /// extended vector operands, performing a reduction.add on the result, and
3611 /// adding the scalar result to a chain.
3612 ExtMulAccReduction,
3613 /// Represent an inloop multiply-accumulate reduction, multiplying the
3614 /// vector operands, performing a reduction.add on the result, and adding
3615 /// the scalar result to a chain.
3616 MulAccReduction,
3617 /// Represent an inloop multiply-accumulate reduction, multiplying the
3618 /// extended vector operands, negating the multiplication, performing a
3619 /// reduction.add on the result, and adding the scalar result to a chain.
3620 ExtNegatedMulAccReduction,
3621 };
3622
3623 /// Type of the expression.
3624 ExpressionTypes ExpressionType;
3625
3626public:
3627 /// Construct a new VPExpressionRecipe by internalizing recipes in \p
3628 /// ExpressionRecipes. External operands (i.e. not defined by another recipe
3629 /// in the expression) are replaced by temporary VPValues and the original
3630 /// operands are transferred to the VPExpressionRecipe itself. Clone recipes
3631 /// as needed (excluding last) to ensure they are only used by other recipes
3632 /// in the expression.
3633 VPExpressionRecipe(ExpressionTypes ExpressionType,
3634 ArrayRef<VPSingleDefRecipe *> ExpressionRecipes);
3635
3637 : VPExpressionRecipe(ExpressionTypes::ExtendedReduction, {Ext, Red}) {}
3639 VPReductionRecipe *Red)
3640 : VPExpressionRecipe(ExpressionTypes::NegatedExtendedReduction,
3641 {Ext, Neg, Red}) {
3642 assert((Red->getRecurrenceKind() == RecurKind::Add ||
3643 Red->getRecurrenceKind() == RecurKind::FAdd ||
3644 Red->getRecurrenceKind() == RecurKind::AddChainWithSubs) &&
3645 "Expected an add or add-chain-with-subs reduction");
3646 if (Neg->getOpcode() == Instruction::Sub) {
3647 [[maybe_unused]] auto *SubConst = dyn_cast<VPConstantInt>(getOperand(1));
3648 assert(SubConst && SubConst->isZero() && "Expected a negating sub");
3649 } else
3650 assert(Neg->getOpcode() == Instruction::FNeg && "Unexpected opcode");
3651 }
3653 : VPExpressionRecipe(ExpressionTypes::MulAccReduction, {Mul, Red}) {}
3656 : VPExpressionRecipe(ExpressionTypes::ExtMulAccReduction,
3657 {Ext0, Ext1, Mul, Red}) {}
3660 VPReductionRecipe *Red)
3661 : VPExpressionRecipe(ExpressionTypes::ExtNegatedMulAccReduction,
3662 {Ext0, Ext1, Mul, Neg, Red}) {
3663 assert((Mul->getOpcode() == Instruction::Mul ||
3664 Mul->getOpcode() == Instruction::FMul) &&
3665 "Expected a mul");
3666 assert((Red->getRecurrenceKind() == RecurKind::Add ||
3667 Red->getRecurrenceKind() == RecurKind::FAdd ||
3668 Red->getRecurrenceKind() == RecurKind::AddChainWithSubs) &&
3669 "Expected an add or add-chain-with-subs reduction");
3670 assert(getNumOperands() >= 3 && "Expected at least three operands");
3671 if (Neg->getOpcode() == Instruction::Sub) {
3672 [[maybe_unused]] auto *SubConst = dyn_cast<VPConstantInt>(getOperand(2));
3673 assert(SubConst && SubConst->isZero() &&
3674 Neg->getOpcode() == Instruction::Sub && "Expected a negating sub");
3675 } else
3676 assert(Neg->getOpcode() == Instruction::FNeg && "Unexpected opcode");
3677 }
3678
3680 SmallPtrSet<VPSingleDefRecipe *, 4> ExpressionRecipesSeen;
3681 for (auto *R : reverse(ExpressionRecipes)) {
3682 if (ExpressionRecipesSeen.insert(R).second)
3683 delete R;
3684 }
3685 for (VPValue *T : LiveInPlaceholders)
3686 delete T;
3687 }
3688
3689 VP_CLASSOF_IMPL(VPRecipeBase::VPExpressionSC)
3690
3692 assert(!ExpressionRecipes.empty() && "empty expressions should be removed");
3693 SmallVector<VPSingleDefRecipe *> NewExpressiondRecipes;
3694 for (auto *R : ExpressionRecipes)
3695 NewExpressiondRecipes.push_back(R->clone());
3696 for (auto *New : NewExpressiondRecipes) {
3697 for (const auto &[Idx, Old] : enumerate(ExpressionRecipes))
3698 New->replaceUsesOfWith(Old, NewExpressiondRecipes[Idx]);
3699 // Update placeholder operands in the cloned recipe to use the external
3700 // operands, to be internalized when the cloned expression is constructed.
3701 for (const auto &[Placeholder, OutsideOp] :
3702 zip(LiveInPlaceholders, operands()))
3703 New->replaceUsesOfWith(Placeholder, OutsideOp);
3704 }
3705 return new VPExpressionRecipe(ExpressionType, NewExpressiondRecipes);
3706 }
3707
3708 /// Return and insert the recipes of the expression back into the VPlan,
3709 /// directly before the current recipe. Leaves the expression recipe empty,
3710 /// which must be removed before codegen.
3712
3713 /// Returns the expression type of this recipe.
3714 ExpressionTypes getExpressionType() const { return ExpressionType; }
3715
3716 unsigned getVFScaleFactor() const {
3717 auto *PR = dyn_cast<VPReductionRecipe>(ExpressionRecipes.back());
3718 return PR ? PR->getVFScaleFactor() : 1;
3719 }
3720
3721 /// Method for generating code, must not be called as this recipe is abstract.
3722 void execute(VPTransformState &State) override {
3723 llvm_unreachable("recipe must be removed before execute");
3724 }
3725
3727 VPCostContext &Ctx) const override;
3728
3729 /// Returns true if this expression contains recipes that may read from or
3730 /// write to memory.
3731 bool mayReadOrWriteMemory() const;
3732
3733 /// Returns true if this expression contains recipes that may have side
3734 /// effects.
3735 bool mayHaveSideEffects() const;
3736
3737 /// Returns true if this VPExpressionRecipe produces a single scalar.
3738 bool isVectorToScalar() const;
3739
3740protected:
3741#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3742 /// Print the recipe.
3743 void printRecipe(raw_ostream &O, const Twine &Indent,
3744 VPSlotTracker &SlotTracker) const override;
3745#endif
3746};
3747
3748/// VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when
3749/// control converges back from a Branch-on-Mask. The phi nodes are needed in
3750/// order to merge values that are set under such a branch and feed their uses.
3751/// The phi nodes can be scalar or vector depending on the users of the value.
3752/// This recipe works in concert with VPBranchOnMaskRecipe.
3754public:
3755 /// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
3756 /// nodes after merging back from a Branch-on-Mask.
3758 : VPSingleDefRecipe(VPRecipeBase::VPPredInstPHISC, PredV,
3759 PredV->getScalarType(), /*UV=*/nullptr, DL) {}
3760 ~VPPredInstPHIRecipe() override = default;
3761
3763 return new VPPredInstPHIRecipe(getOperand(0), getDebugLoc());
3764 }
3765
3766 VP_CLASSOF_IMPL(VPRecipeBase::VPPredInstPHISC)
3767
3768 /// Generates phi nodes for live-outs (from a replicate region) as needed to
3769 /// retain SSA form.
3770 void execute(VPTransformState &State) override;
3771
3772 /// Return the cost of this VPPredInstPHIRecipe.
3774 VPCostContext &Ctx) const override {
3775 // TODO: Compute accurate cost after retiring the legacy cost model.
3776 return 0;
3777 }
3778
3779protected:
3780#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3781 /// Print the recipe.
3782 void printRecipe(raw_ostream &O, const Twine &Indent,
3783 VPSlotTracker &SlotTracker) const override;
3784#endif
3785};
3786
3787/// A common mixin class for widening memory operations. An optional mask can be
3788/// provided as the last operand.
3790protected:
3792
3793 /// Alignment information for this memory access.
3795
3796 /// Whether the accessed addresses are consecutive.
3798
3799 /// Whether the memory access is masked.
3800 bool IsMasked = false;
3801
3802 void setMask(VPValue *Mask) {
3803 assert(!IsMasked && "cannot re-set mask");
3804 if (!Mask)
3805 return;
3806 assert(Mask->getScalarType()->isIntegerTy(1) &&
3807 "Mask must be an i1 (vector)");
3808 getAsRecipe()->addOperand(Mask);
3809 IsMasked = true;
3810 }
3811
3816
3817public:
3818 virtual ~VPWidenMemoryRecipe() = default;
3819
3820 /// Return a VPRecipeBase* to the current object.
3822 virtual const VPRecipeBase *getAsRecipe() const = 0;
3823
3824 /// Return whether the loaded-from / stored-to addresses are consecutive.
3825 bool isConsecutive() const { return Consecutive; }
3826
3827 /// Return the address accessed by this recipe.
3828 VPValue *getAddr() const { return getAsRecipe()->getOperand(0); }
3829
3830 /// Returns true if the recipe is masked.
3831 bool isMasked() const { return IsMasked; }
3832
3833 /// Return the mask used by this recipe. Note that a full mask is represented
3834 /// by a nullptr.
3835 VPValue *getMask() const {
3836 // Mask is optional and therefore the last operand.
3837 const VPRecipeBase *R = getAsRecipe();
3838 return isMasked() ? R->getOperand(R->getNumOperands() - 1) : nullptr;
3839 }
3840
3841 /// Returns the alignment of the memory access.
3842 Align getAlign() const { return Alignment; }
3843
3844 /// Return the cost of this VPWidenMemoryRecipe.
3845 InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const;
3846
3848};
3849
3850/// A recipe for widening load operations, using the address to load from and an
3851/// optional mask.
3853 public VPWidenMemoryRecipe {
3855 bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
3856 : VPSingleDefRecipe(VPRecipeBase::VPWidenLoadSC, {Addr}, Load.getType(),
3857 &Load, DL),
3858 VPWidenMemoryRecipe(Load, Consecutive, Metadata) {
3859 setMask(Mask);
3860 }
3861
3864 getMask(), Consecutive, *this, getDebugLoc());
3865 }
3866
3867 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenLoadSC);
3868
3869 /// Returns the opcode of the widened load.
3870 unsigned getOpcode() const { return Instruction::Load; }
3871
3872 /// Generate a wide load or gather.
3873 void execute(VPTransformState &State) override;
3874
3875 /// Return the cost of this VPWidenLoadRecipe.
3877 VPCostContext &Ctx) const override {
3878 return VPWidenMemoryRecipe::computeCost(VF, Ctx);
3879 }
3880
3881 /// Returns true if the recipe only uses the first lane of operand \p Op.
3882 bool usesFirstLaneOnly(const VPValue *Op) const override {
3884 "Op must be an operand of the recipe");
3885 // Widened, consecutive loads operations only demand the first lane of
3886 // their address.
3887 return Op == getAddr() && isConsecutive();
3888 }
3889
3890protected:
3891 VPRecipeBase *getAsRecipe() override;
3892 const VPRecipeBase *getAsRecipe() const override;
3893
3894#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3895 /// Print the recipe.
3896 void printRecipe(raw_ostream &O, const Twine &Indent,
3897 VPSlotTracker &SlotTracker) const override;
3898#endif
3899};
3900
3901/// A recipe for widening load operations with vector-predication intrinsics,
3902/// using the address to load from, the explicit vector length and an optional
3903/// mask.
3905 : public VPSingleDefRecipe,
3906 public VPWidenMemoryRecipe {
3908 VPValue *Mask)
3909 : VPSingleDefRecipe(VPRecipeBase::VPWidenLoadEVLSC, {Addr, &EVL},
3910 L.getIngredient().getType(), &L.getIngredient(),
3911 L.getDebugLoc()),
3912 VPWidenMemoryRecipe(L.getIngredient(), L.isConsecutive(), L) {
3913 setMask(Mask);
3914 }
3915
3917 llvm_unreachable("cloning not supported");
3918 }
3919
3920 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenLoadEVLSC)
3921
3922 /// Returns the opcode of the widened load.
3923 unsigned getOpcode() const { return Instruction::Load; }
3924
3925 /// Return the EVL operand.
3926 VPValue *getEVL() const { return getOperand(1); }
3927
3928 /// Generate the wide load or gather.
3929 void execute(VPTransformState &State) override;
3930
3931 /// Return the cost of this VPWidenLoadEVLRecipe.
3932 InstructionCost computeCost(ElementCount VF,
3933 VPCostContext &Ctx) const override;
3934
3935 /// Returns true if the recipe only uses the first lane of operand \p Op.
3936 bool usesFirstLaneOnly(const VPValue *Op) const override {
3938 "Op must be an operand of the recipe");
3939 // Widened loads only demand the first lane of EVL and consecutive loads
3940 // only demand the first lane of their address.
3941 return Op == getEVL() || (Op == getAddr() && isConsecutive());
3942 }
3943
3944protected:
3945 VPRecipeBase *getAsRecipe() override;
3946 const VPRecipeBase *getAsRecipe() const override;
3947
3948#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3949 /// Print the recipe.
3950 void printRecipe(raw_ostream &O, const Twine &Indent,
3951 VPSlotTracker &SlotTracker) const override;
3952#endif
3953};
3954
3955/// A recipe for widening store operations, using the stored value, the address
3956/// to store to and an optional mask.
3958 public VPWidenMemoryRecipe {
3960 VPValue *Mask, bool Consecutive,
3961 const VPIRMetadata &Metadata, DebugLoc DL)
3962 : VPRecipeBase(VPRecipeBase::VPWidenStoreSC, {Addr, StoredVal}, DL),
3963 VPWidenMemoryRecipe(Store, Consecutive, Metadata) {
3964 setMask(Mask);
3965 }
3966
3970 *this, getDebugLoc());
3971 }
3972
3973 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenStoreSC);
3974
3975 /// Return the value stored by this recipe.
3976 VPValue *getStoredValue() const { return getOperand(1); }
3977
3978 /// Generate a wide store or scatter.
3979 void execute(VPTransformState &State) override;
3980
3981 /// Return the cost of this VPWidenStoreRecipe.
3983 VPCostContext &Ctx) const override {
3984 return VPWidenMemoryRecipe::computeCost(VF, Ctx);
3985 }
3986
3987 /// Returns true if the recipe only uses the first lane of operand \p Op.
3988 bool usesFirstLaneOnly(const VPValue *Op) const override {
3990 "Op must be an operand of the recipe");
3991 // Widened, consecutive stores only demand the first lane of their address,
3992 // unless the same operand is also stored.
3993 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
3994 }
3995
3996protected:
3997 VPRecipeBase *getAsRecipe() override;
3998 const VPRecipeBase *getAsRecipe() const override;
3999
4000#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4001 /// Print the recipe.
4002 void printRecipe(raw_ostream &O, const Twine &Indent,
4003 VPSlotTracker &SlotTracker) const override;
4004#endif
4005};
4006
4007/// A recipe for widening store operations with vector-predication intrinsics,
4008/// using the value to store, the address to store to, the explicit vector
4009/// length and an optional mask.
4011 : public VPRecipeBase,
4012 public VPWidenMemoryRecipe {
4014 VPValue *StoredVal, VPValue &EVL, VPValue *Mask)
4015 : VPRecipeBase(VPRecipeBase::VPWidenStoreEVLSC, {Addr, StoredVal, &EVL},
4016 S.getDebugLoc()),
4017 VPWidenMemoryRecipe(S.getIngredient(), S.isConsecutive(), S) {
4018 setMask(Mask);
4019 }
4020
4022 llvm_unreachable("cloning not supported");
4023 }
4024
4025 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenStoreEVLSC)
4026
4027 /// Return the address accessed by this recipe.
4028 VPValue *getStoredValue() const { return getOperand(1); }
4029
4030 /// Return the EVL operand.
4031 VPValue *getEVL() const { return getOperand(2); }
4032
4033 /// Generate the wide store or scatter.
4034 void execute(VPTransformState &State) override;
4035
4036 /// Return the cost of this VPWidenStoreEVLRecipe.
4037 InstructionCost computeCost(ElementCount VF,
4038 VPCostContext &Ctx) const override;
4039
4040 /// Returns true if the recipe only uses the first lane of operand \p Op.
4041 bool usesFirstLaneOnly(const VPValue *Op) const override {
4043 "Op must be an operand of the recipe");
4044 if (Op == getEVL()) {
4045 assert(getStoredValue() != Op && "unexpected store of EVL");
4046 return true;
4047 }
4048 // Widened, consecutive memory operations only demand the first lane of
4049 // their address, unless the same operand is also stored. That latter can
4050 // happen with opaque pointers.
4051 return Op == getAddr() && isConsecutive() && Op != getStoredValue();
4052 }
4053
4054protected:
4055 VPRecipeBase *getAsRecipe() override;
4056 const VPRecipeBase *getAsRecipe() const override;
4057
4058#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4059 /// Print the recipe.
4060 void printRecipe(raw_ostream &O, const Twine &Indent,
4061 VPSlotTracker &SlotTracker) const override;
4062#endif
4063};
4064
4065/// Recipe to expand a SCEV expression.
4067 const SCEV *Expr;
4068
4069public:
4070 VPExpandSCEVRecipe(const SCEV *Expr);
4071
4072 ~VPExpandSCEVRecipe() override = default;
4073
4074 VPExpandSCEVRecipe *clone() override { return new VPExpandSCEVRecipe(Expr); }
4075
4076 VP_CLASSOF_IMPL(VPRecipeBase::VPExpandSCEVSC)
4077
4078 void execute(VPTransformState &State) override {
4079 llvm_unreachable("SCEV expressions must be expanded before final execute");
4080 }
4081
4082 /// Return the cost of this VPExpandSCEVRecipe.
4084 VPCostContext &Ctx) const override {
4085 // TODO: Compute accurate cost after retiring the legacy cost model.
4086 return 0;
4087 }
4088
4089 const SCEV *getSCEV() const { return Expr; }
4090
4091protected:
4092#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4093 /// Print the recipe.
4094 void printRecipe(raw_ostream &O, const Twine &Indent,
4095 VPSlotTracker &SlotTracker) const override;
4096#endif
4097};
4098
4099/// A recipe for generating the active lane mask for the vector loop that is
4100/// used to predicate the vector operations.
4102public:
4104 : VPHeaderPHIRecipe(VPRecipeBase::VPActiveLaneMaskPHISC, nullptr,
4105 StartMask, DL) {}
4106
4107 ~VPActiveLaneMaskPHIRecipe() override = default;
4108
4111 if (getNumOperands() == 2)
4112 R->addBackedgeValue(getOperand(1));
4113 return R;
4114 }
4115
4116 VP_CLASSOF_IMPL(VPRecipeBase::VPActiveLaneMaskPHISC)
4117
4118 /// Generate the active lane mask phi of the vector loop.
4119 void execute(VPTransformState &State) override;
4120
4121protected:
4122#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4123 /// Print the recipe.
4124 void printRecipe(raw_ostream &O, const Twine &Indent,
4125 VPSlotTracker &SlotTracker) const override;
4126#endif
4127};
4128
4129/// A recipe for generating the phi node tracking the current scalar iteration
4130/// index. It starts at the start value of the canonical induction and gets
4131/// incremented by the number of scalar iterations processed by the vector loop
4132/// iteration. The increment does not have to be loop invariant.
4134public:
4136 : VPHeaderPHIRecipe(VPRecipeBase::VPCurrentIterationPHISC, nullptr,
4137 StartIV, DL) {}
4138
4139 ~VPCurrentIterationPHIRecipe() override = default;
4140
4142 llvm_unreachable("cloning not implemented yet");
4143 }
4144
4145 VP_CLASSOF_IMPL(VPRecipeBase::VPCurrentIterationPHISC)
4146
4147 void execute(VPTransformState &State) override {
4148 llvm_unreachable("cannot execute this recipe, should be replaced by a "
4149 "scalar phi recipe");
4150 }
4151
4152 /// Return the cost of this VPCurrentIterationPHIRecipe.
4154 VPCostContext &Ctx) const override {
4155 // For now, match the behavior of the legacy cost model.
4156 return 0;
4157 }
4158
4159 /// Returns true if the recipe only uses the first lane of operand \p Op.
4160 bool usesFirstLaneOnly(const VPValue *Op) const override {
4162 "Op must be an operand of the recipe");
4163 return true;
4164 }
4165
4166protected:
4167#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4168 /// Print the recipe.
4169 LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent,
4170 VPSlotTracker &SlotTracker) const override;
4171#endif
4172};
4173
4174/// A Recipe for widening the canonical induction variable of the vector loop.
4175/// First operand is the canonical IV recipe, a second step operand (VF * Part)
4176/// is added during unrolling.
4178public:
4180 const VPIRFlags::WrapFlagsTy &Flags = {})
4181 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCanonicalIVSC, CanonicalIV,
4182 CanonicalIV->getType(), Flags) {}
4183
4184 ~VPWidenCanonicalIVRecipe() override = default;
4185
4187 auto *WideCanIV =
4189 if (VPValue *Step = getStepValue())
4190 WideCanIV->addPerPartStep(Step);
4191 return WideCanIV;
4192 }
4193
4194 VP_CLASSOF_IMPL(VPRecipeBase::VPWidenCanonicalIVSC)
4195
4196 void execute(VPTransformState &State) override {
4197 llvm_unreachable("Expected prior expansion of WidenCanonicalIV recipes");
4198 }
4199
4200 /// Return the cost of this VPWidenCanonicalIVPHIRecipe.
4202 VPCostContext &Ctx) const override {
4203 // TODO: Compute accurate cost after retiring the legacy cost model.
4204 return 0;
4205 }
4206
4207 /// Return the canonical IV being widened.
4211
4213 return getNumOperands() == 2 ? getOperand(1) : nullptr;
4214 }
4215
4216 /// Add the per-part step (VF * Part) used for unrolled parts.
4218 assert(Step->getScalarType() == getScalarType() &&
4219 "per-part step must have the same type as the canonical IV");
4220 VPUser::addOperand(Step);
4221 }
4222
4223protected:
4224#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4225 /// Print the recipe.
4226 void printRecipe(raw_ostream &O, const Twine &Indent,
4227 VPSlotTracker &SlotTracker) const override;
4228#endif
4229};
4230
4231/// A recipe for converting \p Current into \p Start + \p Current * \p Step.
4232/// FastMathFlags are derived from the \p FPBinOp in the case of FP inductions,
4233/// and the passed NoWrap \p Flags apply in the case of Ptr and Int inductions.
4235 /// Kind of the induction.
4237 /// If not nullptr, the floating point induction binary operator. Must be set
4238 /// for floating point inductions.
4239 const FPMathOperator *FPBinOp;
4240
4241public:
4243 const FPMathOperator *FPBinOp, VPValue *Start,
4244 VPValue *Current, VPValue *Step,
4245 const VPIRFlags::WrapFlagsTy &Flags = {})
4246 : VPRecipeWithIRFlags(VPRecipeBase::VPDerivedIVSC, {Start, Current, Step},
4247 Start->getScalarType(), Flags),
4248 Kind(Kind), FPBinOp(FPBinOp) {}
4249
4250 ~VPDerivedIVRecipe() override = default;
4251
4253 return new VPDerivedIVRecipe(Kind, FPBinOp, getStartValue(), getOperand(1),
4255 }
4256
4257 VP_CLASSOF_IMPL(VPRecipeBase::VPDerivedIVSC)
4258
4259 void execute(VPTransformState &State) override {
4260 llvm_unreachable("Expected prior expansion of this recipe");
4261 }
4262
4263 /// Return the cost of this VPDerivedIVRecipe.
4265 VPCostContext &Ctx) const override;
4266
4267 VPValue *getStartValue() const { return getOperand(0); }
4268 VPValue *getIndex() const { return getOperand(1); }
4269 VPValue *getStepValue() const { return getOperand(2); }
4270 const FPMathOperator *getFPBinOp() const { return FPBinOp; }
4272
4273 /// Returns true if the recipe only uses the first lane of operand \p Op.
4274 bool usesFirstLaneOnly(const VPValue *Op) const override {
4276 "Op must be an operand of the recipe");
4277 return true;
4278 }
4279
4280protected:
4281#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4282 /// Print the recipe.
4283 void printRecipe(raw_ostream &O, const Twine &Indent,
4284 VPSlotTracker &SlotTracker) const override;
4285#endif
4286};
4287
4288/// A recipe for handling phi nodes of integer and floating-point inductions,
4289/// producing their scalar values. Before unrolling by UF the recipe represents
4290/// the VF*UF scalar values to be produced, or UF scalar values if only first
4291/// lane is used, and has 3 operands: IV, step and VF. Unrolling adds one extra
4292/// operand StartIndex to all unroll parts except part 0, as the recipe
4293/// represents the VF scalar values (this number of values is taken from
4294/// State.VF rather than from the VF operand) starting at IV + StartIndex.
4296 Instruction::BinaryOps InductionOpcode;
4297
4298public:
4302 : VPRecipeWithIRFlags(VPRecipeBase::VPScalarIVStepsSC, {IV, Step, VF},
4303 IV->getScalarType(), FMFs, DL),
4304 InductionOpcode(Opcode) {}
4305
4306 ~VPScalarIVStepsRecipe() override = default;
4307
4309 auto *NewR = new VPScalarIVStepsRecipe(
4310 getOperand(0), getOperand(1), getOperand(2), InductionOpcode,
4312 if (VPValue *StartIndex = getStartIndex())
4313 NewR->setStartIndex(StartIndex);
4314 return NewR;
4315 }
4316
4317 VP_CLASSOF_IMPL(VPRecipeBase::VPScalarIVStepsSC)
4318
4319 /// Generate the scalarized versions of the phi node as needed by their users.
4320 void execute(VPTransformState &State) override;
4321
4322 /// Return the cost of this VPScalarIVStepsRecipe.
4323 InstructionCost computeCost(ElementCount VF,
4324 VPCostContext &Ctx) const override;
4325
4326 VPValue *getStepValue() const { return getOperand(1); }
4327
4328 /// Return the number of scalars to produce per unroll part, used to compute
4329 /// StartIndex during unrolling.
4330 VPValue *getVFValue() const { return getOperand(2); }
4331
4332 /// Return the StartIndex, or null if known to be zero, valid only after
4333 /// unrolling.
4335 return getNumOperands() == 4 ? getOperand(3) : nullptr;
4336 }
4337
4338 /// Set or add the StartIndex operand.
4339 void setStartIndex(VPValue *StartIndex) {
4340 if (getNumOperands() == 4)
4341 setOperand(3, StartIndex);
4342 else
4343 addOperand(StartIndex);
4344 }
4345
4346 /// Returns true if this recipe produces scalar values for all VF lanes.
4347 bool doesGeneratePerAllLanes() const;
4348
4349 /// Returns true if the recipe only uses the first lane of operand \p Op.
4350 bool usesFirstLaneOnly(const VPValue *Op) const override {
4352 "Op must be an operand of the recipe");
4353 return true;
4354 }
4355
4356 Instruction::BinaryOps getInductionOpcode() const { return InductionOpcode; }
4357
4358protected:
4359#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4360 /// Print the recipe.
4361 void printRecipe(raw_ostream &O, const Twine &Indent,
4362 VPSlotTracker &SlotTracker) const override;
4363#endif
4364};
4365
4366/// CastInfo helper for casting from VPRecipeBase to a mixin class that is not
4367/// part of the VPRecipeBase class hierarchy (e.g. VPPhiAccessors,
4368/// VPIRMetadata).
4369namespace vpdetail {
4370template <typename VPMixin, typename... RecipeTys>
4372 : public DefaultDoCastIfPossible<VPMixin *, VPRecipeBase *,
4373 CastInfoMixinImpl<VPMixin, RecipeTys...>> {
4374 static_assert((std::is_base_of_v<VPMixin, RecipeTys> && ...),
4375 "Each type in RecipeTys must derive from VPMixin");
4376
4377 /// Used by isa.
4378 static bool isPossible(VPRecipeBase *R) { return isa<RecipeTys...>(R); }
4379
4380 /// Used by cast.
4381 static VPMixin *doCast(VPRecipeBase *R) {
4382 VPMixin *Out = nullptr;
4383 ((Out = dyn_cast<RecipeTys>(R)) || ...);
4384 assert(Out && "Illegal recipe for cast");
4385 return Out;
4386 }
4387 static VPMixin *castFailed() { return nullptr; }
4388};
4389} // namespace vpdetail
4390
4391/// Support casting from VPRecipeBase -> VPPhiAccessors.
4392template <>
4396
4397template <>
4402template <>
4404 : public ForwardToPointerCast<VPPhiAccessors, VPRecipeBase *,
4405 CastInfo<VPPhiAccessors, VPRecipeBase *>> {};
4406
4407/// Support casting from VPRecipeBase / VPUser -> VPWidenMemoryRecipe.
4408template <>
4413template <>
4418
4419/// Support casting from VPSingleDefRecipe -> VPWidenMemoryRecipe (loads only).
4420template <>
4424template <>
4429
4430/// Support casting from VPRecipeBase -> VPIRMetadata.
4431template <>
4438
4439template <>
4444template <>
4446 : public ForwardToPointerCast<VPIRMetadata, VPRecipeBase *,
4447 CastInfo<VPIRMetadata, VPRecipeBase *>> {};
4448
4449/// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
4450/// holds a sequence of zero or more VPRecipe's each representing a sequence of
4451/// output IR instructions. All PHI-like recipes must come before any non-PHI
4452/// recipes.
4453class LLVM_ABI_FOR_TEST VPBasicBlock : public VPBlockBase {
4454 friend class VPlan;
4455
4456 /// Use VPlan::createVPBasicBlock to create VPBasicBlocks.
4457 VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr)
4458 : VPBlockBase(VPBasicBlockSC, Name.str()) {
4459 if (Recipe)
4460 appendRecipe(Recipe);
4461 }
4462
4463public:
4465
4466protected:
4467 /// The VPRecipes held in the order of output instructions to generate.
4469
4470 VPBasicBlock(VPBlockTy BlockSC, const Twine &Name = "")
4471 : VPBlockBase(BlockSC, Name.str()) {}
4472
4473public:
4474 ~VPBasicBlock() override {
4475 while (!Recipes.empty())
4476 Recipes.pop_back();
4477 }
4478
4479 /// Instruction iterators...
4484
4485 //===--------------------------------------------------------------------===//
4486 /// Recipe iterator methods
4487 ///
4488 inline iterator begin() { return Recipes.begin(); }
4489 inline const_iterator begin() const { return Recipes.begin(); }
4490 inline iterator end() { return Recipes.end(); }
4491 inline const_iterator end() const { return Recipes.end(); }
4492
4493 inline reverse_iterator rbegin() { return Recipes.rbegin(); }
4494 inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); }
4495 inline reverse_iterator rend() { return Recipes.rend(); }
4496 inline const_reverse_iterator rend() const { return Recipes.rend(); }
4497
4498 inline size_t size() const { return Recipes.size(); }
4499 inline bool empty() const { return Recipes.empty(); }
4500 inline const VPRecipeBase &front() const { return Recipes.front(); }
4501 inline VPRecipeBase &front() { return Recipes.front(); }
4502 inline const VPRecipeBase &back() const { return Recipes.back(); }
4503 inline VPRecipeBase &back() { return Recipes.back(); }
4504
4505 /// Returns a reference to the list of recipes.
4507
4508 /// Returns a pointer to a member of the recipe list.
4509 static RecipeListTy VPBasicBlock::*getSublistAccess(VPRecipeBase *) {
4510 return &VPBasicBlock::Recipes;
4511 }
4512
4513 /// Method to support type inquiry through isa, cast, and dyn_cast.
4514 static inline bool classof(const VPBlockBase *V) {
4515 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
4516 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4517 }
4518
4519 void insert(VPRecipeBase *Recipe, iterator InsertPt) {
4520 assert(Recipe && "No recipe to append.");
4521 assert(!Recipe->Parent && "Recipe already in VPlan");
4522 Recipe->Parent = this;
4523 Recipes.insert(InsertPt, Recipe);
4524 }
4525
4526 /// Augment the existing recipes of a VPBasicBlock with an additional
4527 /// \p Recipe as the last recipe.
4528 void appendRecipe(VPRecipeBase *Recipe) { insert(Recipe, end()); }
4529
4530 /// The method which generates the output IR instructions that correspond to
4531 /// this VPBasicBlock, thereby "executing" the VPlan.
4532 void execute(VPTransformState *State) override;
4533
4534 /// Return the cost of this VPBasicBlock.
4535 InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override;
4536
4537 /// Return the position of the first non-phi node recipe in the block.
4538 iterator getFirstNonPhi();
4539
4540 /// Returns an iterator range over the PHI-like recipes in the block.
4544
4545 /// Split current block at \p SplitAt by inserting a new block between the
4546 /// current block and its successors and moving all recipes starting at
4547 /// SplitAt to the new block. Returns the new block.
4548 VPBasicBlock *splitAt(iterator SplitAt);
4549
4550 VPRegionBlock *getEnclosingLoopRegion();
4551 const VPRegionBlock *getEnclosingLoopRegion() const;
4552
4553#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4554 /// Print this VPBsicBlock to \p O, prefixing all lines with \p Indent. \p
4555 /// SlotTracker is used to print unnamed VPValue's using consequtive numbers.
4556 ///
4557 /// Note that the numbering is applied to the whole VPlan, so printing
4558 /// individual blocks is consistent with the whole VPlan printing.
4559 void print(raw_ostream &O, const Twine &Indent,
4560 VPSlotTracker &SlotTracker) const override;
4561 using VPBlockBase::print; // Get the print(raw_stream &O) version.
4562#endif
4563
4564 /// If the block has multiple successors, return the branch recipe terminating
4565 /// the block. If there are no or only a single successor, return nullptr;
4566 VPRecipeBase *getTerminator();
4567 const VPRecipeBase *getTerminator() const;
4568
4569 /// Returns true if the block is exiting it's parent region.
4570 bool isExiting() const;
4571
4572 /// Clone the current block and it's recipes, without updating the operands of
4573 /// the cloned recipes.
4574 VPBasicBlock *clone() override;
4575
4576 /// Returns the predecessor block at index \p Idx with the predecessors as per
4577 /// the corresponding plain CFG. If the block is an entry block to a region,
4578 /// the first predecessor is the single predecessor of a region, and the
4579 /// second predecessor is the exiting block of the region.
4580 const VPBasicBlock *getCFGPredecessor(unsigned Idx) const;
4581
4582protected:
4583 /// Execute the recipes in the IR basic block \p BB.
4584 void executeRecipes(VPTransformState *State, BasicBlock *BB);
4585
4586 /// Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block
4587 /// generated for this VPBB.
4588 void connectToPredecessors(VPTransformState &State);
4589
4590private:
4591 /// Create an IR BasicBlock to hold the output instructions generated by this
4592 /// VPBasicBlock, and return it. Update the CFGState accordingly.
4593 BasicBlock *createEmptyBasicBlock(VPTransformState &State);
4594};
4595
4596inline const VPBasicBlock *
4598 return getAsRecipe()->getParent()->getCFGPredecessor(Idx);
4599}
4600
4601/// A special type of VPBasicBlock that wraps an existing IR basic block.
4602/// Recipes of the block get added before the first non-phi instruction in the
4603/// wrapped block.
4604/// Note: At the moment, VPIRBasicBlock can only be used to wrap VPlan's
4605/// preheader block.
4606class VPIRBasicBlock : public VPBasicBlock {
4607 friend class VPlan;
4608
4609 BasicBlock *IRBB;
4610
4611 /// Use VPlan::createVPIRBasicBlock to create VPIRBasicBlocks.
4612 VPIRBasicBlock(BasicBlock *IRBB)
4613 : VPBasicBlock(VPIRBasicBlockSC,
4614 (Twine("ir-bb<") + IRBB->getName() + Twine(">")).str()),
4615 IRBB(IRBB) {}
4616
4617public:
4618 ~VPIRBasicBlock() override = default;
4619
4620 static inline bool classof(const VPBlockBase *V) {
4621 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4622 }
4623
4624 /// The method which generates the output IR instructions that correspond to
4625 /// this VPBasicBlock, thereby "executing" the VPlan.
4626 void execute(VPTransformState *State) override;
4627
4628 VPIRBasicBlock *clone() override;
4629
4630 BasicBlock *getIRBasicBlock() const { return IRBB; }
4631};
4632
4633/// Track information about the canonical IV and header mask of a loop region.
4634/// TODO: Have it also track the canonical IV increment, subject of NUW flag.
4636 /// VPRegionValue for the canonical IV, whose allocation is managed by
4637 /// VPCanonicalIVInfo.
4638 std::unique_ptr<VPRegionValue> CanIV;
4639
4640 /// Optional VPRegionValue for the header mask, set when tail folding.
4641 std::unique_ptr<VPRegionValue> HeaderMask;
4642
4643 /// Whether the increment of the canonical IV may unsigned wrap or not.
4644 bool HasNUW = true;
4645
4646public:
4648 : CanIV(std::make_unique<VPRegionValue>(Ty, DL, Region)) {}
4649
4650 VPRegionValue *getRegionValue() { return CanIV.get(); }
4651 const VPRegionValue *getRegionValue() const { return CanIV.get(); }
4652
4653 VPRegionValue *getHeaderMask() const { return HeaderMask.get(); }
4654
4655 /// Create the header mask for the region and return it. Must only be called
4656 /// when no header mask exists yet.
4658 assert(!HeaderMask && "Header mask already created");
4659 HeaderMask = std::make_unique<VPRegionValue>(
4660 Type::getInt1Ty(CanIV->getType()->getContext()), DebugLoc::getUnknown(),
4661 CanIV->getDefiningRegion());
4662 return HeaderMask.get();
4663 }
4664
4665 bool hasNUW() const { return HasNUW; }
4666
4667 void clearNUW() { HasNUW = false; }
4668};
4669
4670/// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
4671/// which form a Single-Entry-Single-Exiting subgraph of the output IR CFG.
4672/// A VPRegionBlock may indicate that its contents are to be replicated several
4673/// times. This is designed to support predicated scalarization, in which a
4674/// scalar if-then code structure needs to be generated VF * UF times. Having
4675/// this replication indicator helps to keep a single model for multiple
4676/// candidate VF's. The actual replication takes place only once the desired VF
4677/// and UF have been determined.
4678class LLVM_ABI_FOR_TEST VPRegionBlock : public VPBlockBase {
4679 friend class VPlan;
4680
4681 /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
4682 VPBlockBase *Entry;
4683
4684 /// Hold the Single Exiting block of the SESE region modelled by the
4685 /// VPRegionBlock.
4686 VPBlockBase *Exiting;
4687
4688 /// Holds the Canonical IV of the loop region along with additional
4689 /// information. If CanIVInfo is nullptr, the region is a replicating region.
4690 /// Loop regions retain their canonical IVs until they are dissolved, even if
4691 /// the canonical IV has no users.
4692 std::unique_ptr<VPCanonicalIVInfo> CanIVInfo;
4693
4694 /// Use VPlan::createLoopRegion() and VPlan::createReplicateRegion() to create
4695 /// VPRegionBlocks.
4696 VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting,
4697 const std::string &Name = "")
4698 : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exiting(Exiting) {
4699 if (Entry) {
4700 assert(!Entry->hasPredecessors() && "Entry block has predecessors.");
4701 assert(Exiting && "Must also pass Exiting if Entry is passed.");
4702 assert(!Exiting->hasSuccessors() && "Exit block has successors.");
4703 Entry->setParent(this);
4704 Exiting->setParent(this);
4705 }
4706 }
4707
4708 VPRegionBlock(Type *CanIVTy, DebugLoc DL, VPBlockBase *Entry,
4709 VPBlockBase *Exiting, const std::string &Name = "")
4710 : VPRegionBlock(Entry, Exiting, Name) {
4711 CanIVInfo = std::make_unique<VPCanonicalIVInfo>(CanIVTy, DL, this);
4712 }
4713
4714public:
4715 ~VPRegionBlock() override = default;
4716
4717 /// Method to support type inquiry through isa, cast, and dyn_cast.
4718 static inline bool classof(const VPBlockBase *V) {
4719 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
4720 }
4721
4722 const VPBlockBase *getEntry() const { return Entry; }
4723 VPBlockBase *getEntry() { return Entry; }
4724
4725 /// Set \p EntryBlock as the entry VPBlockBase of this VPRegionBlock. \p
4726 /// EntryBlock must have no predecessors.
4727 void setEntry(VPBlockBase *EntryBlock) {
4728 assert(!EntryBlock->hasPredecessors() &&
4729 "Entry block cannot have predecessors.");
4730 Entry = EntryBlock;
4731 EntryBlock->setParent(this);
4732 }
4733
4734 const VPBlockBase *getExiting() const { return Exiting; }
4735 VPBlockBase *getExiting() { return Exiting; }
4736
4737 /// Set \p ExitingBlock as the exiting VPBlockBase of this VPRegionBlock. \p
4738 /// ExitingBlock must have no successors.
4739 void setExiting(VPBlockBase *ExitingBlock) {
4740 assert(!ExitingBlock->hasSuccessors() &&
4741 "Exit block cannot have successors.");
4742 Exiting = ExitingBlock;
4743 ExitingBlock->setParent(this);
4744 }
4745
4746 /// Returns the pre-header VPBasicBlock of the loop region.
4748 assert(!isReplicator() && "should only get pre-header of loop regions");
4749 return getSinglePredecessor()->getExitingBasicBlock();
4750 }
4751
4752 /// An indicator whether this region is to generate multiple replicated
4753 /// instances of output IR corresponding to its VPBlockBases.
4754 bool isReplicator() const { return !CanIVInfo; }
4755
4756 /// Return the VPBranchOnMaskRecipe from the entry block of this replicating
4757 /// region.
4758 const VPBranchOnMaskRecipe *getEntryBranchOnMask() const;
4760 return const_cast<VPBranchOnMaskRecipe *>(
4761 static_cast<const VPRegionBlock *>(this)->getEntryBranchOnMask());
4762 }
4763
4764 /// The method which generates the output IR instructions that correspond to
4765 /// this VPRegionBlock, thereby "executing" the VPlan.
4766 void execute(VPTransformState *State) override;
4767
4768 // Return the cost of this region.
4769 InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override;
4770
4771#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4772 /// Print this VPRegionBlock to \p O (recursively), prefixing all lines with
4773 /// \p Indent. \p SlotTracker is used to print unnamed VPValue's using
4774 /// consequtive numbers.
4775 ///
4776 /// Note that the numbering is applied to the whole VPlan, so printing
4777 /// individual regions is consistent with the whole VPlan printing.
4778 void print(raw_ostream &O, const Twine &Indent,
4779 VPSlotTracker &SlotTracker) const override;
4780 using VPBlockBase::print; // Get the print(raw_stream &O) version.
4781#endif
4782
4783 /// Clone all blocks in the single-entry single-exit region of the block and
4784 /// their recipes without updating the operands of the cloned recipes.
4785 VPRegionBlock *clone() override;
4786
4787 /// Remove the current region from its VPlan, connecting its predecessor to
4788 /// its entry, and its exiting block to its successor.
4789 void dissolveToCFGLoop();
4790
4791 /// Get the canonical IV increment instruction if it exists. Otherwise, create
4792 /// a new increment before the terminator and return it. The canonical IV
4793 /// increment is subject to DCE if unused, unlike the canonical IV itself.
4794 VPInstruction *getOrCreateCanonicalIVIncrement();
4795
4796 /// Return the canonical induction variable of the region, null for
4797 /// replicating regions.
4799 return CanIVInfo ? CanIVInfo->getRegionValue() : nullptr;
4800 }
4802 return CanIVInfo ? CanIVInfo->getRegionValue() : nullptr;
4803 }
4804
4805 /// Return the type of the canonical IV for loop regions.
4807 return CanIVInfo->getRegionValue()->getType();
4808 }
4809
4810 /// Return the header mask of the region, or null if not set.
4812 return CanIVInfo ? CanIVInfo->getHeaderMask() : nullptr;
4813 }
4814
4815 /// Return the header mask if it exists and is used, or null otherwise. The
4816 /// mask is materialized into concrete recipes only after costing, so cost and
4817 /// codegen accounting sites use this to skip an unused mask.
4819 VPRegionValue *HeaderMask = getHeaderMask();
4820 return HeaderMask && HeaderMask->getNumUsers() > 0 ? HeaderMask : nullptr;
4821 }
4822
4823 /// Create the header mask for the region and return it. Must only be called
4824 /// on loop regions that don't already have a header mask.
4826 assert(CanIVInfo && "Can only create header mask for loop regions");
4827 return CanIVInfo->createHeaderMask();
4828 }
4829
4830 /// Return the region values of the loop region (canonical IV, header mask)
4831 /// or an empty vector for replicate regions.
4833 if (!CanIVInfo)
4834 return {};
4835 SmallVector<VPRegionValue *, 2> R = {CanIVInfo->getRegionValue()};
4836 if (auto *HM = CanIVInfo->getHeaderMask())
4837 R.push_back(HM);
4838 return R;
4839 }
4840
4841 /// Indicates if NUW is set for the canonical IV increment, for loop regions.
4842 bool hasCanonicalIVNUW() const { return CanIVInfo->hasNUW(); }
4843
4844 /// Unsets NUW for the canonical IV increment \p Increment, for loop regions.
4846 assert(Increment && "Must provide increment to clear");
4847 Increment->dropPoisonGeneratingFlags();
4848 CanIVInfo->clearNUW();
4849 }
4850};
4851
4853 return getParent()->getParent();
4854}
4855
4857 return getParent()->getParent();
4858}
4859
4860/// VPlan models a candidate for vectorization, encoding various decisions take
4861/// to produce efficient output IR, including which branches, basic-blocks and
4862/// output IR instructions to generate, and their cost. VPlan holds a
4863/// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry
4864/// VPBasicBlock.
4865class VPlan {
4866 friend class VPlanPrinter;
4867 friend class VPSlotTracker;
4868
4869 /// VPBasicBlock corresponding to the original preheader. Used to place
4870 /// VPExpandSCEV recipes for expressions used during skeleton creation and the
4871 /// rest of VPlan execution.
4872 /// When this VPlan is used for the epilogue vector loop, the entry will be
4873 /// replaced by a new entry block created during skeleton creation.
4874 VPBasicBlock *Entry;
4875
4876 /// VPIRBasicBlock wrapping the header of the original scalar loop.
4877 VPIRBasicBlock *ScalarHeader;
4878
4879 /// Immutable list of VPIRBasicBlocks wrapping the exit blocks of the original
4880 /// scalar loop. Note that some exit blocks may be unreachable at the moment,
4881 /// e.g. if the scalar epilogue always executes.
4883
4884 /// Holds the VFs applicable to this VPlan.
4886
4887 /// Holds the UFs applicable to this VPlan. If empty, the VPlan is valid for
4888 /// any UF.
4890
4891 /// Holds the name of the VPlan, for printing.
4892 std::string Name;
4893
4894 /// Represents the trip count of the original loop, for folding
4895 /// the tail.
4896 VPValue *TripCount = nullptr;
4897
4898 /// Represents the backedge taken count of the original loop, for folding
4899 /// the tail. It equals TripCount - 1.
4900 VPSymbolicValue *BackedgeTakenCount = nullptr;
4901
4902 /// Represents the vector trip count.
4903 VPSymbolicValue VectorTripCount;
4904
4905 /// Represents the vectorization factor of the loop.
4906 VPSymbolicValue VF;
4907
4908 /// Represents the unroll factor of the loop.
4909 VPSymbolicValue UF;
4910
4911 /// Represents the loop-invariant VF * UF of the vector loop region.
4912 VPSymbolicValue VFxUF;
4913
4914 /// Contains all the external definitions created for this VPlan, as a mapping
4915 /// from IR Values to VPIRValues.
4917
4918 /// Blocks allocated and owned by the VPlan. They will be deleted once the
4919 /// VPlan is destroyed.
4920 SmallVector<VPBlockBase *> CreatedBlocks;
4921
4922 /// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
4923 /// wrapping the original header of the scalar loop. The vector loop will have
4924 /// index type \p IdxTy.
4925 VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader, Type *IdxTy)
4926 : Entry(Entry), ScalarHeader(ScalarHeader), VectorTripCount(IdxTy),
4927 VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
4928 Entry->setPlan(this);
4929 assert(ScalarHeader->getNumSuccessors() == 0 &&
4930 "scalar header must be a leaf node");
4931 }
4932
4933public:
4934 /// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the
4935 /// original preheader and scalar header of \p L, to be used as entry and
4936 /// scalar header blocks of the new VPlan. The vector loop will have index
4937 /// type \p IdxTy.
4938 VPlan(Loop *L, Type *IdxTy);
4939
4940 /// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock
4941 /// wrapping \p ScalarHeaderBB and vector loop index of type \p IdxTy.
4942 VPlan(BasicBlock *ScalarHeaderBB, Type *IdxTy)
4943 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
4944 setEntry(createVPBasicBlock("preheader"));
4945 ScalarHeader = createVPIRBasicBlock(ScalarHeaderBB);
4946 }
4947
4949
4951 Entry = VPBB;
4952 VPBB->setPlan(this);
4953 }
4954
4955 /// Generate the IR code for this VPlan.
4956 void execute(VPTransformState *State);
4957
4958 /// Return the cost of this plan.
4960
4961 VPBasicBlock *getEntry() { return Entry; }
4962 const VPBasicBlock *getEntry() const { return Entry; }
4963
4964 /// Returns the preheader of the vector loop region, if one exists, or null
4965 /// otherwise.
4967 const VPRegionBlock *VectorRegion = getVectorLoopRegion();
4968 return VectorRegion
4969 ? cast<VPBasicBlock>(VectorRegion->getSinglePredecessor())
4970 : nullptr;
4971 }
4972
4973 /// Returns the VPRegionBlock of the vector loop.
4976
4977 /// Returns true if this VPlan is for an outer loop, i.e., its vector
4978 /// loop region contains a nested loop region.
4979 LLVM_ABI_FOR_TEST bool isOuterLoop() const;
4980
4981 /// Returns true if the vector loop region is tail-folded.
4982 bool hasTailFolded() const {
4983 const VPRegionBlock *LoopRegion = getVectorLoopRegion();
4984 return LoopRegion && LoopRegion->getHeaderMask();
4985 }
4986
4987 /// Returns true if the plan requires a scalar epilogue after the vector
4988 /// loop. Must be called before removeBranchOnConst.
4990 const VPBasicBlock *MiddleVPBB = getMiddleBlock();
4991 return MiddleVPBB->getSingleSuccessor() == getScalarPreheader();
4992 }
4993
4994 /// Returns the 'middle' block of the plan, that is the block that selects
4995 /// whether to execute the scalar tail loop or the exit block from the loop
4996 /// latch. If there is an early exit from the vector loop, the middle block
4997 /// conceptully has the early exit block as third successor, split accross 2
4998 /// VPBBs. In that case, the second VPBB selects whether to execute the scalar
4999 /// tail loop or the exit block. If the scalar tail loop or exit block are
5000 /// known to always execute, the middle block may branch directly to that
5001 /// block. This function cannot be called once the vector loop region has been
5002 /// removed.
5004 VPRegionBlock *LoopRegion = getVectorLoopRegion();
5005 assert(
5006 LoopRegion &&
5007 "cannot call the function after vector loop region has been removed");
5008 // The middle block is always the last successor of the region.
5009 return cast<VPBasicBlock>(LoopRegion->getSuccessors().back());
5010 }
5011
5013 return const_cast<VPlan *>(this)->getMiddleBlock();
5014 }
5015
5016 /// Return the VPBasicBlock for the preheader of the scalar loop.
5019 getScalarHeader()->getSinglePredecessor());
5020 }
5021
5022 /// Return the VPIRBasicBlock wrapping the header of the scalar loop.
5023 VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; }
5024
5025 /// Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of
5026 /// the original scalar loop.
5027 ArrayRef<VPIRBasicBlock *> getExitBlocks() const { return ExitBlocks; }
5028
5029 /// Returns true if \p VPBB is an exit block.
5030 bool isExitBlock(VPBlockBase *VPBB);
5031
5032 /// The trip count of the original loop.
5034 assert(TripCount && "trip count needs to be set before accessing it");
5035 return TripCount;
5036 }
5037
5038 /// Set the trip count assuming it is currently null; if it is not - use
5039 /// resetTripCount().
5040 void setTripCount(VPValue *NewTripCount) {
5041 assert(!TripCount && NewTripCount && "TripCount should not be set yet.");
5042 TripCount = NewTripCount;
5043 }
5044
5045 /// Resets the trip count for the VPlan. The caller must make sure all uses of
5046 /// the original trip count have been replaced.
5047 void resetTripCount(VPValue *NewTripCount) {
5048 assert(TripCount && NewTripCount && TripCount->user_empty() &&
5049 "TripCount must be set when resetting");
5050 TripCount = NewTripCount;
5051 }
5052
5053 /// The backedge taken count of the original loop.
5055 // BTC shares the canonical IV type with VectorTripCount.
5056 if (!BackedgeTakenCount)
5057 BackedgeTakenCount = new VPSymbolicValue(VectorTripCount.getType());
5058 return BackedgeTakenCount;
5059 }
5060 VPValue *getBackedgeTakenCount() const { return BackedgeTakenCount; }
5061
5062 /// The vector trip count.
5063 VPSymbolicValue &getVectorTripCount() { return VectorTripCount; }
5064
5065 /// Returns the VF of the vector loop region.
5066 VPSymbolicValue &getVF() { return VF; };
5067 const VPSymbolicValue &getVF() const { return VF; };
5068
5069 /// Returns the UF of the vector loop region.
5070 VPSymbolicValue &getUF() { return UF; };
5071
5072 /// Returns VF * UF of the vector loop region.
5073 VPSymbolicValue &getVFxUF() { return VFxUF; }
5074
5077 }
5078
5079 const DataLayout &getDataLayout() const {
5081 }
5082
5083 void addVF(ElementCount VF) { VFs.insert(VF); }
5084
5086 assert(hasVF(VF) && "Cannot set VF not already in plan");
5087 VFs.clear();
5088 VFs.insert(VF);
5089 }
5090
5091 /// Remove \p VF from the plan.
5093 assert(hasVF(VF) && "tried to remove VF not present in plan");
5094 VFs.remove(VF);
5095 }
5096
5097 bool hasVF(ElementCount VF) const { return VFs.count(VF); }
5098 bool hasScalableVF() const {
5099 return any_of(VFs, [](ElementCount VF) { return VF.isScalable(); });
5100 }
5101
5102 /// Returns an iterator range over all VFs of the plan.
5105 return VFs;
5106 }
5107
5108 /// Returns the single VF of the plan, asserting that the plan has exactly
5109 /// one VF.
5111 assert(VFs.size() == 1 && "expected plan with single VF");
5112 return VFs[0];
5113 }
5114
5115 bool hasScalarVFOnly() const {
5116 bool HasScalarVFOnly = VFs.size() == 1 && VFs[0].isScalar();
5117 assert(HasScalarVFOnly == hasVF(ElementCount::getFixed(1)) &&
5118 "Plan with scalar VF should only have a single VF");
5119 return HasScalarVFOnly;
5120 }
5121
5122 bool hasUF(unsigned UF) const { return UFs.empty() || UFs.contains(UF); }
5123
5124 /// Returns the concrete UF of the plan, after unrolling.
5125 unsigned getConcreteUF() const {
5126 assert(UFs.size() == 1 && "Expected a single UF");
5127 return UFs[0];
5128 }
5129
5130 void setUF(unsigned UF) {
5131 assert(hasUF(UF) && "Cannot set the UF not already in plan");
5132 UFs.clear();
5133 UFs.insert(UF);
5134 }
5135
5136 /// Returns true if the VPlan already has been unrolled, i.e. it has a single
5137 /// concrete UF.
5138 bool isUnrolled() const { return UFs.size() == 1; }
5139
5140 /// Return a string with the name of the plan and the applicable VFs and UFs.
5141 std::string getName() const;
5142
5143 void setName(const Twine &newName) { Name = newName.str(); }
5144
5145 /// Gets the live-in VPIRValue for \p V or adds a new live-in (if none exists
5146 /// yet) for \p V.
5148 assert(V && "Trying to get or add the VPIRValue of a null Value");
5149 auto [It, Inserted] = LiveIns.try_emplace(V);
5150 if (Inserted) {
5151 if (auto *CI = dyn_cast<ConstantInt>(V))
5152 It->second = new VPConstantInt(CI);
5153 else
5154 It->second = new VPIRValue(V);
5155 }
5156
5157 assert(isa<VPIRValue>(It->second) &&
5158 "Only VPIRValues should be in mapping");
5159 return It->second;
5160 }
5162 assert(V && "Trying to get or add the VPIRValue of a null VPIRValue");
5163 return getOrAddLiveIn(V->getValue());
5164 }
5165
5166 /// Return a VPIRValue wrapping i1 true.
5167 VPIRValue *getTrue() { return getConstantInt(1, 1); }
5168
5169 /// Return a VPIRValue wrapping i1 false.
5170 VPIRValue *getFalse() { return getConstantInt(1, 0); }
5171
5172 /// Return a VPIRValue wrapping the null value of type \p Ty.
5173 VPIRValue *getZero(Type *Ty) { return getConstantInt(Ty, 0); }
5174
5175 /// Return a VPIRValue wrapping the AllOnes value of type \p Ty.
5177 return getConstantInt(APInt::getAllOnes(Ty->getIntegerBitWidth()));
5178 }
5179
5180 /// Return a VPIRValue wrapping a ConstantInt with the given type and value.
5181 VPIRValue *getConstantInt(Type *Ty, uint64_t Val, bool IsSigned = false) {
5182 return getOrAddLiveIn(ConstantInt::get(Ty, Val, IsSigned));
5183 }
5184
5185 /// Return a VPIRValue wrapping a ConstantInt with the given bitwidth and
5186 /// value.
5188 bool IsSigned = false) {
5189 return getConstantInt(APInt(BitWidth, Val, IsSigned));
5190 }
5191
5192 /// Return a VPIRValue wrapping a ConstantInt with the given APInt value.
5194 return getOrAddLiveIn(ConstantInt::get(getContext(), Val));
5195 }
5196
5197 /// Return a VPIRValue wrapping a poison value of type \p Ty.
5199 return getOrAddLiveIn(PoisonValue::get(Ty));
5200 }
5201
5202 /// Return the live-in VPIRValue for \p V, if there is one or nullptr
5203 /// otherwise.
5204 VPIRValue *getLiveIn(Value *V) const { return LiveIns.lookup(V); }
5205
5206 /// Return the list of live-in VPValues available in the VPlan.
5207 auto getLiveIns() const { return LiveIns.values(); }
5208
5209#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5210 /// Print the live-ins of this VPlan to \p O.
5211 void printLiveIns(raw_ostream &O) const;
5212
5213 /// Print this VPlan to \p O.
5214 LLVM_ABI_FOR_TEST void print(raw_ostream &O) const;
5215
5216 /// Print this VPlan in DOT format to \p O.
5217 LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const;
5218
5219 /// Dump the plan to stderr (for debugging).
5220 LLVM_DUMP_METHOD void dump() const;
5221#endif
5222
5223 /// Clone the current VPlan, update all VPValues of the new VPlan and cloned
5224 /// recipes to refer to the clones, and return it.
5226
5227 /// Create a new VPBasicBlock with \p Name and containing \p Recipe if
5228 /// present. The returned block is owned by the VPlan and deleted once the
5229 /// VPlan is destroyed.
5231 VPRecipeBase *Recipe = nullptr) {
5232 auto *VPB = new VPBasicBlock(Name, Recipe);
5233 VPB->setNumber(CreatedBlocks.size());
5234 CreatedBlocks.push_back(VPB);
5235 return VPB;
5236 }
5237
5238 /// Create a new loop region with a canonical IV using \p CanIVTy and
5239 /// \p DL. Use \p Name as the region's name and set entry and exiting blocks
5240 /// to \p Entry and \p Exiting respectively, if provided. The returned block
5241 /// is owned by the VPlan and deleted once the VPlan is destroyed.
5243 const std::string &Name = "",
5244 VPBlockBase *Entry = nullptr,
5245 VPBlockBase *Exiting = nullptr) {
5246 auto *VPB = new VPRegionBlock(CanIVTy, DL, Entry, Exiting, Name);
5247 VPB->setNumber(CreatedBlocks.size());
5248 CreatedBlocks.push_back(VPB);
5249 return VPB;
5250 }
5251
5252 /// Create a new replicate region with \p Entry, \p Exiting and \p Name. The
5253 /// returned block is owned by the VPlan and deleted once the VPlan is
5254 /// destroyed.
5256 const std::string &Name = "") {
5257 auto *VPB = new VPRegionBlock(Entry, Exiting, Name);
5258 VPB->setNumber(CreatedBlocks.size());
5259 CreatedBlocks.push_back(VPB);
5260 return VPB;
5261 }
5262
5263 /// Create a VPIRBasicBlock wrapping \p IRBB, but do not create
5264 /// VPIRInstructions wrapping the instructions in t\p IRBB. The returned
5265 /// block is owned by the VPlan and deleted once the VPlan is destroyed.
5267
5268 /// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
5269 /// instructions in \p IRBB, except its terminator which is managed by the
5270 /// successors of the block in VPlan. The returned block is owned by the VPlan
5271 /// and deleted once the VPlan is destroyed.
5273
5274 unsigned getMaxBlockNumber() const { return CreatedBlocks.size(); }
5275
5276 /// Returns true if the VPlan is based on a loop with an early exit.
5277 bool hasEarlyExit() const {
5278 unsigned NumExitPredecessors =
5279 sum_of(map_range(ExitBlocks, [](VPIRBasicBlock *EB) {
5280 return EB->getNumPredecessors();
5281 }));
5282
5283 // If the scalar preheader executes unconditionally, there's no branch from
5284 // middle block to any exit. If there is any edge to an exit block
5285 // remaining, it must be an early exit.
5286 VPBasicBlock *ScalarPH = getScalarPreheader();
5287 VPBlockBase *ScalarPHPred =
5288 ScalarPH ? ScalarPH->getSinglePredecessor() : nullptr;
5289 if (ScalarPHPred && ScalarPHPred->getNumSuccessors() == 1)
5290 return NumExitPredecessors >= 1;
5291
5292 // Otherwise there must be at least 2 edges to exit blocks (from the middle
5293 // block and the early exiting edge).
5294 return NumExitPredecessors > 1;
5295 }
5296
5297 /// Returns true if the scalar tail may execute after the vector loop, i.e.
5298 /// if the middle block is a predecessor of the scalar preheader. Note that
5299 /// this relies on unneeded branches to the scalar tail loop being removed.
5300 bool hasScalarTail() const {
5301 auto *ScalarPH = getScalarPreheader();
5302 return ScalarPH &&
5303 is_contained(ScalarPH->getPredecessors(), getMiddleBlock());
5304 }
5305
5306 /// The type of the canonical induction variable of the vector loop.
5307 Type *getIndexType() const { return VF.getType(); }
5308};
5309
5310#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5311inline raw_ostream &operator<<(raw_ostream &OS, const VPlan &Plan) {
5312 Plan.print(OS);
5313 return OS;
5314}
5315#endif
5316
5317} // end namespace llvm
5318
5319#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
unsigned uint64_t
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)
This file implements methods to test, set and extract typed bits from packed unsigned integers.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
#define LLVM_ABI_FOR_TEST
Definition Compiler.h:220
#define LLVM_PACKED_START
Definition Compiler.h:571
dxil translate DXIL Translate Metadata
Hexagon Common GEP
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 F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
static Interval intersect(const Interval &I1, const Interval &I2)
This file provides utility analysis objects describing memory locations.
#define T
#define P(N)
static StringRef getName(Value *V)
static bool mayHaveSideEffects(MachineInstr &MI)
SI Fold Operands
Func MI getDebugLoc()))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static const BasicSubtargetSubTypeKV * find(StringRef S, ArrayRef< BasicSubtargetSubTypeKV > A)
Find KV in array using binary search.
This file contains the declarations of the entities induced by Vectorization Plans,...
#define VP_CLASSOF_IMPL(VPRecipeID)
Definition VPlan.h:596
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:231
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & back() const
Get the last element.
Definition ArrayRef.h:150
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
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:512
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags fromRaw(unsigned Flags)
unsigned getRaw() const
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 ...
bool isCast() const
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.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
Root of the metadata hierarchy.
Definition Metadata.h:64
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an assumption made using SCEV expressions which can be checked at run-time.
This class represents an analyzed expression in the program.
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:345
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.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
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:46
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:4109
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPActiveLaneMaskPHIRecipe(VPValue *StartMask, DebugLoc DL)
Definition VPlan.h:4103
~VPActiveLaneMaskPHIRecipe() override=default
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4453
RecipeListTy::const_iterator const_iterator
Definition VPlan.h:4481
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4528
RecipeListTy::const_reverse_iterator const_reverse_iterator
Definition VPlan.h:4483
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4480
RecipeListTy & getRecipeList()
Returns a reference to the list of recipes.
Definition VPlan.h:4506
iplist< VPRecipeBase > RecipeListTy
Definition VPlan.h:4464
iterator end()
Definition VPlan.h:4490
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4488
RecipeListTy::reverse_iterator reverse_iterator
Definition VPlan.h:4482
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4541
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:800
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
~VPBasicBlock() override
Definition VPlan.h:4474
const_reverse_iterator rbegin() const
Definition VPlan.h:4494
reverse_iterator rend()
Definition VPlan.h:4495
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition VPlan.h:4468
VPRecipeBase & back()
Definition VPlan.h:4503
const VPRecipeBase & front() const
Definition VPlan.h:4500
const_iterator begin() const
Definition VPlan.h:4489
VPRecipeBase & front()
Definition VPlan.h:4501
const VPRecipeBase & back() const
Definition VPlan.h:4502
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4519
bool empty() const
Definition VPlan.h:4499
const_iterator end() const
Definition VPlan.h:4491
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition VPlan.h:4514
static RecipeListTy VPBasicBlock::* getSublistAccess(VPRecipeBase *)
Returns a pointer to a member of the recipe list.
Definition VPlan.h:4509
reverse_iterator rbegin()
Definition VPlan.h:4493
friend class VPlan
Definition VPlan.h:4454
size_t size() const
Definition VPlan.h:4498
const_reverse_iterator rend() const
Definition VPlan.h:4496
VPBasicBlock(VPBlockTy BlockSC, const Twine &Name="")
Definition VPlan.h:4470
VPValue * getIncomingValue(unsigned Idx) const
Return incoming value number Idx.
Definition VPlan.h:3039
VPValue * getMask(unsigned Idx) const
Return mask number Idx.
Definition VPlan.h:3044
VPBlendRecipe(PHINode *Phi, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL)
The blend operation is a User of the incoming values and of their respective masks,...
Definition VPlan.h:2998
unsigned getNumIncomingValues() const
Return the number of incoming values, taking into account when normalized the first incoming value wi...
Definition VPlan.h:3034
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition VPlan.h:3056
VPBlendRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
Definition VPlan.h:3021
VPBlendRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3019
void setMask(unsigned Idx, VPValue *V)
Set mask number Idx to V.
Definition VPlan.h:3050
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:3030
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:95
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:316
VPRegionBlock * getParent()
Definition VPlan.h:193
VPBlocksTy & getPredecessors()
Definition VPlan.h:230
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:227
LLVM_DUMP_METHOD void dump() const
Dump this VPBlockBase to dbgs().
Definition VPlan.h:392
void setName(const Twine &newName)
Definition VPlan.h:186
size_t getNumSuccessors() const
Definition VPlan.h:244
iterator_range< VPBlockBase ** > successors()
Definition VPlan.h:226
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:338
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:685
SmallVectorImpl< VPBlockBase * > VPBlocksTy
Definition VPlan.h:180
virtual ~VPBlockBase()=default
unsigned getNumber() const
Return the unique number of the block.
Definition VPlan.h:358
const VPBlocksTy & getHierarchicalPredecessors()
Definition VPlan.h:274
void setNumber(unsigned N)
Set the unique number of the block, used for dominator tree.
Definition VPlan.h:361
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
Definition VPlan.h:351
size_t getNumPredecessors() const
Definition VPlan.h:245
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:307
VPBlockBase * getEnclosingBlockWithPredecessors()
Definition VPlan.cpp:258
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
Definition VPlan.h:344
enum :unsigned char { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC } VPBlockTy
An enumeration for keeping track of the concrete subclass of VPBlockBase that are actually instantiat...
Definition VPlan.h:103
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:222
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:229
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
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:230
const VPRegionBlock * getParent() const
Definition VPlan.h:194
const std::string & getName() const
Definition VPlan.h:184
void clearSuccessors()
Remove all the successors of this block.
Definition VPlan.h:326
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition VPlan.h:298
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:240
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:264
void clearPredecessors()
Remove all the predecessor of this block.
Definition VPlan.h:323
friend class VPBlockUtils
Definition VPlan.h:96
unsigned getVPBlockID() const
Definition VPlan.h:191
void printAsOperand(raw_ostream &OS, bool PrintType=false) const
Definition VPlan.h:371
void swapPredecessors()
Swap predecessors of the block.
Definition VPlan.h:330
VPBlocksTy & getSuccessors()
Definition VPlan.h:219
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
Definition VPlan.cpp:250
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
Definition VPlan.h:287
void setParent(VPRegionBlock *P)
Definition VPlan.h:204
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:280
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:234
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:218
VPBlockBase(VPBlockTy SC, const std::string &N)
Definition VPlan.h:401
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:3545
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL, const VPIRMetadata &Metadata={})
Definition VPlan.h:3547
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Definition VPlan.h:3568
VPBranchOnMaskRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3552
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition VPlan.h:3576
VPlan-based builder utility analogous to IRBuilder.
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4657
VPRegionValue * getHeaderMask() const
Definition VPlan.h:4653
VPRegionValue * getRegionValue()
Definition VPlan.h:4650
VPCanonicalIVInfo(Type *Ty, DebugLoc DL, VPRegionBlock *Region)
Definition VPlan.h:4647
const VPRegionValue * getRegionValue() const
Definition VPlan.h:4651
bool hasNUW() const
Definition VPlan.h:4665
VPCurrentIterationPHIRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4141
VPCurrentIterationPHIRecipe(VPValue *StartIV, DebugLoc DL)
Definition VPlan.h:4135
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPCurrentIterationPHIRecipe.
Definition VPlan.h:4153
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition VPlan.h:4147
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:4160
~VPCurrentIterationPHIRecipe() override=default
InductionDescriptor::InductionKind getInductionKind() const
Definition VPlan.h:4271
VPValue * getIndex() const
Definition VPlan.h:4268
const FPMathOperator * getFPBinOp() const
Definition VPlan.h:4270
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
Definition VPlan.h:4242
VPValue * getStepValue() const
Definition VPlan.h:4269
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPDerivedIVRecipe.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition VPlan.h:4259
VPDerivedIVRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4252
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPDerivedIVRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:4274
VPValue * getStartValue() const
Definition VPlan.h:4267
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition VPlan.h:4078
void printRecipe(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 VPExpandSCEVRecipe.
Definition VPlan.h:4083
VPExpandSCEVRecipe(const SCEV *Expr)
const SCEV * getSCEV() const
Definition VPlan.h:4089
VPExpandSCEVRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4074
~VPExpandSCEVRecipe() override=default
void execute(VPTransformState &State) override
Method for generating code, must not be called as this recipe is abstract.
Definition VPlan.h:3722
bool isVectorToScalar() const
Returns true if this VPExpressionRecipe produces a single scalar.
VPExpressionRecipe(VPWidenCastRecipe *Ext, VPWidenRecipe *Neg, VPReductionRecipe *Red)
Definition VPlan.h:3638
VPExpressionRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3691
SmallVector< VPSingleDefRecipe * > decompose()
Return and insert the recipes of the expression back into the VPlan, directly before the current reci...
~VPExpressionRecipe() override
Definition VPlan.h:3679
ExpressionTypes getExpressionType() const
Returns the expression type of this recipe.
Definition VPlan.h:3714
VPExpressionRecipe(VPWidenCastRecipe *Ext, VPReductionRecipe *Red)
Definition VPlan.h:3636
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:3654
VPExpressionRecipe(ExpressionTypes ExpressionType, ArrayRef< VPSingleDefRecipe * > ExpressionRecipes)
Construct a new VPExpressionRecipe by internalizing recipes in ExpressionRecipes.
VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1, VPWidenRecipe *Mul, VPWidenRecipe *Neg, VPReductionRecipe *Red)
Definition VPlan.h:3658
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
unsigned getVFScaleFactor() const
Definition VPlan.h:3716
VPExpressionRecipe(VPWidenRecipe *Mul, VPReductionRecipe *Red)
Definition VPlan.h:3652
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition VPlan.h:2482
VPHeaderPHIRecipe(VPRecipeTy VPRecipeID, Instruction *UnderlyingInstr, VPValue *Start, Type *ResultTy, DebugLoc DL)
Definition VPlan.h:2489
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this header phi recipe.
VPHeaderPHIRecipe(VPRecipeTy VPRecipeID, Instruction *UnderlyingInstr, VPValue *Start, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:2484
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition VPlan.h:2493
void addBackedgeValue(VPValue *V)
Add V as the incoming value from the loop backedge.
Definition VPlan.h:2535
static bool classof(const VPSingleDefRecipe *R)
Definition VPlan.h:2506
static bool classof(const VPValue *V)
Definition VPlan.h:2503
void printRecipe(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:2529
void setBackedgeValue(VPValue *V)
Update the incoming value from the loop backedge.
Definition VPlan.h:2532
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2518
void setStartValue(VPValue *V)
Update the start value of the recipe.
Definition VPlan.h:2526
static bool classof(const VPRecipeBase *R)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition VPlan.h:2499
VPValue * getStartValue() const
Definition VPlan.h:2521
void execute(VPTransformState &State) override=0
Generate the phi nodes.
~VPHeaderPHIRecipe() override=default
A recipe representing a sequence of load -> update -> store as part of a histogram operation.
Definition VPlan.h:2209
void execute(VPTransformState &State) override
Produce a vectorized histogram operation.
VPHistogramRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2222
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHistogramRecipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
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:2239
unsigned getOpcode() const
Definition VPlan.h:2235
VP_CLASSOF_IMPL(VPRecipeBase::VPHistogramSC)
~VPHistogramRecipe() override=default
VPHistogramRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:2214
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4606
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:497
BasicBlock * getIRBasicBlock() const
Definition VPlan.h:4630
static bool classof(const VPBlockBase *V)
Definition VPlan.h:4620
~VPIRBasicBlock() override=default
friend class VPlan
Definition VPlan.h:4607
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:522
Class to record and manage LLVM IR flags.
Definition VPlan.h:705
WrapFlagsTy getNoWrapFlagsOrNone() const
Definition VPlan.h:1046
FastMathFlagsTy FMFs
Definition VPlan.h:794
ReductionFlagsTy ReductionFlags
Definition VPlan.h:796
VPIRFlags(RecurKind Kind, bool IsOrdered, bool IsInLoop, FastMathFlags FMFs)
Definition VPlan.h:887
LLVM_ABI_FOR_TEST bool flagsValidForOpcode(unsigned Opcode) const
Returns true if the set flags are valid for Opcode.
VPIRFlags(DisjointFlagsTy DisjointFlags)
Definition VPlan.h:867
VPIRFlags(WrapFlagsTy WrapFlags)
Definition VPlan.h:853
WrapFlagsTy WrapFlags
Definition VPlan.h:788
void printFlags(raw_ostream &O) const
VPIRFlags(CmpInst::Predicate Pred, FastMathFlags FMFs)
Definition VPlan.h:846
bool hasFastMathFlags() const
Returns true if the recipe has fast-math flags.
Definition VPlan.h:1011
static VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
bool isReductionOrdered() const
Definition VPlan.h:1072
TruncFlagsTy TruncFlags
Definition VPlan.h:789
CmpInst::Predicate getPredicate() const
Definition VPlan.h:983
WrapFlagsTy getNoWrapFlags() const
Definition VPlan.h:1056
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlagsOrNone() const
uint8_t AllFlags[2]
Definition VPlan.h:797
void transferFlags(VPIRFlags &Other)
Definition VPlan.h:892
ExactFlagsTy ExactFlags
Definition VPlan.h:791
bool hasNoSignedWrap() const
Definition VPlan.h:1035
void intersectFlags(const VPIRFlags &Other)
Only keep flags also present in Other.
bool isDisjoint() const
Definition VPlan.h:1060
VPIRFlags(TruncFlagsTy TruncFlags)
Definition VPlan.h:858
VPIRFlags(FastMathFlags FMFs)
Definition VPlan.h:863
VPIRFlags(NonNegFlagsTy NonNegFlags)
Definition VPlan.h:872
VPIRFlags(CmpInst::Predicate Pred)
Definition VPlan.h:841
uint8_t GEPFlagsStorage
Definition VPlan.h:792
VPIRFlags(ExactFlagsTy ExactFlags)
Definition VPlan.h:877
bool isNonNeg() const
Definition VPlan.h:1018
GEPNoWrapFlags getGEPNoWrapFlags() const
Definition VPlan.h:1001
bool hasPredicate() const
Returns true if the recipe has a comparison predicate.
Definition VPlan.h:1006
LLVM_ABI_FOR_TEST bool hasRequiredFlagsForOpcode(unsigned Opcode, Type *ResultTy) const
Returns true if Opcode with scalar result type ResultTy has its required flags set.
DisjointFlagsTy DisjointFlags
Definition VPlan.h:790
void setPredicate(CmpInst::Predicate Pred)
Definition VPlan.h:991
bool hasNoUnsignedWrap() const
Definition VPlan.h:1024
FCmpFlagsTy FCmpFlags
Definition VPlan.h:795
NonNegFlagsTy NonNegFlags
Definition VPlan.h:793
bool isReductionInLoop() const
Definition VPlan.h:1078
void dropPoisonGeneratingFlags()
Drop all poison-generating flags.
Definition VPlan.h:903
void applyFlags(Instruction &I) const
Apply the IR flags to I.
Definition VPlan.h:940
VPIRFlags(GEPNoWrapFlags GEPFlags)
Definition VPlan.h:882
uint8_t CmpPredStorage
Definition VPlan.h:787
RecurKind getRecurKind() const
Definition VPlan.h:1066
VPIRFlags(Instruction &I)
Definition VPlan.h:803
Instruction & getInstruction() const
Definition VPlan.h:1794
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first part of operand Op.
Definition VPlan.h:1802
~VPIRInstruction() override=default
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPIRInstruction * clone() override
Clone the current recipe.
Definition VPlan.h:1781
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition VPlan.h:1808
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.
bool usesScalars(const VPValue *Op) const override
Returns true if the VPUser uses scalars of operand Op.
Definition VPlan.h:1796
VPIRInstruction(Instruction &I)
VPIRInstruction::create() should be used to create VPIRInstructions, as subclasses may need to be cre...
Definition VPlan.h:1769
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Helper to manage IR metadata for recipes.
Definition VPlan.h:1182
VPIRMetadata & operator=(const VPIRMetadata &Other)=default
MDNode * getMetadata(unsigned Kind) const
Get metadata of kind Kind. Returns nullptr if not found.
Definition VPlan.h:1236
VPIRMetadata(Instruction &I)
Adds metatadata that can be preserved from the original instruction I.
Definition VPlan.h:1201
VPIRMetadata(const VPIRMetadata &Other)=default
Copy constructor for cloning.
VPIRMetadata()=default
void applyMetadata(Instruction &I) const
Add all metadata to I.
void setMetadata(unsigned Kind, MDNode *Node)
Set metadata with kind Kind to Node.
Definition VPlan.h:1220
static bool classof(const VPUser *R)
Definition VPlan.h:1612
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:1592
Type * getResultType() const
Definition VPlan.h:1630
VPInstruction * clone() override
Clone the current recipe.
Definition VPlan.h:1616
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPInstructionWithType(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Value *UV=nullptr)
Definition VPlan.h:1583
void execute(VPTransformState &State) override
Generate the instruction.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInstruction.
bool usesScalars(const VPValue *Op) const override
Cast recipes always use scalars of their operand.
Definition VPlan.h:1633
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1266
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr)
unsigned getNumOperandsWithoutMask() const
Returns the number of operands, excluding the mask if the VPInstruction is masked.
Definition VPlan.h:1516
iterator_range< operand_iterator > operandsWithoutMask()
Returns an iterator range over the operands excluding the mask operand if present.
Definition VPlan.h:1538
VPInstruction * clone() override
Clone the current recipe.
Definition VPlan.h:1447
@ ExtractLastActive
Extracts the last active lane from a set of vectors.
Definition VPlan.h:1376
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
Definition VPlan.h:1396
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition VPlan.h:1367
@ ExitingIVValue
Compute the exiting value of a wide induction after vectorization, that is the value of the last lane...
Definition VPlan.h:1380
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
Definition VPlan.h:1392
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
Definition VPlan.h:1370
@ Unpack
Extracts all lanes from its (non-scalable) vector operand.
Definition VPlan.h:1317
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1363
@ BuildVector
Creates a fixed-width vector containing all operands.
Definition VPlan.h:1312
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
Definition VPlan.h:1309
@ CanonicalIVIncrementForPart
Definition VPlan.h:1293
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1320
bool hasResult() const
Definition VPlan.h:1481
iterator_range< const_operand_iterator > operandsWithoutMask() const
Definition VPlan.h:1541
void addMask(VPValue *Mask)
Add mask Mask to an unmasked VPInstruction, if it needs masking.
Definition VPlan.h:1521
StringRef getName() const
Returns the symbolic name assigned to the VPInstruction.
Definition VPlan.h:1562
unsigned getOpcode() const
Definition VPlan.h:1460
void setName(StringRef NewName)
Set the symbolic name for the VPInstruction.
Definition VPlan.h:1565
VPValue * getMask() const
Returns the mask for the VPInstruction.
Definition VPlan.h:1532
VPInstruction * cloneWithOperands(ArrayRef< VPValue * > NewOperands, Type *ResultTy=nullptr)
Definition VPlan.h:1451
unsigned getNumOperandsForOpcode() const
Return the number of operands determined by the opcode of the VPInstruction, excluding mask.
bool isMasked() const
Returns true if the VPInstruction has a mask operand.
Definition VPlan.h:1506
A common base class for interleaved memory operations.
Definition VPlan.h:3081
virtual unsigned getNumStoreOperands() const =0
Returns the number of stored operands of this interleave group.
VPInterleaveBase(VPRecipeTy SC, const InterleaveGroup< Instruction > *IG, ArrayRef< VPValue * > Operands, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
Definition VPlan.h:3093
bool usesFirstLaneOnly(const VPValue *Op) const override=0
Returns true if the recipe only uses the first lane of operand Op.
bool needsMaskForGaps() const
Return true if the access needs a mask because of the gaps.
Definition VPlan.h:3143
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition VPlan.h:3149
static bool classof(const VPUser *U)
Definition VPlan.h:3125
Instruction * getInsertPos() const
Definition VPlan.h:3147
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:3120
const InterleaveGroup< Instruction > * getInterleaveGroup() const
Definition VPlan.h:3145
VPValue * getMask() const
Return the mask used by this recipe.
Definition VPlan.h:3137
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
Definition VPlan.h:3166
VPInterleaveBase * clone() override=0
Clone the current recipe.
VPValue * getAddr() const
Return the address accessed by this recipe.
Definition VPlan.h:3131
bool usesFirstLaneOnly(const VPValue *Op) const override
The recipe only uses the first lane of the address, and EVL operand.
Definition VPlan.h:3246
VPValue * getEVL() const
The VPValue of the explicit vector length.
Definition VPlan.h:3240
~VPInterleaveEVLRecipe() override=default
unsigned getNumStoreOperands() const override
Returns the number of stored operands of this interleave group.
Definition VPlan.h:3253
VPInterleaveEVLRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3233
VPInterleaveEVLRecipe(VPInterleaveRecipe &R, VPValue &EVL, VPValue *Mask)
Definition VPlan.h:3220
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
Definition VPlan.h:3176
unsigned getNumStoreOperands() const override
Returns the number of stored operands of this interleave group.
Definition VPlan.h:3203
~VPInterleaveRecipe() override=default
VPInterleaveRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3186
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3197
VPInterleaveRecipe(const InterleaveGroup< Instruction > *IG, VPValue *Addr, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
Definition VPlan.h:3178
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
A VPRecipeValue defined by a multi-def recipe, stores a pointer to it.
Definition VPlanValue.h:381
Helper type to provide functions to access incoming values and blocks for phi-like recipes.
Definition VPlan.h:1649
virtual const VPRecipeBase * getAsRecipe() const =0
Return a VPRecipeBase* to the current object.
VPValue * getIncomingValueForBlock(const VPBasicBlock *VPBB) const
Returns the incoming value for VPBB. VPBB must be an incoming block.
VPUser::const_operand_range incoming_values() const
Returns an interator range over the incoming values.
Definition VPlan.h:1678
void addIncoming(VPValue *IncomingV)
Append IncomingV as an incoming value to the phi-like recipe.
Definition VPlan.h:1707
virtual unsigned getNumIncoming() const
Returns the number of incoming values, also number of incoming blocks.
Definition VPlan.h:1673
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:4597
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:1698
VPValue * getIncomingValue(unsigned Idx) const
Returns the incoming VPValue with index Idx.
Definition VPlan.h:1658
virtual ~VPPhiAccessors()=default
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the recipe.
void setIncomingValueForBlock(const VPBasicBlock *VPBB, VPValue *V) const
Sets the incoming value for VPBB to V.
iterator_range< mapped_iterator< detail::index_iterator, std::function< const VPBasicBlock *(size_t)> > > const_incoming_blocks_range
Definition VPlan.h:1683
const_incoming_blocks_range incoming_blocks() const
Returns an iterator range over the incoming blocks.
Definition VPlan.h:1687
~VPPredInstPHIRecipe() override=default
VPPredInstPHIRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3762
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPredInstPHIRecipe.
Definition VPlan.h:3773
VPPredInstPHIRecipe(VPValue *PredV, DebugLoc DL)
Construct a VPPredInstPHIRecipe given PredInst whose value needs a phi nodes after merging back from ...
Definition VPlan.h:3757
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:412
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:557
virtual void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Each concrete VPRecipe prints itself, without printing common information, like debug info or metadat...
VPRegionBlock * getRegion()
Definition VPlan.h:4852
void setDebugLoc(DebugLoc NewDL)
Set the recipe's debug location to NewDL.
Definition VPlan.h:565
bool mayWriteToMemory() const
Returns true if the recipe may write to memory.
VPRecipeTy getVPRecipeID() const
Definition VPlan.h:530
~VPRecipeBase() override=default
VPBasicBlock * getParent()
Definition VPlan.h:484
enum :unsigned char { VPBranchOnMaskSC, VPDerivedIVSC, VPExpandSCEVSC, VPExpressionSC, VPIRInstructionSC, VPInstructionSC, VPInterleaveEVLSC, VPInterleaveSC, VPReductionEVLSC, VPReductionSC, VPReplicateSC, VPScalarIVStepsSC, VPVectorPointerSC, VPVectorEndPointerSC, VPWidenCallSC, VPWidenCanonicalIVSC, VPWidenCastSC, VPWidenGEPSC, VPWidenIntrinsicSC, VPWidenMemIntrinsicSC, VPWidenLoadEVLSC, VPWidenLoadSC, VPWidenStoreEVLSC, VPWidenStoreSC, VPWidenSC, VPBlendSC, VPHistogramSC, VPWidenPHISC, VPPredInstPHISC, VPCurrentIterationPHISC, VPActiveLaneMaskPHISC, VPFirstOrderRecurrencePHISC, VPWidenIntOrFpInductionSC, VPWidenPointerInductionSC, VPReductionPHISC, VPFirstPHISC=VPWidenPHISC, VPFirstHeaderPHISC=VPCurrentIterationPHISC, VPLastHeaderPHISC=VPReductionPHISC, VPLastPHISC=VPReductionPHISC, } VPRecipeTy
An enumeration for keeping track of the concrete subclass of VPRecipeBase that is actually instantiat...
Definition VPlan.h:427
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:562
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:533
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:414
const VPBasicBlock * getParent() const
Definition VPlan.h:485
VPRecipeBase(VPRecipeTy SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:474
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:538
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...
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:354
VPValue * getEVL() const
The VPValue of the explicit vector length.
Definition VPlan.h:3414
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:3392
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3417
VPReductionEVLRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3404
~VPReductionEVLRecipe() override=default
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
Definition VPlan.h:2959
void setVFScaleFactor(unsigned ScaleFactor)
Set the VFScaleFactor for this reduction phi.
Definition VPlan.h:2950
VPReductionPHIRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2932
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by, or 1 if it isn't scaled.
Definition VPlan.h:2943
~VPReductionPHIRecipe() override=default
bool hasUsesOutsideReductionChain() const
Returns true, if the phi is part of a multi-use reduction.
Definition VPlan.h:2971
VPReductionPHIRecipe(PHINode *Phi, RecurKind Kind, VPValue &Start, VPValue &BackedgeValue, ReductionStyle Style, const VPIRFlags &Flags, bool HasUsesOutsideReductionChain=false)
Create a new VPReductionPHIRecipe for the reduction Phi.
Definition VPlan.h:2913
bool isInLoop() const
Returns true if the phi is part of an in-loop reduction.
Definition VPlan.h:2962
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:2976
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi/select nodes.
VPReductionPHIRecipe * cloneWithOperands(VPValue *Start, VPValue *BackedgeValue)
Definition VPlan.h:2925
bool isPartialReduction() const
Returns true if the reduction outputs a vector with a scaled down VF.
Definition VPlan.h:2968
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
Definition VPlan.h:2956
A recipe to represent inloop, ordered or partial reduction operations.
Definition VPlan.h:3269
bool isConditional() const
Return true if the in-loop reduction is conditional.
Definition VPlan.h:3353
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:3322
static bool classof(const VPSingleDefRecipe *R)
Definition VPlan.h:3337
VPValue * getVecOp() const
The VPValue of the vector value to be reduced.
Definition VPlan.h:3366
VPValue * getCondOp() const
The VPValue of the condition for the block.
Definition VPlan.h:3368
RecurKind getRecurrenceKind() const
Return the recurrence kind for the in-loop reduction.
Definition VPlan.h:3349
VPReductionRecipe(RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, ReductionStyle Style, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:3302
bool isOrdered() const
Return true if the in-loop reduction is ordered.
Definition VPlan.h:3351
VPReductionRecipe(const RecurKind RdxKind, FastMathFlags FMFs, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, ReductionStyle Style, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:3308
VPReductionRecipe(VPRecipeTy SC, RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, ReductionStyle Style, DebugLoc DL)
Definition VPlan.h:3278
bool isPartialReduction() const
Returns true if the reduction outputs a vector with a scaled down VF.
Definition VPlan.h:3355
~VPReductionRecipe() override=default
VPValue * getChainOp() const
The VPValue of the scalar Chain being accumulated.
Definition VPlan.h:3364
bool isInLoop() const
Returns true if the reduction is in-loop.
Definition VPlan.h:3359
VPReductionRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3316
static bool classof(const VPUser *U)
Definition VPlan.h:3327
static bool classof(const VPValue *VPV)
Definition VPlan.h:3332
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by, or 1 if it isn't scaled.
Definition VPlan.h:3373
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4678
const VPBlockBase * getEntry() const
Definition VPlan.h:4722
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4754
~VPRegionBlock() override=default
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4825
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
Definition VPlan.h:4818
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
Definition VPlan.h:4739
VPBlockBase * getExiting()
Definition VPlan.h:4735
VPBranchOnMaskRecipe * getEntryBranchOnMask()
Definition VPlan.h:4759
const VPRegionValue * getCanonicalIV() const
Definition VPlan.h:4801
SmallVector< VPRegionValue *, 2 > getRegionValues() const
Return the region values of the loop region (canonical IV, header mask) or an empty vector for replic...
Definition VPlan.h:4832
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
Definition VPlan.h:4727
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
Definition VPlan.h:4806
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4842
void clearCanonicalIVNUW(VPInstruction *Increment)
Unsets NUW for the canonical IV increment Increment, for loop regions.
Definition VPlan.h:4845
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4798
const VPBlockBase * getExiting() const
Definition VPlan.h:4734
VPBlockBase * getEntry()
Definition VPlan.h:4723
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
Definition VPlan.h:4747
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4811
friend class VPlan
Definition VPlan.h:4679
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
Definition VPlan.h:4718
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:252
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3436
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
Definition VPlan.h:3495
unsigned getNumOperandsWithoutMask() const
Returns the number of operands, excluding the mask if the recipe is predicated.
Definition VPlan.h:3529
VPReplicateRecipe(Instruction *I, ArrayRef< VPValue * > Operands, bool IsSingleScalar, VPValue *Mask=nullptr, const VPIRFlags &Flags={}, VPIRMetadata Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:3444
~VPReplicateRecipe() override=default
static Type * computeScalarType(const Instruction *I, ArrayRef< VPValue * > Operands)
Compute the scalar result type for a VPReplicateRecipe wrapping I with Operands (excluding any predic...
VPReplicateRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
Definition VPlan.h:3468
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
Definition VPlan.h:3510
operand_range operandsWithoutMask()
Return the recipe's operands, excluding the mask of a predicated recipe.
Definition VPlan.h:3523
bool isPredicated() const
Definition VPlan.h:3500
VPReplicateRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3466
bool doesGeneratePerAllLanes() const
Returns true if the recipe produces scalar values for all VF lanes.
Definition VPlan.h:3498
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3503
unsigned getOpcode() const
Definition VPlan.h:3533
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
Definition VPlan.h:3517
Instruction::BinaryOps getInductionOpcode() const
Definition VPlan.h:4356
VPValue * getStepValue() const
Definition VPlan.h:4326
void setStartIndex(VPValue *StartIndex)
Set or add the StartIndex operand.
Definition VPlan.h:4339
VPScalarIVStepsRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4308
VPValue * getStartIndex() const
Return the StartIndex, or null if known to be zero, valid only after unrolling.
Definition VPlan.h:4334
VPValue * getVFValue() const
Return the number of scalars to produce per unroll part, used to compute StartIndex during unrolling.
Definition VPlan.h:4330
VPScalarIVStepsRecipe(VPValue *IV, VPValue *Step, VPValue *VF, Instruction::BinaryOps Opcode, FastMathFlags FMFs={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:4299
~VPScalarIVStepsRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:4350
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:620
static bool classof(const VPValue *V)
Definition VPlan.h:677
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
Definition VPlan.h:690
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:634
VPSingleDefRecipe(VPRecipeTy SC, ArrayRef< VPValue * > Operands, Value *UV, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:626
const Instruction * getUnderlyingInstr() const
Definition VPlan.h:693
VPSingleDefRecipe(VPRecipeTy SC, ArrayRef< VPValue * > Operands, Type *ResultTy, Value *UV=nullptr, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:630
static bool classof(const VPUser *U)
Definition VPlan.h:682
VPSingleDefRecipe * clone() override=0
Clone the current recipe.
VPSingleDefRecipe(VPRecipeTy SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:622
LLVM_ABI_FOR_TEST VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
Definition VPlan.cpp:169
This class can be used to assign names to VPValues.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
Definition VPlan.cpp:1547
operand_range operands()
Definition VPlanValue.h:474
void setOperand(unsigned I, VPValue *New)
Definition VPlanValue.h:447
unsigned getNumOperands() const
Definition VPlanValue.h:441
operand_iterator op_end()
Definition VPlanValue.h:472
operand_iterator op_begin()
Definition VPlanValue.h:470
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
VPUser(ArrayRef< VPValue * > Operands)
Definition VPlanValue.h:422
iterator_range< const_operand_iterator > const_operand_range
Definition VPlanValue.h:468
virtual bool usesScalars(const VPValue *Op) const
Returns true if the VPUser uses scalars of operand Op.
Definition VPlanValue.h:481
iterator_range< operand_iterator > operand_range
Definition VPlanValue.h:467
void addOperand(VPValue *Operand)
Definition VPlanValue.h:427
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:149
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
Definition VPlan.cpp:143
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
bool user_empty() const
Definition VPlanValue.h:161
void setUnderlyingValue(Value *Val)
Definition VPlanValue.h:209
unsigned getNumUsers() const
Definition VPlanValue.h:115
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition VPlan.h:2352
VPValue * getVFValue() const
Definition VPlan.h:2333
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getSourceElementType() const
Definition VPlan.h:2330
int64_t getStride() const
Definition VPlan.h:2331
VPVectorEndPointerRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2373
VPValue * getOffset() const
Definition VPlan.h:2334
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition VPlan.h:2366
void addOffset(VPValue *Offset)
Append Offset as the offset operand.
Definition VPlan.h:2344
VPVectorEndPointerRecipe(VPValue *Ptr, VPValue *VF, Type *SourceElementTy, int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition VPlan.h:2320
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPVectorPointerRecipe.
Definition VPlan.h:2359
VPValue * getPointer() const
Definition VPlan.h:2332
void materializeOffset(unsigned Part=0)
Adds the offset operand to the recipe.
void addPerPartOffset(VPValue *VFxPart)
Add the per-part offset (VFxPart) used for unrolled parts > 0.
Definition VPlan.h:2414
VPValue * getStride() const
Definition VPlan.h:2407
Type * getSourceElementType() const
Definition VPlan.h:2422
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Definition VPlan.h:2424
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
Definition VPlan.h:2431
VPVectorPointerRecipe(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
Definition VPlan.h:2398
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHeaderPHIRecipe.
Definition VPlan.h:2448
VPVectorPointerRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2438
VPValue * getVFxPart() const
Definition VPlan.h:2409
A recipe for widening Call instructions using library calls.
Definition VPlan.h:2143
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
Definition VPlan.h:2150
const_operand_range args() const
Definition VPlan.h:2191
VPWidenCallRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2169
operand_range args()
Definition VPlan.h:2190
Function * getCalledScalarFunction() const
Definition VPlan.h:2186
~VPWidenCallRecipe() override=default
~VPWidenCanonicalIVRecipe() override=default
VPValue * getStepValue() const
Definition VPlan.h:4212
void addPerPartStep(VPValue *Step)
Add the per-part step (VF * Part) used for unrolled parts.
Definition VPlan.h:4217
void printRecipe(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 VPWidenCanonicalIVPHIRecipe.
Definition VPlan.h:4201
VPRegionValue * getCanonicalIV() const
Return the canonical IV being widened.
Definition VPlan.h:4208
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4186
VPWidenCanonicalIVRecipe(VPRegionValue *CanonicalIV, const VPIRFlags::WrapFlagsTy &Flags={})
Definition VPlan.h:4179
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
Definition VPlan.h:4196
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1925
Instruction::CastOps getOpcode() const
Definition VPlan.h:1961
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Produce widened copies of the cast.
~VPWidenCastRecipe() override=default
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCastRecipe.
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, CastInst *CI=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:1930
VPWidenCastRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:1946
unsigned getOpcode() const
This recipe generates a GEP instruction.
Definition VPlan.h:2282
Type * getSourceElementType() const
Definition VPlan.h:2287
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenGEPRecipe.
Definition VPlan.h:2290
VPWidenGEPRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2273
~VPWidenGEPRecipe() override=default
VPWidenGEPRecipe(Type *SourceElementTy, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), GetElementPtrInst *UV=nullptr)
Definition VPlan.h:2256
void execute(VPTransformState &State) override=0
Generate the phi nodes.
ArrayRef< const SCEVPredicate * > getNoWrapPredicates() const
Returns the SCEV predicates associated with this induction.
Definition VPlan.h:2628
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:2640
static bool classof(const VPValue *V)
Definition VPlan.h:2590
void setStepValue(VPValue *V)
Update the step value of the recipe.
Definition VPlan.h:2609
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
Definition VPlan.h:2632
VPValue * getStartValue() const
Returns the start value of the induction.
Definition VPlan.h:2602
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Definition VPlan.h:2617
PHINode * getPHINode() const
Returns the underlying PHINode if one exists, or null otherwise.
Definition VPlan.h:2620
VPValue * getStepValue()
Returns the step value of the induction.
Definition VPlan.h:2605
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2625
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:2585
VPWidenInductionRecipe(VPRecipeTy Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, Type *ResultTy, DebugLoc DL)
Definition VPlan.h:2564
const VPValue * getVFValue() const
Definition VPlan.h:2612
static bool classof(const VPSingleDefRecipe *R)
Definition VPlan.h:2595
const VPValue * getStepValue() const
Definition VPlan.h:2606
VPWidenInductionRecipe(VPRecipeTy Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, DebugLoc DL)
Definition VPlan.h:2558
void addUnrolledPartOperands(VPValue *SplatVFStep, VPValue *LastPart)
After unrolling, append the splat-VF step (VF * step) and the value of the induction at the last unro...
Definition VPlan.h:2573
const TruncInst * getTruncInst() const
Definition VPlan.h:2714
void execute(VPTransformState &State) override
Generate the phi nodes.
Definition VPlan.h:2695
~VPWidenIntOrFpInductionRecipe() override=default
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, TruncInst *Trunc, const VPIRFlags &Flags, DebugLoc DL)
Definition VPlan.h:2670
VPValue * getSplatVFValue() const
If the recipe has been unrolled, return the VPValue for the induction increment, otherwise return nul...
Definition VPlan.h:2702
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenIntOrFpInductionRecipe.
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2687
TruncInst * getTruncInst()
Returns the first defined value as TruncInst, if it is one or nullptr otherwise.
Definition VPlan.h:2713
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, const VPIRFlags &Flags, DebugLoc DL)
Definition VPlan.h:2661
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
Definition VPlan.h:2728
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Definition VPlan.h:2709
bool isCanonical() const
Returns true if the induction is canonical, i.e.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
A recipe for widening vector intrinsics.
Definition VPlan.h:1972
VPWidenIntrinsicRecipe(VPRecipeTy SC, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:1986
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:2021
CallInst * createVectorCall(VPTransformState &State)
Helper function to produce the widened intrinsic call.
Intrinsic::ID getVectorIntrinsicID() const
Return the ID of the intrinsic.
Definition VPlan.h:2075
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool mayReadFromMemory() const
Returns true if the intrinsic may read from memory.
Definition VPlan.h:2081
StringRef getIntrinsicName() const
Return to name of the intrinsic as string.
static InstructionCost computeCallCost(Intrinsic::ID ID, ArrayRef< const VPValue * > Operands, const VPRecipeWithIRFlags &R, ElementCount VF, VPCostContext &Ctx)
Compute the cost of a vector intrinsic with ID and Operands.
VPWidenIntrinsicRecipe(CallInst &CI, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:2007
bool mayHaveSideEffects() const
Returns true if the intrinsic may have side-effects.
Definition VPlan.h:2087
static bool classof(const VPSingleDefRecipe *R)
Definition VPlan.h:2057
static bool classof(const VPValue *V)
Definition VPlan.h:2052
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2032
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
Definition VPlan.h:2084
~VPWidenIntrinsicRecipe() override=default
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:2042
LLVM_ABI_FOR_TEST bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Produce a widened version of the vector intrinsic.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this vector intrinsic.
static bool classof(const VPUser *U)
Definition VPlan.h:2047
static InstructionCost computeMemIntrinsicCost(Intrinsic::ID IID, Type *Ty, bool IsMasked, Align Alignment, VPCostContext &Ctx)
Helper function for computing the cost of vector memory intrinsic.
void execute(VPTransformState &State) override
Produce a widened version of the vector memory intrinsic.
~VPWidenMemIntrinsicRecipe() override=default
VPWidenMemIntrinsicRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2120
VPWidenMemIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:2105
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this vector memory intrinsic.
A common mixin class for widening memory operations.
Definition VPlan.h:3789
bool IsMasked
Whether the memory access is masked.
Definition VPlan.h:3800
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
Definition VPlan.h:3825
virtual ~VPWidenMemoryRecipe()=default
Instruction & Ingredient
Definition VPlan.h:3791
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const
Return the cost of this VPWidenMemoryRecipe.
Instruction & getIngredient() const
Definition VPlan.h:3847
bool Consecutive
Whether the accessed addresses are consecutive.
Definition VPlan.h:3797
virtual const VPRecipeBase * getAsRecipe() const =0
VPValue * getMask() const
Return the mask used by this recipe.
Definition VPlan.h:3835
Align Alignment
Alignment information for this memory access.
Definition VPlan.h:3794
VPWidenMemoryRecipe(Instruction &I, bool Consecutive, const VPIRMetadata &Metadata)
Definition VPlan.h:3812
virtual VPRecipeBase * getAsRecipe()=0
Return a VPRecipeBase* to the current object.
bool isMasked() const
Returns true if the recipe is masked.
Definition VPlan.h:3831
void setMask(VPValue *Mask)
Definition VPlan.h:3802
Align getAlign() const
Returns the alignment of the memory access.
Definition VPlan.h:3842
VPValue * getAddr() const
Return the address accessed by this recipe.
Definition VPlan.h:3828
A recipe for widened phis.
Definition VPlan.h:2786
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition VPlan.h:2831
unsigned getOpcode() const
This recipe generates a PHI.
Definition VPlan.h:2813
VPWidenPHIRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2806
~VPWidenPHIRecipe() override=default
VPWidenPHIRecipe(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new VPWidenPHIRecipe with incoming values IncomingValues, debug location DL and Name.
Definition VPlan.h:2793
VPWidenPointerInductionRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:2755
~VPWidenPointerInductionRecipe() override=default
bool onlyScalarsGenerated(bool IsScalable)
Returns true if only scalar values will be generated.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate vector values for the pointer induction.
Definition VPlan.h:2764
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step, VPValue *NumUnrolledElems, const InductionDescriptor &IndDesc, DebugLoc DL)
Create a new VPWidenPointerInductionRecipe for Phi with start value Start and the number of elements ...
Definition VPlan.h:2745
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1859
VPWidenRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:1885
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:1914
VPWidenRecipe(Instruction &I, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
Definition VPlan.h:1863
VPWidenRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
Definition VPlan.h:1870
~VPWidenRecipe() override=default
VPWidenRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
Definition VPlan.h:1887
unsigned getOpcode() const
Definition VPlan.h:1904
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4865
VPIRValue * getLiveIn(Value *V) const
Return the live-in VPIRValue for V, if there is one or nullptr otherwise.
Definition VPlan.h:5204
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition VPlan.cpp:1199
friend class VPSlotTracker
Definition VPlan.h:4867
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition VPlan.cpp:1175
bool hasVF(ElementCount VF) const
Definition VPlan.h:5097
ElementCount getSingleVF() const
Returns the single VF of the plan, asserting that the plan has exactly one VF.
Definition VPlan.h:5110
const DataLayout & getDataLayout() const
Definition VPlan.h:5079
LLVMContext & getContext() const
Definition VPlan.h:5075
VPBasicBlock * getEntry()
Definition VPlan.h:4961
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
Definition VPlan.h:5307
void setName(const Twine &newName)
Definition VPlan.h:5143
bool hasScalableVF() const
Definition VPlan.h:5098
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:5033
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
Definition VPlan.h:5054
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition VPlan.h:5104
LLVM_ABI_FOR_TEST ~VPlan()
Definition VPlan.cpp:932
VPIRValue * getOrAddLiveIn(VPIRValue *V)
Definition VPlan.h:5161
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition VPlan.cpp:951
const VPBasicBlock * getEntry() const
Definition VPlan.h:4962
friend class VPlanPrinter
Definition VPlan.h:4866
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
Definition VPlan.h:5170
VPIRValue * getConstantInt(const APInt &Val)
Return a VPIRValue wrapping a ConstantInt with the given APInt value.
Definition VPlan.h:5193
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5073
VPIRValue * getAllOnesValue(Type *Ty)
Return a VPIRValue wrapping the AllOnes value of type Ty.
Definition VPlan.h:5176
VPRegionBlock * createReplicateRegion(VPBlockBase *Entry, VPBlockBase *Exiting, const std::string &Name="")
Create a new replicate region with Entry, Exiting and Name.
Definition VPlan.h:5255
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1338
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
Definition VPlan.h:5207
bool hasUF(unsigned UF) const
Definition VPlan.h:5122
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
Definition VPlan.h:5198
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5027
VPlan(BasicBlock *ScalarHeaderBB, Type *IdxTy)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and vect...
Definition VPlan.h:4942
VPSymbolicValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:5063
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:5060
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:5147
VPRegionBlock * createLoopRegion(Type *CanIVTy, DebugLoc DL, const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with a canonical IV using CanIVTy and DL.
Definition VPlan.h:5242
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5173
void setVF(ElementCount VF)
Definition VPlan.h:5085
unsigned getMaxBlockNumber() const
Definition VPlan.h:5274
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5138
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1086
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
Definition VPlan.h:5277
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition VPlan.cpp:1068
LLVM_ABI_FOR_TEST bool isOuterLoop() const
Returns true if this VPlan is for an outer loop, i.e., its vector loop region contains a nested loop ...
Definition VPlan.cpp:1105
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5125
VPIRValue * getConstantInt(unsigned BitWidth, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given bitwidth and value.
Definition VPlan.h:5187
const VPBasicBlock * getMiddleBlock() const
Definition VPlan.h:5012
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
Definition VPlan.h:5040
void resetTripCount(VPValue *NewTripCount)
Resets the trip count for the VPlan.
Definition VPlan.h:5047
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
Definition VPlan.h:5003
void setEntry(VPBasicBlock *VPBB)
Definition VPlan.h:4950
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5230
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1345
void removeVF(ElementCount VF)
Remove VF from the plan.
Definition VPlan.h:5092
VPIRValue * getTrue()
Return a VPIRValue wrapping i1 true.
Definition VPlan.h:5167
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4966
bool requiresScalarEpilogue() const
Returns true if the plan requires a scalar epilogue after the vector loop.
Definition VPlan.h:4989
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition VPlan.cpp:1205
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5070
bool hasScalarVFOnly() const
Definition VPlan.h:5115
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5017
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition VPlan.cpp:961
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
Definition VPlan.cpp:1158
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:4982
void addVF(ElementCount VF)
Definition VPlan.h:5083
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:5023
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition VPlan.cpp:1114
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5066
void setUF(unsigned UF)
Definition VPlan.h:5130
const VPSymbolicValue & getVF() const
Definition VPlan.h:5067
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop, i.e.
Definition VPlan.h:5300
LLVM_ABI_FOR_TEST VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
Definition VPlan.cpp:1246
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
Definition VPlan.h:5181
LLVM Value Representation.
Definition Value.h:75
Increasing range of size_t indices.
Definition STLExtras.h:2507
typename base_list_type::const_reverse_iterator const_reverse_iterator
Definition ilist.h:124
typename base_list_type::reverse_iterator reverse_iterator
Definition ilist.h:123
typename 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.
LLVM_ABI AttributeSet getFnAttributes(LLVMContext &C, ID id)
Return the function attributes for an intrinsic.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Definition DwarfDebug.h:190
CastInfo helper for casting from VPRecipeBase to a mixin class that is not part of the VPRecipeBase c...
Definition VPlan.h:4369
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:577
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:830
LLVM_PACKED_END
Definition VPlan.h:1123
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
Definition Casting.h:683
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:1765
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
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:840
ReductionStyle getReductionStyle(bool InLoop, bool Ordered, unsigned ScaleFactor)
Definition VPlan.h:2886
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:2554
Type * toScalarizedTy(Type *Ty)
A helper for converting vectorized types to scalarized (non-vector) types.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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:714
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
UncountableExitStyle
Different methods of handling early exits.
Definition VPlan.h:81
@ MaskedHandleExitInScalarLoop
All memory operations other than the load(s) required to determine whether an uncountable exit occurr...
Definition VPlan.h:90
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:383
LLVM_ABI Type * computeScalarTypeForInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands)
Compute the scalar result type for an IR Opcode given Operands.
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:547
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition STLExtras.h:322
@ Other
Any other memory.
Definition ModRef.h:68
RecurKind
These are the kinds of recurrences that we support.
@ Mul
Product of integers.
@ Add
Sum of integers.
@ AddChainWithSubs
A chain of adds and subs.
@ FAdd
Sum of floats.
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:2012
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
auto sum_of(R &&Range, E Init=E{0})
Returns the sum of all values in Range with Init initial value.
Definition STLExtras.h:1717
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
std::variant< RdxOrdered, RdxInLoop, RdxUnordered > ReductionStyle
Definition VPlan.h:2884
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:76
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static Bitfield::Type get(StorageType Packed)
Unpacks the field from the Packed value.
Definition Bitfields.h:207
static void set(StorageType &Packed, typename Bitfield::Type Value)
Sets the typed value in the provided Packed value.
Definition Bitfields.h:223
This struct provides a method for customizing the way a cast is performed.
Definition Casting.h:476
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
Definition Casting.h:388
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
Definition Casting.h:309
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
Definition Casting.h:423
This reduction is in-loop.
Definition VPlan.h:2878
Possible variants of a reduction.
Definition VPlan.h:2876
This reduction is unordered with the partial result scaled down by some factor.
Definition VPlan.h:2881
unsigned VFScaleFactor
Definition VPlan.h:2882
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342
An overlay on VPConstant for VPValues that wrap a ConstantInt.
Definition VPlanValue.h:310
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:2847
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this first-order recurrence phi recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:2859
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPFirstOrderRecurrencePHIRecipe(PHINode *Phi, VPValue &Start, VPValue &BackedgeValue)
Definition VPlan.h:2838
DisjointFlagsTy(bool IsDisjoint)
Definition VPlan.h:738
NonNegFlagsTy(bool IsNonNeg)
Definition VPlan.h:743
TruncFlagsTy(bool HasNUW, bool HasNSW)
Definition VPlan.h:733
WrapFlagsTy(bool HasNUW, bool HasNSW)
Definition VPlan.h:725
An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use cast/dyn_cast/isa and exec...
Definition VPlan.h:1827
VPIRPhi(PHINode &PN)
Definition VPlan.h:1828
static bool classof(const VPRecipeBase *U)
Definition VPlan.h:1830
static bool classof(const VPUser *U)
Definition VPlan.h:1835
PHINode & getIRPhi() const
Definition VPlan.h:1840
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition VPlan.h:1851
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279
static bool classof(const VPUser *U)
Definition VPlan.h:1727
VPPhi * clone() override
Clone the current recipe.
Definition VPlan.h:1742
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
Definition VPlan.h:1757
static bool classof(const VPSingleDefRecipe *SDR)
Definition VPlan.h:1737
static bool classof(const VPValue *V)
Definition VPlan.h:1732
VPPhi(ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL, const Twine &Name="", Type *ResultTy=nullptr)
Definition VPlan.h:1722
A pure-virtual common base class for recipes defining a single VPValue and using IR flags.
Definition VPlan.h:1127
VPRecipeWithIRFlags(VPRecipeTy SC, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:1128
static bool classof(const VPSingleDefRecipe *R)
Definition VPlan.h:1169
static bool classof(const VPRecipeBase *R)
Definition VPlan.h:1139
InstructionCost getCostForRecipeWithOpcode(unsigned Opcode, ElementCount VF, VPCostContext &Ctx) const
Compute the cost for this recipe for VF, using Opcode and Ctx.
static bool classof(const VPValue *V)
Definition VPlan.h:1162
VPRecipeWithIRFlags(VPRecipeTy SC, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
Definition VPlan.h:1133
void execute(VPTransformState &State) override=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPRecipeWithIRFlags * clone() override=0
Clone the current recipe.
static bool classof(const VPUser *U)
Definition VPlan.h:1157
VPTransformState holds information passed down when "executing" a VPlan, needed for generating the ou...
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition VPlan.h:3906
VPWidenLoadEVLRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3916
unsigned getOpcode() const
Returns the opcode of the widened load.
Definition VPlan.h:3923
VPValue * getEVL() const
Return the EVL operand.
Definition VPlan.h:3926
VPWidenLoadEVLRecipe(VPWidenLoadRecipe &L, VPValue *Addr, VPValue &EVL, VPValue *Mask)
Definition VPlan.h:3907
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3936
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3853
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Definition VPlan.h:3854
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3882
unsigned getOpcode() const
Returns the opcode of the widened load.
Definition VPlan.h:3870
VPWidenLoadRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3862
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenLoadSC)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenLoadRecipe.
Definition VPlan.h:3876
A recipe for widening store operations with vector-predication intrinsics, using the value to store,...
Definition VPlan.h:4012
VPValue * getStoredValue() const
Return the address accessed by this recipe.
Definition VPlan.h:4028
VPWidenStoreEVLRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:4021
VPWidenStoreEVLRecipe(VPWidenStoreRecipe &S, VPValue *Addr, VPValue *StoredVal, VPValue &EVL, VPValue *Mask)
Definition VPlan.h:4013
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:4041
VPValue * getEVL() const
Return the EVL operand.
Definition VPlan.h:4031
A recipe for widening store operations, using the stored value, the address to store to and an option...
Definition VPlan.h:3958
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, const VPIRMetadata &Metadata, DebugLoc DL)
Definition VPlan.h:3959
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
Definition VPlan.h:3976
VPWidenStoreRecipe * clone() override
Clone the current recipe.
Definition VPlan.h:3967
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreRecipe.
Definition VPlan.h:3982
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Definition VPlan.h:3988
static VPMixin * castFailed()
Definition VPlan.h:4387
static bool isPossible(VPRecipeBase *R)
Used by isa.
Definition VPlan.h:4378
static VPMixin * doCast(VPRecipeBase *R)
Used by cast.
Definition VPlan.h:4381