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