1 //===- VPlan.h - Represent A Vectorizer Plan ------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file contains the declarations of the Vectorization Plan base classes:
12 /// 1. VPBasicBlock and VPRegionBlock that inherit from a common pure virtual
13 ///    VPBlockBase, together implementing a Hierarchical CFG;
14 /// 2. Specializations of GraphTraits that allow VPBlockBase graphs to be
15 ///    treated as proper graphs for generic algorithms;
16 /// 3. Pure virtual VPRecipeBase serving as the base class for recipes contained
17 ///    within VPBasicBlocks;
18 /// 4. The VPlan class holding a candidate for vectorization;
19 /// 5. The VPlanPrinter class providing a way to print a plan in dot format.
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 "llvm/ADT/GraphTraits.h"
28 #include "llvm/ADT/SmallSet.h"
29 #include "llvm/ADT/ilist.h"
30 #include "llvm/ADT/ilist_node.h"
31 #include "llvm/IR/IRBuilder.h"
32 #include "llvm/Support/raw_ostream.h"
33 
34 // The (re)use of existing LoopVectorize classes is subject to future VPlan
35 // refactoring.
36 namespace {
37 // Forward declarations.
38 //class InnerLoopVectorizer;
39 class LoopVectorizationLegality;
40 class LoopVectorizationCostModel;
41 } // namespace
42 
43 namespace llvm {
44 
45 // Forward declarations.
46 class BasicBlock;
47 class InnerLoopVectorizer;
48 class VPBasicBlock;
49 
50 /// In what follows, the term "input IR" refers to code that is fed into the
51 /// vectorizer whereas the term "output IR" refers to code that is generated by
52 /// the vectorizer.
53 
54 /// VPIteration represents a single point in the iteration space of the output
55 /// (vectorized and/or unrolled) IR loop.
56 struct VPIteration {
57   unsigned Part; ///< in [0..UF)
58   unsigned Lane; ///< in [0..VF)
59 };
60 
61 /// This is a helper struct for maintaining vectorization state. It's used for
62 /// mapping values from the original loop to their corresponding values in
63 /// the new loop. Two mappings are maintained: one for vectorized values and
64 /// one for scalarized values. Vectorized values are represented with UF
65 /// vector values in the new loop, and scalarized values are represented with
66 /// UF x VF scalar values in the new loop. UF and VF are the unroll and
67 /// vectorization factors, respectively.
68 ///
69 /// Entries can be added to either map with setVectorValue and setScalarValue,
70 /// which assert that an entry was not already added before. If an entry is to
71 /// replace an existing one, call resetVectorValue and resetScalarValue. This is
72 /// currently needed to modify the mapped values during "fix-up" operations that
73 /// occur once the first phase of widening is complete. These operations include
74 /// type truncation and the second phase of recurrence widening.
75 ///
76 /// Entries from either map can be retrieved using the getVectorValue and
77 /// getScalarValue functions, which assert that the desired value exists.
78 
79 struct VectorizerValueMap {
80 private:
81   /// The unroll factor. Each entry in the vector map contains UF vector values.
82   unsigned UF;
83 
84   /// The vectorization factor. Each entry in the scalar map contains UF x VF
85   /// scalar values.
86   unsigned VF;
87 
88   /// The vector and scalar map storage. We use std::map and not DenseMap
89   /// because insertions to DenseMap invalidate its iterators.
90   typedef SmallVector<Value *, 2> VectorParts;
91   typedef SmallVector<SmallVector<Value *, 4>, 2> ScalarParts;
92   std::map<Value *, VectorParts> VectorMapStorage;
93   std::map<Value *, ScalarParts> ScalarMapStorage;
94 
95 public:
96   /// Construct an empty map with the given unroll and vectorization factors.
97   VectorizerValueMap(unsigned UF, unsigned VF) : UF(UF), VF(VF) {}
98 
99   /// \return True if the map has any vector entry for \p Key.
100   bool hasAnyVectorValue(Value *Key) const {
101     return VectorMapStorage.count(Key);
102   }
103 
104   /// \return True if the map has a vector entry for \p Key and \p Part.
105   bool hasVectorValue(Value *Key, unsigned Part) const {
106     assert(Part < UF && "Queried Vector Part is too large.");
107     if (!hasAnyVectorValue(Key))
108       return false;
109     const VectorParts &Entry = VectorMapStorage.find(Key)->second;
110     assert(Entry.size() == UF && "VectorParts has wrong dimensions.");
111     return Entry[Part] != nullptr;
112   }
113 
114   /// \return True if the map has any scalar entry for \p Key.
115   bool hasAnyScalarValue(Value *Key) const {
116     return ScalarMapStorage.count(Key);
117   }
118 
119   /// \return True if the map has a scalar entry for \p Key and \p Instance.
120   bool hasScalarValue(Value *Key, const VPIteration &Instance) const {
121     assert(Instance.Part < UF && "Queried Scalar Part is too large.");
122     assert(Instance.Lane < VF && "Queried Scalar Lane is too large.");
123     if (!hasAnyScalarValue(Key))
124       return false;
125     const ScalarParts &Entry = ScalarMapStorage.find(Key)->second;
126     assert(Entry.size() == UF && "ScalarParts has wrong dimensions.");
127     assert(Entry[Instance.Part].size() == VF &&
128            "ScalarParts has wrong dimensions.");
129     return Entry[Instance.Part][Instance.Lane] != nullptr;
130   }
131 
132   /// Retrieve the existing vector value that corresponds to \p Key and
133   /// \p Part.
134   Value *getVectorValue(Value *Key, unsigned Part) {
135     assert(hasVectorValue(Key, Part) && "Getting non-existent value.");
136     return VectorMapStorage[Key][Part];
137   }
138 
139   /// Retrieve the existing scalar value that corresponds to \p Key and
140   /// \p Instance.
141   Value *getScalarValue(Value *Key, const VPIteration &Instance) {
142     assert(hasScalarValue(Key, Instance) && "Getting non-existent value.");
143     return ScalarMapStorage[Key][Instance.Part][Instance.Lane];
144   }
145 
146   /// Set a vector value associated with \p Key and \p Part. Assumes such a
147   /// value is not already set. If it is, use resetVectorValue() instead.
148   void setVectorValue(Value *Key, unsigned Part, Value *Vector) {
149     assert(!hasVectorValue(Key, Part) && "Vector value already set for part");
150     if (!VectorMapStorage.count(Key)) {
151       VectorParts Entry(UF);
152       VectorMapStorage[Key] = Entry;
153     }
154     VectorMapStorage[Key][Part] = Vector;
155   }
156 
157   /// Set a scalar value associated with \p Key and \p Instance. Assumes such a
158   /// value is not already set.
159   void setScalarValue(Value *Key, const VPIteration &Instance, Value *Scalar) {
160     assert(!hasScalarValue(Key, Instance) && "Scalar value already set");
161     if (!ScalarMapStorage.count(Key)) {
162       ScalarParts Entry(UF);
163       // TODO: Consider storing uniform values only per-part, as they occupy
164       //       lane 0 only, keeping the other VF-1 redundant entries null.
165       for (unsigned Part = 0; Part < UF; ++Part)
166         Entry[Part].resize(VF, nullptr);
167       ScalarMapStorage[Key] = Entry;
168     }
169     ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar;
170   }
171 
172   /// Reset the vector value associated with \p Key for the given \p Part.
173   /// This function can be used to update values that have already been
174   /// vectorized. This is the case for "fix-up" operations including type
175   /// truncation and the second phase of recurrence vectorization.
176   void resetVectorValue(Value *Key, unsigned Part, Value *Vector) {
177     assert(hasVectorValue(Key, Part) && "Vector value not set for part");
178     VectorMapStorage[Key][Part] = Vector;
179   }
180 
181   /// Reset the scalar value associated with \p Key for \p Part and \p Lane.
182   /// This function can be used to update values that have already been
183   /// scalarized. This is the case for "fix-up" operations including scalar phi
184   /// nodes for scalarized and predicated instructions.
185   void resetScalarValue(Value *Key, const VPIteration &Instance,
186                         Value *Scalar) {
187     assert(hasScalarValue(Key, Instance) &&
188            "Scalar value not set for part and lane");
189     ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar;
190   }
191 };
192 
193 /// VPTransformState holds information passed down when "executing" a VPlan,
194 /// needed for generating the output IR.
195 struct VPTransformState {
196 
197   VPTransformState(unsigned VF, unsigned UF, class LoopInfo *LI,
198                    class DominatorTree *DT, IRBuilder<> &Builder,
199                    VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV)
200       : VF(VF), UF(UF), Instance(), LI(LI), DT(DT), Builder(Builder),
201         ValueMap(ValueMap), ILV(ILV) {}
202 
203   /// The chosen Vectorization and Unroll Factors of the loop being vectorized.
204   unsigned VF;
205   unsigned UF;
206 
207   /// Hold the indices to generate specific scalar instructions. Null indicates
208   /// that all instances are to be generated, using either scalar or vector
209   /// instructions.
210   Optional<VPIteration> Instance;
211 
212   /// Hold state information used when constructing the CFG of the output IR,
213   /// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks.
214   struct CFGState {
215     /// The previous VPBasicBlock visited. Initially set to null.
216     VPBasicBlock *PrevVPBB;
217     /// The previous IR BasicBlock created or used. Initially set to the new
218     /// header BasicBlock.
219     BasicBlock *PrevBB;
220     /// The last IR BasicBlock in the output IR. Set to the new latch
221     /// BasicBlock, used for placing the newly created BasicBlocks.
222     BasicBlock *LastBB;
223     /// A mapping of each VPBasicBlock to the corresponding BasicBlock. In case
224     /// of replication, maps the BasicBlock of the last replica created.
225     SmallDenseMap<VPBasicBlock *, BasicBlock *> VPBB2IRBB;
226 
227     CFGState() : PrevVPBB(nullptr), PrevBB(nullptr), LastBB(nullptr) {}
228   } CFG;
229 
230   /// Hold a pointer to LoopInfo to register new basic blocks in the loop.
231   class LoopInfo *LI;
232 
233   /// Hold a pointer to Dominator Tree to register new basic blocks in the loop.
234   class DominatorTree *DT;
235 
236   /// Hold a reference to the IRBuilder used to generate output IR code.
237   IRBuilder<> &Builder;
238 
239   /// Hold a reference to the Value state information used when generating the
240   /// Values of the output IR.
241   VectorizerValueMap &ValueMap;
242 
243   /// Hold a pointer to InnerLoopVectorizer to reuse its IR generation methods.
244   class InnerLoopVectorizer *ILV;
245 };
246 
247 /// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
248 /// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
249 class VPBlockBase {
250 private:
251   const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
252 
253   /// An optional name for the block.
254   std::string Name;
255 
256   /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if
257   /// it is a topmost VPBlockBase.
258   class VPRegionBlock *Parent;
259 
260   /// List of predecessor blocks.
261   SmallVector<VPBlockBase *, 1> Predecessors;
262 
263   /// List of successor blocks.
264   SmallVector<VPBlockBase *, 1> Successors;
265 
266   /// Add \p Successor as the last successor to this block.
267   void appendSuccessor(VPBlockBase *Successor) {
268     assert(Successor && "Cannot add nullptr successor!");
269     Successors.push_back(Successor);
270   }
271 
272   /// Add \p Predecessor as the last predecessor to this block.
273   void appendPredecessor(VPBlockBase *Predecessor) {
274     assert(Predecessor && "Cannot add nullptr predecessor!");
275     Predecessors.push_back(Predecessor);
276   }
277 
278   /// Remove \p Predecessor from the predecessors of this block.
279   void removePredecessor(VPBlockBase *Predecessor) {
280     auto Pos = std::find(Predecessors.begin(), Predecessors.end(), Predecessor);
281     assert(Pos && "Predecessor does not exist");
282     Predecessors.erase(Pos);
283   }
284 
285   /// Remove \p Successor from the successors of this block.
286   void removeSuccessor(VPBlockBase *Successor) {
287     auto Pos = std::find(Successors.begin(), Successors.end(), Successor);
288     assert(Pos && "Successor does not exist");
289     Successors.erase(Pos);
290   }
291 
292 protected:
293   VPBlockBase(const unsigned char SC, const std::string &N)
294       : SubclassID(SC), Name(N), Parent(nullptr) {}
295 
296 public:
297   /// An enumeration for keeping track of the concrete subclass of VPBlockBase
298   /// that are actually instantiated. Values of this enumeration are kept in the
299   /// SubclassID field of the VPBlockBase objects. They are used for concrete
300   /// type identification.
301   typedef enum { VPBasicBlockSC, VPRegionBlockSC } VPBlockTy;
302 
303   typedef SmallVectorImpl<VPBlockBase *> VPBlocksTy;
304 
305   virtual ~VPBlockBase() {}
306 
307   const std::string &getName() const { return Name; }
308 
309   void setName(const Twine &newName) { Name = newName.str(); }
310 
311   /// \return an ID for the concrete type of this object.
312   /// This is used to implement the classof checks. This should not be used
313   /// for any other purpose, as the values may change as LLVM evolves.
314   unsigned getVPBlockID() const { return SubclassID; }
315 
316   const VPRegionBlock *getParent() const { return Parent; }
317 
318   void setParent(VPRegionBlock *P) { Parent = P; }
319 
320   /// \return the VPBasicBlock that is the entry of this VPBlockBase,
321   /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
322   /// VPBlockBase is a VPBasicBlock, it is returned.
323   const VPBasicBlock *getEntryBasicBlock() const;
324   VPBasicBlock *getEntryBasicBlock();
325 
326   /// \return the VPBasicBlock that is the exit of this VPBlockBase,
327   /// recursively, if the latter is a VPRegionBlock. Otherwise, if this
328   /// VPBlockBase is a VPBasicBlock, it is returned.
329   const VPBasicBlock *getExitBasicBlock() const;
330   VPBasicBlock *getExitBasicBlock();
331 
332   const VPBlocksTy &getSuccessors() const { return Successors; }
333   VPBlocksTy &getSuccessors() { return Successors; }
334 
335   const VPBlocksTy &getPredecessors() const { return Predecessors; }
336   VPBlocksTy &getPredecessors() { return Predecessors; }
337 
338   /// \return the successor of this VPBlockBase if it has a single successor.
339   /// Otherwise return a null pointer.
340   VPBlockBase *getSingleSuccessor() const {
341     return (Successors.size() == 1 ? *Successors.begin() : nullptr);
342   }
343 
344   /// \return the predecessor of this VPBlockBase if it has a single
345   /// predecessor. Otherwise return a null pointer.
346   VPBlockBase *getSinglePredecessor() const {
347     return (Predecessors.size() == 1 ? *Predecessors.begin() : nullptr);
348   }
349 
350   /// An Enclosing Block of a block B is any block containing B, including B
351   /// itself. \return the closest enclosing block starting from "this", which
352   /// has successors. \return the root enclosing block if all enclosing blocks
353   /// have no successors.
354   VPBlockBase *getEnclosingBlockWithSuccessors();
355 
356   /// \return the closest enclosing block starting from "this", which has
357   /// predecessors. \return the root enclosing block if all enclosing blocks
358   /// have no predecessors.
359   VPBlockBase *getEnclosingBlockWithPredecessors();
360 
361   /// \return the successors either attached directly to this VPBlockBase or, if
362   /// this VPBlockBase is the exit block of a VPRegionBlock and has no
363   /// successors of its own, search recursively for the first enclosing
364   /// VPRegionBlock that has successors and return them. If no such
365   /// VPRegionBlock exists, return the (empty) successors of the topmost
366   /// VPBlockBase reached.
367   const VPBlocksTy &getHierarchicalSuccessors() {
368     return getEnclosingBlockWithSuccessors()->getSuccessors();
369   }
370 
371   /// \return the hierarchical successor of this VPBlockBase if it has a single
372   /// hierarchical successor. Otherwise return a null pointer.
373   VPBlockBase *getSingleHierarchicalSuccessor() {
374     return getEnclosingBlockWithSuccessors()->getSingleSuccessor();
375   }
376 
377   /// \return the predecessors either attached directly to this VPBlockBase or,
378   /// if this VPBlockBase is the entry block of a VPRegionBlock and has no
379   /// predecessors of its own, search recursively for the first enclosing
380   /// VPRegionBlock that has predecessors and return them. If no such
381   /// VPRegionBlock exists, return the (empty) predecessors of the topmost
382   /// VPBlockBase reached.
383   const VPBlocksTy &getHierarchicalPredecessors() {
384     return getEnclosingBlockWithPredecessors()->getPredecessors();
385   }
386 
387   /// \return the hierarchical predecessor of this VPBlockBase if it has a
388   /// single hierarchical predecessor. Otherwise return a null pointer.
389   VPBlockBase *getSingleHierarchicalPredecessor() {
390     return getEnclosingBlockWithPredecessors()->getSinglePredecessor();
391   }
392 
393   /// Sets a given VPBlockBase \p Successor as the single successor and \return
394   /// \p Successor. The parent of this Block is copied to be the parent of
395   /// \p Successor.
396   VPBlockBase *setOneSuccessor(VPBlockBase *Successor) {
397     assert(Successors.empty() && "Setting one successor when others exist.");
398     appendSuccessor(Successor);
399     Successor->appendPredecessor(this);
400     Successor->Parent = Parent;
401     return Successor;
402   }
403 
404   /// Sets two given VPBlockBases \p IfTrue and \p IfFalse to be the two
405   /// successors. The parent of this Block is copied to be the parent of both
406   /// \p IfTrue and \p IfFalse.
407   void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse) {
408     assert(Successors.empty() && "Setting two successors when others exist.");
409     appendSuccessor(IfTrue);
410     appendSuccessor(IfFalse);
411     IfTrue->appendPredecessor(this);
412     IfFalse->appendPredecessor(this);
413     IfTrue->Parent = Parent;
414     IfFalse->Parent = Parent;
415   }
416 
417   void disconnectSuccessor(VPBlockBase *Successor) {
418     assert(Successor && "Successor to disconnect is null.");
419     removeSuccessor(Successor);
420     Successor->removePredecessor(this);
421   }
422 
423   /// The method which generates the output IR that correspond to this
424   /// VPBlockBase, thereby "executing" the VPlan.
425   virtual void execute(struct VPTransformState *State) = 0;
426 
427   /// Delete all blocks reachable from a given VPBlockBase, inclusive.
428   static void deleteCFG(VPBlockBase *Entry);
429 };
430 
431 /// VPRecipeBase is a base class modeling a sequence of one or more output IR
432 /// instructions.
433 class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock> {
434   friend VPBasicBlock;
435 
436 private:
437   const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
438 
439   /// Each VPRecipe belongs to a single VPBasicBlock.
440   VPBasicBlock *Parent;
441 
442 public:
443   /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
444   /// that is actually instantiated. Values of this enumeration are kept in the
445   /// SubclassID field of the VPRecipeBase objects. They are used for concrete
446   /// type identification.
447   typedef enum {
448     VPBranchOnMaskSC,
449     VPInterleaveSC,
450     VPPredInstPHISC,
451     VPReplicateSC,
452     VPWidenIntOrFpInductionSC,
453     VPWidenPHISC,
454     VPWidenSC,
455   } VPRecipeTy;
456 
457   VPRecipeBase(const unsigned char SC) : SubclassID(SC), Parent(nullptr) {}
458 
459   virtual ~VPRecipeBase() {}
460 
461   /// \return an ID for the concrete type of this object.
462   /// This is used to implement the classof checks. This should not be used
463   /// for any other purpose, as the values may change as LLVM evolves.
464   unsigned getVPRecipeID() const { return SubclassID; }
465 
466   /// \return the VPBasicBlock which this VPRecipe belongs to.
467   VPBasicBlock *getParent() { return Parent; }
468   const VPBasicBlock *getParent() const { return Parent; }
469 
470   /// The method which generates the output IR instructions that correspond to
471   /// this VPRecipe, thereby "executing" the VPlan.
472   virtual void execute(struct VPTransformState &State) = 0;
473 
474   /// Each recipe prints itself.
475   virtual void print(raw_ostream &O, const Twine &Indent) const = 0;
476 };
477 
478 /// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
479 /// holds a sequence of zero or more VPRecipe's each representing a sequence of
480 /// output IR instructions.
481 class VPBasicBlock : public VPBlockBase {
482 public:
483   typedef iplist<VPRecipeBase> RecipeListTy;
484 
485 private:
486   /// The VPRecipes held in the order of output instructions to generate.
487   RecipeListTy Recipes;
488 
489 public:
490   /// Instruction iterators...
491   typedef RecipeListTy::iterator iterator;
492   typedef RecipeListTy::const_iterator const_iterator;
493   typedef RecipeListTy::reverse_iterator reverse_iterator;
494   typedef RecipeListTy::const_reverse_iterator const_reverse_iterator;
495 
496   //===--------------------------------------------------------------------===//
497   /// Recipe iterator methods
498   ///
499   inline iterator begin() { return Recipes.begin(); }
500   inline const_iterator begin() const { return Recipes.begin(); }
501   inline iterator end() { return Recipes.end(); }
502   inline const_iterator end() const { return Recipes.end(); }
503 
504   inline reverse_iterator rbegin() { return Recipes.rbegin(); }
505   inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); }
506   inline reverse_iterator rend() { return Recipes.rend(); }
507   inline const_reverse_iterator rend() const { return Recipes.rend(); }
508 
509   inline size_t size() const { return Recipes.size(); }
510   inline bool empty() const { return Recipes.empty(); }
511   inline const VPRecipeBase &front() const { return Recipes.front(); }
512   inline VPRecipeBase &front() { return Recipes.front(); }
513   inline const VPRecipeBase &back() const { return Recipes.back(); }
514   inline VPRecipeBase &back() { return Recipes.back(); }
515 
516   /// \brief Returns a pointer to a member of the recipe list.
517   static RecipeListTy VPBasicBlock::*getSublistAccess(VPRecipeBase *) {
518     return &VPBasicBlock::Recipes;
519   }
520 
521   VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr)
522       : VPBlockBase(VPBasicBlockSC, Name.str()) {
523     if (Recipe)
524       appendRecipe(Recipe);
525   }
526 
527   ~VPBasicBlock() { Recipes.clear(); }
528 
529   /// Method to support type inquiry through isa, cast, and dyn_cast.
530   static inline bool classof(const VPBlockBase *V) {
531     return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC;
532   }
533 
534   /// Augment the existing recipes of a VPBasicBlock with an additional
535   /// \p Recipe as the last recipe.
536   void appendRecipe(VPRecipeBase *Recipe) {
537     assert(Recipe && "No recipe to append.");
538     assert(!Recipe->Parent && "Recipe already in VPlan");
539     Recipe->Parent = this;
540     return Recipes.push_back(Recipe);
541   }
542 
543   /// The method which generates the output IR instructions that correspond to
544   /// this VPBasicBlock, thereby "executing" the VPlan.
545   void execute(struct VPTransformState *State) override;
546 
547 private:
548   /// Create an IR BasicBlock to hold the output instructions generated by this
549   /// VPBasicBlock, and return it. Update the CFGState accordingly.
550   BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG);
551 };
552 
553 /// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
554 /// which form a Single-Entry-Single-Exit subgraph of the output IR CFG.
555 /// A VPRegionBlock may indicate that its contents are to be replicated several
556 /// times. This is designed to support predicated scalarization, in which a
557 /// scalar if-then code structure needs to be generated VF * UF times. Having
558 /// this replication indicator helps to keep a single model for multiple
559 /// candidate VF's. The actual replication takes place only once the desired VF
560 /// and UF have been determined.
561 class VPRegionBlock : public VPBlockBase {
562 private:
563   /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
564   VPBlockBase *Entry;
565 
566   /// Hold the Single Exit of the SESE region modelled by the VPRegionBlock.
567   VPBlockBase *Exit;
568 
569   /// An indicator whether this region is to generate multiple replicated
570   /// instances of output IR corresponding to its VPBlockBases.
571   bool IsReplicator;
572 
573 public:
574   VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exit,
575                 const std::string &Name = "", bool IsReplicator = false)
576       : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exit(Exit),
577         IsReplicator(IsReplicator) {
578     assert(Entry->getPredecessors().empty() && "Entry block has predecessors.");
579     assert(Exit->getSuccessors().empty() && "Exit block has successors.");
580     Entry->setParent(this);
581     Exit->setParent(this);
582   }
583 
584   ~VPRegionBlock() {
585     if (Entry)
586       deleteCFG(Entry);
587   }
588 
589   /// Method to support type inquiry through isa, cast, and dyn_cast.
590   static inline bool classof(const VPBlockBase *V) {
591     return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
592   }
593 
594   const VPBlockBase *getEntry() const { return Entry; }
595   VPBlockBase *getEntry() { return Entry; }
596 
597   const VPBlockBase *getExit() const { return Exit; }
598   VPBlockBase *getExit() { return Exit; }
599 
600   /// An indicator whether this region is to generate multiple replicated
601   /// instances of output IR corresponding to its VPBlockBases.
602   bool isReplicator() const { return IsReplicator; }
603 
604   /// The method which generates the output IR instructions that correspond to
605   /// this VPRegionBlock, thereby "executing" the VPlan.
606   void execute(struct VPTransformState *State) override;
607 };
608 
609 /// VPlan models a candidate for vectorization, encoding various decisions take
610 /// to produce efficient output IR, including which branches, basic-blocks and
611 /// output IR instructions to generate, and their cost. VPlan holds a
612 /// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry
613 /// VPBlock.
614 class VPlan {
615 private:
616   /// Hold the single entry to the Hierarchical CFG of the VPlan.
617   VPBlockBase *Entry;
618 
619   /// Holds the VFs applicable to this VPlan.
620   SmallSet<unsigned, 2> VFs;
621 
622   /// Holds the name of the VPlan, for printing.
623   std::string Name;
624 
625 public:
626   VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) {}
627 
628   ~VPlan() {
629     if (Entry)
630       VPBlockBase::deleteCFG(Entry);
631   }
632 
633   /// Generate the IR code for this VPlan.
634   void execute(struct VPTransformState *State);
635 
636   VPBlockBase *getEntry() { return Entry; }
637   const VPBlockBase *getEntry() const { return Entry; }
638 
639   VPBlockBase *setEntry(VPBlockBase *Block) { return Entry = Block; }
640 
641   void addVF(unsigned VF) { VFs.insert(VF); }
642 
643   bool hasVF(unsigned VF) { return VFs.count(VF); }
644 
645   const std::string &getName() const { return Name; }
646 
647   void setName(const Twine &newName) { Name = newName.str(); }
648 
649 private:
650   /// Add to the given dominator tree the header block and every new basic block
651   /// that was created between it and the latch block, inclusive.
652   static void updateDominatorTree(class DominatorTree *DT,
653                                   BasicBlock *LoopPreHeaderBB,
654                                   BasicBlock *LoopLatchBB);
655 };
656 
657 /// VPlanPrinter prints a given VPlan to a given output stream. The printing is
658 /// indented and follows the dot format.
659 class VPlanPrinter {
660   friend inline raw_ostream &operator<<(raw_ostream &OS, VPlan &Plan);
661   friend inline raw_ostream &operator<<(raw_ostream &OS,
662                                         const struct VPlanIngredient &I);
663 
664 private:
665   raw_ostream &OS;
666   VPlan &Plan;
667   unsigned Depth;
668   unsigned TabWidth = 2;
669   std::string Indent;
670 
671   unsigned BID = 0;
672 
673   SmallDenseMap<const VPBlockBase *, unsigned> BlockID;
674 
675   /// Handle indentation.
676   void bumpIndent(int b) { Indent = std::string((Depth += b) * TabWidth, ' '); }
677 
678   /// Print a given \p Block of the Plan.
679   void dumpBlock(const VPBlockBase *Block);
680 
681   /// Print the information related to the CFG edges going out of a given
682   /// \p Block, followed by printing the successor blocks themselves.
683   void dumpEdges(const VPBlockBase *Block);
684 
685   /// Print a given \p BasicBlock, including its VPRecipes, followed by printing
686   /// its successor blocks.
687   void dumpBasicBlock(const VPBasicBlock *BasicBlock);
688 
689   /// Print a given \p Region of the Plan.
690   void dumpRegion(const VPRegionBlock *Region);
691 
692   unsigned getOrCreateBID(const VPBlockBase *Block) {
693     return BlockID.count(Block) ? BlockID[Block] : BlockID[Block] = BID++;
694   }
695 
696   const Twine getOrCreateName(const VPBlockBase *Block);
697 
698   const Twine getUID(const VPBlockBase *Block);
699 
700   /// Print the information related to a CFG edge between two VPBlockBases.
701   void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden,
702                 const Twine &Label);
703 
704   VPlanPrinter(raw_ostream &O, VPlan &P) : OS(O), Plan(P) {}
705 
706   void dump();
707 
708   static void printAsIngredient(raw_ostream &O, Value *V);
709 };
710 
711 struct VPlanIngredient {
712   Value *V;
713   VPlanIngredient(Value *V) : V(V) {}
714 };
715 
716 inline raw_ostream &operator<<(raw_ostream &OS, const VPlanIngredient &I) {
717   VPlanPrinter::printAsIngredient(OS, I.V);
718   return OS;
719 }
720 
721 inline raw_ostream &operator<<(raw_ostream &OS, VPlan &Plan) {
722   VPlanPrinter Printer(OS, Plan);
723   Printer.dump();
724   return OS;
725 }
726 
727 //===--------------------------------------------------------------------===//
728 // GraphTraits specializations for VPlan/VPRegionBlock Control-Flow Graphs  //
729 //===--------------------------------------------------------------------===//
730 
731 // Provide specializations of GraphTraits to be able to treat a VPBlockBase as a
732 // graph of VPBlockBase nodes...
733 
734 template <> struct GraphTraits<VPBlockBase *> {
735   typedef VPBlockBase *NodeRef;
736   typedef SmallVectorImpl<VPBlockBase *>::iterator ChildIteratorType;
737 
738   static NodeRef getEntryNode(NodeRef N) { return N; }
739 
740   static inline ChildIteratorType child_begin(NodeRef N) {
741     return N->getSuccessors().begin();
742   }
743 
744   static inline ChildIteratorType child_end(NodeRef N) {
745     return N->getSuccessors().end();
746   }
747 };
748 
749 template <> struct GraphTraits<const VPBlockBase *> {
750   typedef const VPBlockBase *NodeRef;
751   typedef SmallVectorImpl<VPBlockBase *>::const_iterator ChildIteratorType;
752 
753   static NodeRef getEntryNode(NodeRef N) { return N; }
754 
755   static inline ChildIteratorType child_begin(NodeRef N) {
756     return N->getSuccessors().begin();
757   }
758 
759   static inline ChildIteratorType child_end(NodeRef N) {
760     return N->getSuccessors().end();
761   }
762 };
763 
764 // Provide specializations of GraphTraits to be able to treat a VPBlockBase as a
765 // graph of VPBlockBase nodes... and to walk it in inverse order. Inverse order
766 // for a VPBlockBase is considered to be when traversing the predecessors of a
767 // VPBlockBase instead of its successors.
768 //
769 
770 template <> struct GraphTraits<Inverse<VPBlockBase *>> {
771   typedef VPBlockBase *NodeRef;
772   typedef SmallVectorImpl<VPBlockBase *>::iterator ChildIteratorType;
773 
774   static Inverse<VPBlockBase *> getEntryNode(Inverse<VPBlockBase *> B) {
775     return B;
776   }
777 
778   static inline ChildIteratorType child_begin(NodeRef N) {
779     return N->getPredecessors().begin();
780   }
781 
782   static inline ChildIteratorType child_end(NodeRef N) {
783     return N->getPredecessors().end();
784   }
785 };
786 
787 } // namespace llvm
788 
789 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
790