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