1 //===- VPlan.h - Represent A Vectorizer Plan --------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// This file contains the declarations of the Vectorization Plan base classes: 11 /// 1. VPBasicBlock and VPRegionBlock that inherit from a common pure virtual 12 /// VPBlockBase, together implementing a Hierarchical CFG; 13 /// 2. Specializations of GraphTraits that allow VPBlockBase graphs to be 14 /// treated as proper graphs for generic algorithms; 15 /// 3. Pure virtual VPRecipeBase serving as the base class for recipes contained 16 /// within VPBasicBlocks; 17 /// 4. VPInstruction, a concrete Recipe and VPUser modeling a single planned 18 /// instruction; 19 /// 5. The VPlan class holding a candidate for vectorization; 20 /// 6. The VPlanPrinter class providing a way to print a plan in dot format; 21 /// These are documented in docs/VectorizationPlan.rst. 22 // 23 //===----------------------------------------------------------------------===// 24 25 #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H 26 #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H 27 28 #include "VPlanLoopInfo.h" 29 #include "VPlanValue.h" 30 #include "llvm/ADT/DenseMap.h" 31 #include "llvm/ADT/DepthFirstIterator.h" 32 #include "llvm/ADT/GraphTraits.h" 33 #include "llvm/ADT/Optional.h" 34 #include "llvm/ADT/SmallBitVector.h" 35 #include "llvm/ADT/SmallPtrSet.h" 36 #include "llvm/ADT/SmallSet.h" 37 #include "llvm/ADT/SmallVector.h" 38 #include "llvm/ADT/Twine.h" 39 #include "llvm/ADT/ilist.h" 40 #include "llvm/ADT/ilist_node.h" 41 #include "llvm/Analysis/VectorUtils.h" 42 #include "llvm/IR/IRBuilder.h" 43 #include <algorithm> 44 #include <cassert> 45 #include <cstddef> 46 #include <map> 47 #include <string> 48 49 namespace llvm { 50 51 class BasicBlock; 52 class DominatorTree; 53 class InnerLoopVectorizer; 54 class LoopInfo; 55 class raw_ostream; 56 class RecurrenceDescriptor; 57 class Value; 58 class VPBasicBlock; 59 class VPRegionBlock; 60 class VPlan; 61 class VPlanSlp; 62 63 /// A range of powers-of-2 vectorization factors with fixed start and 64 /// adjustable end. The range includes start and excludes end, e.g.,: 65 /// [1, 9) = {1, 2, 4, 8} 66 struct VFRange { 67 // A power of 2. 68 const unsigned Start; 69 70 // Need not be a power of 2. If End <= Start range is empty. 71 unsigned End; 72 }; 73 74 using VPlanPtr = std::unique_ptr<VPlan>; 75 76 /// In what follows, the term "input IR" refers to code that is fed into the 77 /// vectorizer whereas the term "output IR" refers to code that is generated by 78 /// the vectorizer. 79 80 /// VPIteration represents a single point in the iteration space of the output 81 /// (vectorized and/or unrolled) IR loop. 82 struct VPIteration { 83 /// in [0..UF) 84 unsigned Part; 85 86 /// in [0..VF) 87 unsigned Lane; 88 }; 89 90 /// This is a helper struct for maintaining vectorization state. It's used for 91 /// mapping values from the original loop to their corresponding values in 92 /// the new loop. Two mappings are maintained: one for vectorized values and 93 /// one for scalarized values. Vectorized values are represented with UF 94 /// vector values in the new loop, and scalarized values are represented with 95 /// UF x VF scalar values in the new loop. UF and VF are the unroll and 96 /// vectorization factors, respectively. 97 /// 98 /// Entries can be added to either map with setVectorValue and setScalarValue, 99 /// which assert that an entry was not already added before. If an entry is to 100 /// replace an existing one, call resetVectorValue and resetScalarValue. This is 101 /// currently needed to modify the mapped values during "fix-up" operations that 102 /// occur once the first phase of widening is complete. These operations include 103 /// type truncation and the second phase of recurrence widening. 104 /// 105 /// Entries from either map can be retrieved using the getVectorValue and 106 /// getScalarValue functions, which assert that the desired value exists. 107 struct VectorizerValueMap { 108 friend struct VPTransformState; 109 110 private: 111 /// The unroll factor. Each entry in the vector map contains UF vector values. 112 unsigned UF; 113 114 /// The vectorization factor. Each entry in the scalar map contains UF x VF 115 /// scalar values. 116 ElementCount VF; 117 118 /// The vector and scalar map storage. We use std::map and not DenseMap 119 /// because insertions to DenseMap invalidate its iterators. 120 using VectorParts = SmallVector<Value *, 2>; 121 using ScalarParts = SmallVector<SmallVector<Value *, 4>, 2>; 122 std::map<Value *, VectorParts> VectorMapStorage; 123 std::map<Value *, ScalarParts> ScalarMapStorage; 124 125 public: 126 /// Construct an empty map with the given unroll and vectorization factors. 127 VectorizerValueMap(unsigned UF, ElementCount VF) : UF(UF), VF(VF) {} 128 129 /// \return True if the map has any vector entry for \p Key. 130 bool hasAnyVectorValue(Value *Key) const { 131 return VectorMapStorage.count(Key); 132 } 133 134 /// \return True if the map has a vector entry for \p Key and \p Part. 135 bool hasVectorValue(Value *Key, unsigned Part) const { 136 assert(Part < UF && "Queried Vector Part is too large."); 137 if (!hasAnyVectorValue(Key)) 138 return false; 139 const VectorParts &Entry = VectorMapStorage.find(Key)->second; 140 assert(Entry.size() == UF && "VectorParts has wrong dimensions."); 141 return Entry[Part] != nullptr; 142 } 143 144 /// \return True if the map has any scalar entry for \p Key. 145 bool hasAnyScalarValue(Value *Key) const { 146 return ScalarMapStorage.count(Key); 147 } 148 149 /// \return True if the map has a scalar entry for \p Key and \p Instance. 150 bool hasScalarValue(Value *Key, const VPIteration &Instance) const { 151 assert(Instance.Part < UF && "Queried Scalar Part is too large."); 152 assert(Instance.Lane < VF.getKnownMinValue() && 153 "Queried Scalar Lane is too large."); 154 assert(!VF.isScalable() && "VF is assumed to be non scalable."); 155 156 if (!hasAnyScalarValue(Key)) 157 return false; 158 const ScalarParts &Entry = ScalarMapStorage.find(Key)->second; 159 assert(Entry.size() == UF && "ScalarParts has wrong dimensions."); 160 assert(Entry[Instance.Part].size() == VF.getKnownMinValue() && 161 "ScalarParts has wrong dimensions."); 162 return Entry[Instance.Part][Instance.Lane] != nullptr; 163 } 164 165 /// Retrieve the existing vector value that corresponds to \p Key and 166 /// \p Part. 167 Value *getVectorValue(Value *Key, unsigned Part) { 168 assert(hasVectorValue(Key, Part) && "Getting non-existent value."); 169 return VectorMapStorage[Key][Part]; 170 } 171 172 /// Retrieve the existing scalar value that corresponds to \p Key and 173 /// \p Instance. 174 Value *getScalarValue(Value *Key, const VPIteration &Instance) { 175 assert(hasScalarValue(Key, Instance) && "Getting non-existent value."); 176 return ScalarMapStorage[Key][Instance.Part][Instance.Lane]; 177 } 178 179 /// Set a vector value associated with \p Key and \p Part. Assumes such a 180 /// value is not already set. If it is, use resetVectorValue() instead. 181 void setVectorValue(Value *Key, unsigned Part, Value *Vector) { 182 assert(!hasVectorValue(Key, Part) && "Vector value already set for part"); 183 if (!VectorMapStorage.count(Key)) { 184 VectorParts Entry(UF); 185 VectorMapStorage[Key] = Entry; 186 } 187 VectorMapStorage[Key][Part] = Vector; 188 } 189 190 /// Set a scalar value associated with \p Key and \p Instance. Assumes such a 191 /// value is not already set. 192 void setScalarValue(Value *Key, const VPIteration &Instance, Value *Scalar) { 193 assert(!hasScalarValue(Key, Instance) && "Scalar value already set"); 194 if (!ScalarMapStorage.count(Key)) { 195 ScalarParts Entry(UF); 196 // TODO: Consider storing uniform values only per-part, as they occupy 197 // lane 0 only, keeping the other VF-1 redundant entries null. 198 for (unsigned Part = 0; Part < UF; ++Part) 199 Entry[Part].resize(VF.getKnownMinValue(), nullptr); 200 ScalarMapStorage[Key] = Entry; 201 } 202 ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar; 203 } 204 205 /// Reset the vector value associated with \p Key for the given \p Part. 206 /// This function can be used to update values that have already been 207 /// vectorized. This is the case for "fix-up" operations including type 208 /// truncation and the second phase of recurrence vectorization. 209 void resetVectorValue(Value *Key, unsigned Part, Value *Vector) { 210 assert(hasVectorValue(Key, Part) && "Vector value not set for part"); 211 VectorMapStorage[Key][Part] = Vector; 212 } 213 214 /// Reset the scalar value associated with \p Key for \p Part and \p Lane. 215 /// This function can be used to update values that have already been 216 /// scalarized. This is the case for "fix-up" operations including scalar phi 217 /// nodes for scalarized and predicated instructions. 218 void resetScalarValue(Value *Key, const VPIteration &Instance, 219 Value *Scalar) { 220 assert(hasScalarValue(Key, Instance) && 221 "Scalar value not set for part and lane"); 222 ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar; 223 } 224 }; 225 226 /// This class is used to enable the VPlan to invoke a method of ILV. This is 227 /// needed until the method is refactored out of ILV and becomes reusable. 228 struct VPCallback { 229 virtual ~VPCallback() {} 230 virtual Value *getOrCreateVectorValues(Value *V, unsigned Part) = 0; 231 virtual Value *getOrCreateScalarValue(Value *V, 232 const VPIteration &Instance) = 0; 233 }; 234 235 /// VPTransformState holds information passed down when "executing" a VPlan, 236 /// needed for generating the output IR. 237 struct VPTransformState { 238 VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI, 239 DominatorTree *DT, IRBuilder<> &Builder, 240 VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV, 241 VPCallback &Callback) 242 : VF(VF), UF(UF), Instance(), LI(LI), DT(DT), Builder(Builder), 243 ValueMap(ValueMap), ILV(ILV), Callback(Callback) {} 244 245 /// The chosen Vectorization and Unroll Factors of the loop being vectorized. 246 ElementCount VF; 247 unsigned UF; 248 249 /// Hold the indices to generate specific scalar instructions. Null indicates 250 /// that all instances are to be generated, using either scalar or vector 251 /// instructions. 252 Optional<VPIteration> Instance; 253 254 struct DataState { 255 /// A type for vectorized values in the new loop. Each value from the 256 /// original loop, when vectorized, is represented by UF vector values in 257 /// the new unrolled loop, where UF is the unroll factor. 258 typedef SmallVector<Value *, 2> PerPartValuesTy; 259 260 DenseMap<VPValue *, PerPartValuesTy> PerPartOutput; 261 } Data; 262 263 /// Get the generated Value for a given VPValue and a given Part. Note that 264 /// as some Defs are still created by ILV and managed in its ValueMap, this 265 /// method will delegate the call to ILV in such cases in order to provide 266 /// callers a consistent API. 267 /// \see set. 268 Value *get(VPValue *Def, unsigned Part) { 269 // If Values have been set for this Def return the one relevant for \p Part. 270 if (Data.PerPartOutput.count(Def)) 271 return Data.PerPartOutput[Def][Part]; 272 // Def is managed by ILV: bring the Values from ValueMap. 273 return Callback.getOrCreateVectorValues(VPValue2Value[Def], Part); 274 } 275 276 /// Get the generated Value for a given VPValue and given Part and Lane. 277 Value *get(VPValue *Def, const VPIteration &Instance) { 278 // If the Def is managed directly by VPTransformState, extract the lane from 279 // the relevant part. Note that currently only VPInstructions and external 280 // defs are managed by VPTransformState. Other Defs are still created by ILV 281 // and managed in its ValueMap. For those this method currently just 282 // delegates the call to ILV below. 283 if (Data.PerPartOutput.count(Def)) { 284 auto *VecPart = Data.PerPartOutput[Def][Instance.Part]; 285 // TODO: Cache created scalar values. 286 return Builder.CreateExtractElement(VecPart, 287 Builder.getInt32(Instance.Lane)); 288 } 289 290 return Callback.getOrCreateScalarValue(VPValue2Value[Def], Instance); 291 } 292 293 /// Set the generated Value for a given VPValue and a given Part. 294 void set(VPValue *Def, Value *V, unsigned Part) { 295 if (!Data.PerPartOutput.count(Def)) { 296 DataState::PerPartValuesTy Entry(UF); 297 Data.PerPartOutput[Def] = Entry; 298 } 299 Data.PerPartOutput[Def][Part] = V; 300 } 301 302 /// Hold state information used when constructing the CFG of the output IR, 303 /// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks. 304 struct CFGState { 305 /// The previous VPBasicBlock visited. Initially set to null. 306 VPBasicBlock *PrevVPBB = nullptr; 307 308 /// The previous IR BasicBlock created or used. Initially set to the new 309 /// header BasicBlock. 310 BasicBlock *PrevBB = nullptr; 311 312 /// The last IR BasicBlock in the output IR. Set to the new latch 313 /// BasicBlock, used for placing the newly created BasicBlocks. 314 BasicBlock *LastBB = nullptr; 315 316 /// A mapping of each VPBasicBlock to the corresponding BasicBlock. In case 317 /// of replication, maps the BasicBlock of the last replica created. 318 SmallDenseMap<VPBasicBlock *, BasicBlock *> VPBB2IRBB; 319 320 /// Vector of VPBasicBlocks whose terminator instruction needs to be fixed 321 /// up at the end of vector code generation. 322 SmallVector<VPBasicBlock *, 8> VPBBsToFix; 323 324 CFGState() = default; 325 } CFG; 326 327 /// Hold a pointer to LoopInfo to register new basic blocks in the loop. 328 LoopInfo *LI; 329 330 /// Hold a pointer to Dominator Tree to register new basic blocks in the loop. 331 DominatorTree *DT; 332 333 /// Hold a reference to the IRBuilder used to generate output IR code. 334 IRBuilder<> &Builder; 335 336 /// Hold a reference to the Value state information used when generating the 337 /// Values of the output IR. 338 VectorizerValueMap &ValueMap; 339 340 /// Hold a reference to a mapping between VPValues in VPlan and original 341 /// Values they correspond to. 342 VPValue2ValueTy VPValue2Value; 343 344 /// Hold the canonical scalar IV of the vector loop (start=0, step=VF*UF). 345 Value *CanonicalIV = nullptr; 346 347 /// Hold the trip count of the scalar loop. 348 Value *TripCount = nullptr; 349 350 /// Hold a pointer to InnerLoopVectorizer to reuse its IR generation methods. 351 InnerLoopVectorizer *ILV; 352 353 VPCallback &Callback; 354 }; 355 356 /// VPBlockBase is the building block of the Hierarchical Control-Flow Graph. 357 /// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock. 358 class VPBlockBase { 359 friend class VPBlockUtils; 360 361 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast). 362 363 /// An optional name for the block. 364 std::string Name; 365 366 /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if 367 /// it is a topmost VPBlockBase. 368 VPRegionBlock *Parent = nullptr; 369 370 /// List of predecessor blocks. 371 SmallVector<VPBlockBase *, 1> Predecessors; 372 373 /// List of successor blocks. 374 SmallVector<VPBlockBase *, 1> Successors; 375 376 /// Successor selector, null for zero or single successor blocks. 377 VPValue *CondBit = nullptr; 378 379 /// Current block predicate - null if the block does not need a predicate. 380 VPValue *Predicate = nullptr; 381 382 /// VPlan containing the block. Can only be set on the entry block of the 383 /// plan. 384 VPlan *Plan = nullptr; 385 386 /// Add \p Successor as the last successor to this block. 387 void appendSuccessor(VPBlockBase *Successor) { 388 assert(Successor && "Cannot add nullptr successor!"); 389 Successors.push_back(Successor); 390 } 391 392 /// Add \p Predecessor as the last predecessor to this block. 393 void appendPredecessor(VPBlockBase *Predecessor) { 394 assert(Predecessor && "Cannot add nullptr predecessor!"); 395 Predecessors.push_back(Predecessor); 396 } 397 398 /// Remove \p Predecessor from the predecessors of this block. 399 void removePredecessor(VPBlockBase *Predecessor) { 400 auto Pos = std::find(Predecessors.begin(), Predecessors.end(), Predecessor); 401 assert(Pos && "Predecessor does not exist"); 402 Predecessors.erase(Pos); 403 } 404 405 /// Remove \p Successor from the successors of this block. 406 void removeSuccessor(VPBlockBase *Successor) { 407 auto Pos = std::find(Successors.begin(), Successors.end(), Successor); 408 assert(Pos && "Successor does not exist"); 409 Successors.erase(Pos); 410 } 411 412 protected: 413 VPBlockBase(const unsigned char SC, const std::string &N) 414 : SubclassID(SC), Name(N) {} 415 416 public: 417 /// An enumeration for keeping track of the concrete subclass of VPBlockBase 418 /// that are actually instantiated. Values of this enumeration are kept in the 419 /// SubclassID field of the VPBlockBase objects. They are used for concrete 420 /// type identification. 421 using VPBlockTy = enum { VPBasicBlockSC, VPRegionBlockSC }; 422 423 using VPBlocksTy = SmallVectorImpl<VPBlockBase *>; 424 425 virtual ~VPBlockBase() = default; 426 427 const std::string &getName() const { return Name; } 428 429 void setName(const Twine &newName) { Name = newName.str(); } 430 431 /// \return an ID for the concrete type of this object. 432 /// This is used to implement the classof checks. This should not be used 433 /// for any other purpose, as the values may change as LLVM evolves. 434 unsigned getVPBlockID() const { return SubclassID; } 435 436 VPRegionBlock *getParent() { return Parent; } 437 const VPRegionBlock *getParent() const { return Parent; } 438 439 /// \return A pointer to the plan containing the current block. 440 VPlan *getPlan(); 441 const VPlan *getPlan() const; 442 443 /// Sets the pointer of the plan containing the block. The block must be the 444 /// entry block into the VPlan. 445 void setPlan(VPlan *ParentPlan); 446 447 void setParent(VPRegionBlock *P) { Parent = P; } 448 449 /// \return the VPBasicBlock that is the entry of this VPBlockBase, 450 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this 451 /// VPBlockBase is a VPBasicBlock, it is returned. 452 const VPBasicBlock *getEntryBasicBlock() const; 453 VPBasicBlock *getEntryBasicBlock(); 454 455 /// \return the VPBasicBlock that is the exit of this VPBlockBase, 456 /// recursively, if the latter is a VPRegionBlock. Otherwise, if this 457 /// VPBlockBase is a VPBasicBlock, it is returned. 458 const VPBasicBlock *getExitBasicBlock() const; 459 VPBasicBlock *getExitBasicBlock(); 460 461 const VPBlocksTy &getSuccessors() const { return Successors; } 462 VPBlocksTy &getSuccessors() { return Successors; } 463 464 const VPBlocksTy &getPredecessors() const { return Predecessors; } 465 VPBlocksTy &getPredecessors() { return Predecessors; } 466 467 /// \return the successor of this VPBlockBase if it has a single successor. 468 /// Otherwise return a null pointer. 469 VPBlockBase *getSingleSuccessor() const { 470 return (Successors.size() == 1 ? *Successors.begin() : nullptr); 471 } 472 473 /// \return the predecessor of this VPBlockBase if it has a single 474 /// predecessor. Otherwise return a null pointer. 475 VPBlockBase *getSinglePredecessor() const { 476 return (Predecessors.size() == 1 ? *Predecessors.begin() : nullptr); 477 } 478 479 size_t getNumSuccessors() const { return Successors.size(); } 480 size_t getNumPredecessors() const { return Predecessors.size(); } 481 482 /// An Enclosing Block of a block B is any block containing B, including B 483 /// itself. \return the closest enclosing block starting from "this", which 484 /// has successors. \return the root enclosing block if all enclosing blocks 485 /// have no successors. 486 VPBlockBase *getEnclosingBlockWithSuccessors(); 487 488 /// \return the closest enclosing block starting from "this", which has 489 /// predecessors. \return the root enclosing block if all enclosing blocks 490 /// have no predecessors. 491 VPBlockBase *getEnclosingBlockWithPredecessors(); 492 493 /// \return the successors either attached directly to this VPBlockBase or, if 494 /// this VPBlockBase is the exit block of a VPRegionBlock and has no 495 /// successors of its own, search recursively for the first enclosing 496 /// VPRegionBlock that has successors and return them. If no such 497 /// VPRegionBlock exists, return the (empty) successors of the topmost 498 /// VPBlockBase reached. 499 const VPBlocksTy &getHierarchicalSuccessors() { 500 return getEnclosingBlockWithSuccessors()->getSuccessors(); 501 } 502 503 /// \return the hierarchical successor of this VPBlockBase if it has a single 504 /// hierarchical successor. Otherwise return a null pointer. 505 VPBlockBase *getSingleHierarchicalSuccessor() { 506 return getEnclosingBlockWithSuccessors()->getSingleSuccessor(); 507 } 508 509 /// \return the predecessors either attached directly to this VPBlockBase or, 510 /// if this VPBlockBase is the entry block of a VPRegionBlock and has no 511 /// predecessors of its own, search recursively for the first enclosing 512 /// VPRegionBlock that has predecessors and return them. If no such 513 /// VPRegionBlock exists, return the (empty) predecessors of the topmost 514 /// VPBlockBase reached. 515 const VPBlocksTy &getHierarchicalPredecessors() { 516 return getEnclosingBlockWithPredecessors()->getPredecessors(); 517 } 518 519 /// \return the hierarchical predecessor of this VPBlockBase if it has a 520 /// single hierarchical predecessor. Otherwise return a null pointer. 521 VPBlockBase *getSingleHierarchicalPredecessor() { 522 return getEnclosingBlockWithPredecessors()->getSinglePredecessor(); 523 } 524 525 /// \return the condition bit selecting the successor. 526 VPValue *getCondBit() { return CondBit; } 527 528 const VPValue *getCondBit() const { return CondBit; } 529 530 void setCondBit(VPValue *CV) { CondBit = CV; } 531 532 VPValue *getPredicate() { return Predicate; } 533 534 const VPValue *getPredicate() const { return Predicate; } 535 536 void setPredicate(VPValue *Pred) { Predicate = Pred; } 537 538 /// Set a given VPBlockBase \p Successor as the single successor of this 539 /// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor. 540 /// This VPBlockBase must have no successors. 541 void setOneSuccessor(VPBlockBase *Successor) { 542 assert(Successors.empty() && "Setting one successor when others exist."); 543 appendSuccessor(Successor); 544 } 545 546 /// Set two given VPBlockBases \p IfTrue and \p IfFalse to be the two 547 /// successors of this VPBlockBase. \p Condition is set as the successor 548 /// selector. This VPBlockBase is not added as predecessor of \p IfTrue or \p 549 /// IfFalse. This VPBlockBase must have no successors. 550 void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse, 551 VPValue *Condition) { 552 assert(Successors.empty() && "Setting two successors when others exist."); 553 assert(Condition && "Setting two successors without condition!"); 554 CondBit = Condition; 555 appendSuccessor(IfTrue); 556 appendSuccessor(IfFalse); 557 } 558 559 /// Set each VPBasicBlock in \p NewPreds as predecessor of this VPBlockBase. 560 /// This VPBlockBase must have no predecessors. This VPBlockBase is not added 561 /// as successor of any VPBasicBlock in \p NewPreds. 562 void setPredecessors(ArrayRef<VPBlockBase *> NewPreds) { 563 assert(Predecessors.empty() && "Block predecessors already set."); 564 for (auto *Pred : NewPreds) 565 appendPredecessor(Pred); 566 } 567 568 /// Remove all the predecessor of this block. 569 void clearPredecessors() { Predecessors.clear(); } 570 571 /// Remove all the successors of this block and set to null its condition bit 572 void clearSuccessors() { 573 Successors.clear(); 574 CondBit = nullptr; 575 } 576 577 /// The method which generates the output IR that correspond to this 578 /// VPBlockBase, thereby "executing" the VPlan. 579 virtual void execute(struct VPTransformState *State) = 0; 580 581 /// Delete all blocks reachable from a given VPBlockBase, inclusive. 582 static void deleteCFG(VPBlockBase *Entry); 583 584 void printAsOperand(raw_ostream &OS, bool PrintType) const { 585 OS << getName(); 586 } 587 588 void print(raw_ostream &OS) const { 589 // TODO: Only printing VPBB name for now since we only have dot printing 590 // support for VPInstructions/Recipes. 591 printAsOperand(OS, false); 592 } 593 594 /// Return true if it is legal to hoist instructions into this block. 595 bool isLegalToHoistInto() { 596 // There are currently no constraints that prevent an instruction to be 597 // hoisted into a VPBlockBase. 598 return true; 599 } 600 }; 601 602 /// VPRecipeBase is a base class modeling a sequence of one or more output IR 603 /// instructions. 604 class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock> { 605 friend VPBasicBlock; 606 friend class VPBlockUtils; 607 608 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast). 609 610 /// Each VPRecipe belongs to a single VPBasicBlock. 611 VPBasicBlock *Parent = nullptr; 612 613 public: 614 /// An enumeration for keeping track of the concrete subclass of VPRecipeBase 615 /// that is actually instantiated. Values of this enumeration are kept in the 616 /// SubclassID field of the VPRecipeBase objects. They are used for concrete 617 /// type identification. 618 using VPRecipeTy = enum { 619 VPBlendSC, 620 VPBranchOnMaskSC, 621 VPInstructionSC, 622 VPInterleaveSC, 623 VPPredInstPHISC, 624 VPReductionSC, 625 VPReplicateSC, 626 VPWidenCallSC, 627 VPWidenCanonicalIVSC, 628 VPWidenGEPSC, 629 VPWidenIntOrFpInductionSC, 630 VPWidenMemoryInstructionSC, 631 VPWidenPHISC, 632 VPWidenSC, 633 VPWidenSelectSC 634 }; 635 636 VPRecipeBase(const unsigned char SC) : SubclassID(SC) {} 637 virtual ~VPRecipeBase() = default; 638 639 /// \return an ID for the concrete type of this object. 640 /// This is used to implement the classof checks. This should not be used 641 /// for any other purpose, as the values may change as LLVM evolves. 642 unsigned getVPRecipeID() const { return SubclassID; } 643 644 /// \return the VPBasicBlock which this VPRecipe belongs to. 645 VPBasicBlock *getParent() { return Parent; } 646 const VPBasicBlock *getParent() const { return Parent; } 647 648 /// The method which generates the output IR instructions that correspond to 649 /// this VPRecipe, thereby "executing" the VPlan. 650 virtual void execute(struct VPTransformState &State) = 0; 651 652 /// Each recipe prints itself. 653 virtual void print(raw_ostream &O, const Twine &Indent, 654 VPSlotTracker &SlotTracker) const = 0; 655 656 /// Dump the recipe to stderr (for debugging). 657 void dump() const; 658 659 /// Insert an unlinked recipe into a basic block immediately before 660 /// the specified recipe. 661 void insertBefore(VPRecipeBase *InsertPos); 662 663 /// Insert an unlinked Recipe into a basic block immediately after 664 /// the specified Recipe. 665 void insertAfter(VPRecipeBase *InsertPos); 666 667 /// Unlink this recipe from its current VPBasicBlock and insert it into 668 /// the VPBasicBlock that MovePos lives in, right after MovePos. 669 void moveAfter(VPRecipeBase *MovePos); 670 671 /// This method unlinks 'this' from the containing basic block, but does not 672 /// delete it. 673 void removeFromParent(); 674 675 /// This method unlinks 'this' from the containing basic block and deletes it. 676 /// 677 /// \returns an iterator pointing to the element after the erased one 678 iplist<VPRecipeBase>::iterator eraseFromParent(); 679 680 /// Returns a pointer to a VPUser, if the recipe inherits from VPUser or 681 /// nullptr otherwise. 682 VPUser *toVPUser(); 683 684 /// Returns a pointer to a VPValue, if the recipe inherits from VPValue or 685 /// nullptr otherwise. 686 VPValue *toVPValue(); 687 }; 688 689 inline bool VPUser::classof(const VPRecipeBase *Recipe) { 690 return Recipe->getVPRecipeID() == VPRecipeBase::VPInstructionSC || 691 Recipe->getVPRecipeID() == VPRecipeBase::VPWidenSC || 692 Recipe->getVPRecipeID() == VPRecipeBase::VPWidenCallSC || 693 Recipe->getVPRecipeID() == VPRecipeBase::VPWidenSelectSC || 694 Recipe->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC || 695 Recipe->getVPRecipeID() == VPRecipeBase::VPBlendSC || 696 Recipe->getVPRecipeID() == VPRecipeBase::VPInterleaveSC || 697 Recipe->getVPRecipeID() == VPRecipeBase::VPReplicateSC || 698 Recipe->getVPRecipeID() == VPRecipeBase::VPBranchOnMaskSC || 699 Recipe->getVPRecipeID() == VPRecipeBase::VPWidenMemoryInstructionSC; 700 } 701 702 /// This is a concrete Recipe that models a single VPlan-level instruction. 703 /// While as any Recipe it may generate a sequence of IR instructions when 704 /// executed, these instructions would always form a single-def expression as 705 /// the VPInstruction is also a single def-use vertex. 706 class VPInstruction : public VPUser, public VPValue, public VPRecipeBase { 707 friend class VPlanSlp; 708 709 public: 710 /// VPlan opcodes, extending LLVM IR with idiomatics instructions. 711 enum { 712 Not = Instruction::OtherOpsEnd + 1, 713 ICmpULE, 714 SLPLoad, 715 SLPStore, 716 ActiveLaneMask, 717 }; 718 719 private: 720 typedef unsigned char OpcodeTy; 721 OpcodeTy Opcode; 722 723 /// Utility method serving execute(): generates a single instance of the 724 /// modeled instruction. 725 void generateInstruction(VPTransformState &State, unsigned Part); 726 727 protected: 728 Instruction *getUnderlyingInstr() { 729 return cast_or_null<Instruction>(getUnderlyingValue()); 730 } 731 732 void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); } 733 734 public: 735 VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands) 736 : VPUser(Operands), VPValue(VPValue::VPInstructionSC), 737 VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {} 738 739 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands) 740 : VPInstruction(Opcode, ArrayRef<VPValue *>(Operands)) {} 741 742 /// Method to support type inquiry through isa, cast, and dyn_cast. 743 static inline bool classof(const VPValue *V) { 744 return V->getVPValueID() == VPValue::VPInstructionSC; 745 } 746 747 VPInstruction *clone() const { 748 SmallVector<VPValue *, 2> Operands(operands()); 749 return new VPInstruction(Opcode, Operands); 750 } 751 752 /// Method to support type inquiry through isa, cast, and dyn_cast. 753 static inline bool classof(const VPRecipeBase *R) { 754 return R->getVPRecipeID() == VPRecipeBase::VPInstructionSC; 755 } 756 757 unsigned getOpcode() const { return Opcode; } 758 759 /// Generate the instruction. 760 /// TODO: We currently execute only per-part unless a specific instance is 761 /// provided. 762 void execute(VPTransformState &State) override; 763 764 /// Print the Recipe. 765 void print(raw_ostream &O, const Twine &Indent, 766 VPSlotTracker &SlotTracker) const override; 767 768 /// Print the VPInstruction. 769 void print(raw_ostream &O) const; 770 void print(raw_ostream &O, VPSlotTracker &SlotTracker) const; 771 772 /// Return true if this instruction may modify memory. 773 bool mayWriteToMemory() const { 774 // TODO: we can use attributes of the called function to rule out memory 775 // modifications. 776 return Opcode == Instruction::Store || Opcode == Instruction::Call || 777 Opcode == Instruction::Invoke || Opcode == SLPStore; 778 } 779 780 bool hasResult() const { 781 // CallInst may or may not have a result, depending on the called function. 782 // Conservatively return calls have results for now. 783 switch (getOpcode()) { 784 case Instruction::Ret: 785 case Instruction::Br: 786 case Instruction::Store: 787 case Instruction::Switch: 788 case Instruction::IndirectBr: 789 case Instruction::Resume: 790 case Instruction::CatchRet: 791 case Instruction::Unreachable: 792 case Instruction::Fence: 793 case Instruction::AtomicRMW: 794 return false; 795 default: 796 return true; 797 } 798 } 799 }; 800 801 /// VPWidenRecipe is a recipe for producing a copy of vector type its 802 /// ingredient. This recipe covers most of the traditional vectorization cases 803 /// where each ingredient transforms into a vectorized version of itself. 804 class VPWidenRecipe : public VPRecipeBase, public VPUser { 805 /// Hold the instruction to be widened. 806 Instruction &Ingredient; 807 808 public: 809 template <typename IterT> 810 VPWidenRecipe(Instruction &I, iterator_range<IterT> Operands) 811 : VPRecipeBase(VPWidenSC), VPUser(Operands), Ingredient(I) {} 812 813 ~VPWidenRecipe() override = default; 814 815 /// Method to support type inquiry through isa, cast, and dyn_cast. 816 static inline bool classof(const VPRecipeBase *V) { 817 return V->getVPRecipeID() == VPRecipeBase::VPWidenSC; 818 } 819 820 /// Produce widened copies of all Ingredients. 821 void execute(VPTransformState &State) override; 822 823 /// Print the recipe. 824 void print(raw_ostream &O, const Twine &Indent, 825 VPSlotTracker &SlotTracker) const override; 826 }; 827 828 /// A recipe for widening Call instructions. 829 class VPWidenCallRecipe : public VPRecipeBase, public VPUser { 830 /// Hold the call to be widened. 831 CallInst &Ingredient; 832 833 public: 834 template <typename IterT> 835 VPWidenCallRecipe(CallInst &I, iterator_range<IterT> CallArguments) 836 : VPRecipeBase(VPWidenCallSC), VPUser(CallArguments), Ingredient(I) {} 837 838 ~VPWidenCallRecipe() override = default; 839 840 /// Method to support type inquiry through isa, cast, and dyn_cast. 841 static inline bool classof(const VPRecipeBase *V) { 842 return V->getVPRecipeID() == VPRecipeBase::VPWidenCallSC; 843 } 844 845 /// Produce a widened version of the call instruction. 846 void execute(VPTransformState &State) override; 847 848 /// Print the recipe. 849 void print(raw_ostream &O, const Twine &Indent, 850 VPSlotTracker &SlotTracker) const override; 851 }; 852 853 /// A recipe for widening select instructions. 854 class VPWidenSelectRecipe : public VPRecipeBase, public VPUser { 855 private: 856 /// Hold the select to be widened. 857 SelectInst &Ingredient; 858 859 /// Is the condition of the select loop invariant? 860 bool InvariantCond; 861 862 public: 863 template <typename IterT> 864 VPWidenSelectRecipe(SelectInst &I, iterator_range<IterT> Operands, 865 bool InvariantCond) 866 : VPRecipeBase(VPWidenSelectSC), VPUser(Operands), Ingredient(I), 867 InvariantCond(InvariantCond) {} 868 869 ~VPWidenSelectRecipe() override = default; 870 871 /// Method to support type inquiry through isa, cast, and dyn_cast. 872 static inline bool classof(const VPRecipeBase *V) { 873 return V->getVPRecipeID() == VPRecipeBase::VPWidenSelectSC; 874 } 875 876 /// Produce a widened version of the select instruction. 877 void execute(VPTransformState &State) override; 878 879 /// Print the recipe. 880 void print(raw_ostream &O, const Twine &Indent, 881 VPSlotTracker &SlotTracker) const override; 882 }; 883 884 /// A recipe for handling GEP instructions. 885 class VPWidenGEPRecipe : public VPRecipeBase, public VPUser { 886 GetElementPtrInst *GEP; 887 888 bool IsPtrLoopInvariant; 889 SmallBitVector IsIndexLoopInvariant; 890 891 public: 892 template <typename IterT> 893 VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands) 894 : VPRecipeBase(VPWidenGEPSC), VPUser(Operands), GEP(GEP), 895 IsIndexLoopInvariant(GEP->getNumIndices(), false) {} 896 897 template <typename IterT> 898 VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands, 899 Loop *OrigLoop) 900 : VPRecipeBase(VPWidenGEPSC), VPUser(Operands), GEP(GEP), 901 IsIndexLoopInvariant(GEP->getNumIndices(), false) { 902 IsPtrLoopInvariant = OrigLoop->isLoopInvariant(GEP->getPointerOperand()); 903 for (auto Index : enumerate(GEP->indices())) 904 IsIndexLoopInvariant[Index.index()] = 905 OrigLoop->isLoopInvariant(Index.value().get()); 906 } 907 ~VPWidenGEPRecipe() override = default; 908 909 /// Method to support type inquiry through isa, cast, and dyn_cast. 910 static inline bool classof(const VPRecipeBase *V) { 911 return V->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC; 912 } 913 914 /// Generate the gep nodes. 915 void execute(VPTransformState &State) override; 916 917 /// Print the recipe. 918 void print(raw_ostream &O, const Twine &Indent, 919 VPSlotTracker &SlotTracker) const override; 920 }; 921 922 /// A recipe for handling phi nodes of integer and floating-point inductions, 923 /// producing their vector and scalar values. 924 class VPWidenIntOrFpInductionRecipe : public VPRecipeBase { 925 PHINode *IV; 926 TruncInst *Trunc; 927 928 public: 929 VPWidenIntOrFpInductionRecipe(PHINode *IV, TruncInst *Trunc = nullptr) 930 : VPRecipeBase(VPWidenIntOrFpInductionSC), IV(IV), Trunc(Trunc) {} 931 ~VPWidenIntOrFpInductionRecipe() override = default; 932 933 /// Method to support type inquiry through isa, cast, and dyn_cast. 934 static inline bool classof(const VPRecipeBase *V) { 935 return V->getVPRecipeID() == VPRecipeBase::VPWidenIntOrFpInductionSC; 936 } 937 938 /// Generate the vectorized and scalarized versions of the phi node as 939 /// needed by their users. 940 void execute(VPTransformState &State) override; 941 942 /// Print the recipe. 943 void print(raw_ostream &O, const Twine &Indent, 944 VPSlotTracker &SlotTracker) const override; 945 }; 946 947 /// A recipe for handling all phi nodes except for integer and FP inductions. 948 class VPWidenPHIRecipe : public VPRecipeBase { 949 PHINode *Phi; 950 951 public: 952 VPWidenPHIRecipe(PHINode *Phi) : VPRecipeBase(VPWidenPHISC), Phi(Phi) {} 953 ~VPWidenPHIRecipe() override = default; 954 955 /// Method to support type inquiry through isa, cast, and dyn_cast. 956 static inline bool classof(const VPRecipeBase *V) { 957 return V->getVPRecipeID() == VPRecipeBase::VPWidenPHISC; 958 } 959 960 /// Generate the phi/select nodes. 961 void execute(VPTransformState &State) override; 962 963 /// Print the recipe. 964 void print(raw_ostream &O, const Twine &Indent, 965 VPSlotTracker &SlotTracker) const override; 966 }; 967 968 /// A recipe for vectorizing a phi-node as a sequence of mask-based select 969 /// instructions. 970 class VPBlendRecipe : public VPRecipeBase, public VPUser { 971 PHINode *Phi; 972 973 public: 974 /// The blend operation is a User of the incoming values and of their 975 /// respective masks, ordered [I0, M0, I1, M1, ...]. Note that a single value 976 /// might be incoming with a full mask for which there is no VPValue. 977 VPBlendRecipe(PHINode *Phi, ArrayRef<VPValue *> Operands) 978 : VPRecipeBase(VPBlendSC), VPUser(Operands), Phi(Phi) { 979 assert(Operands.size() > 0 && 980 ((Operands.size() == 1) || (Operands.size() % 2 == 0)) && 981 "Expected either a single incoming value or a positive even number " 982 "of operands"); 983 } 984 985 /// Method to support type inquiry through isa, cast, and dyn_cast. 986 static inline bool classof(const VPRecipeBase *V) { 987 return V->getVPRecipeID() == VPRecipeBase::VPBlendSC; 988 } 989 990 /// Return the number of incoming values, taking into account that a single 991 /// incoming value has no mask. 992 unsigned getNumIncomingValues() const { return (getNumOperands() + 1) / 2; } 993 994 /// Return incoming value number \p Idx. 995 VPValue *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); } 996 997 /// Return mask number \p Idx. 998 VPValue *getMask(unsigned Idx) const { return getOperand(Idx * 2 + 1); } 999 1000 /// Generate the phi/select nodes. 1001 void execute(VPTransformState &State) override; 1002 1003 /// Print the recipe. 1004 void print(raw_ostream &O, const Twine &Indent, 1005 VPSlotTracker &SlotTracker) const override; 1006 }; 1007 1008 /// VPInterleaveRecipe is a recipe for transforming an interleave group of load 1009 /// or stores into one wide load/store and shuffles. 1010 class VPInterleaveRecipe : public VPRecipeBase, public VPUser { 1011 const InterleaveGroup<Instruction> *IG; 1012 1013 public: 1014 VPInterleaveRecipe(const InterleaveGroup<Instruction> *IG, VPValue *Addr, 1015 VPValue *Mask) 1016 : VPRecipeBase(VPInterleaveSC), VPUser({Addr}), IG(IG) { 1017 if (Mask) 1018 addOperand(Mask); 1019 } 1020 ~VPInterleaveRecipe() override = default; 1021 1022 /// Method to support type inquiry through isa, cast, and dyn_cast. 1023 static inline bool classof(const VPRecipeBase *V) { 1024 return V->getVPRecipeID() == VPRecipeBase::VPInterleaveSC; 1025 } 1026 1027 /// Return the address accessed by this recipe. 1028 VPValue *getAddr() const { 1029 return getOperand(0); // Address is the 1st, mandatory operand. 1030 } 1031 1032 /// Return the mask used by this recipe. Note that a full mask is represented 1033 /// by a nullptr. 1034 VPValue *getMask() const { 1035 // Mask is optional and therefore the last, currently 2nd operand. 1036 return getNumOperands() == 2 ? getOperand(1) : nullptr; 1037 } 1038 1039 /// Generate the wide load or store, and shuffles. 1040 void execute(VPTransformState &State) override; 1041 1042 /// Print the recipe. 1043 void print(raw_ostream &O, const Twine &Indent, 1044 VPSlotTracker &SlotTracker) const override; 1045 1046 const InterleaveGroup<Instruction> *getInterleaveGroup() { return IG; } 1047 }; 1048 1049 /// A recipe to represent inloop reduction operations, performing a reduction on 1050 /// a vector operand into a scalar value, and adding the result to a chain. 1051 class VPReductionRecipe : public VPRecipeBase { 1052 /// The recurrence decriptor for the reduction in question. 1053 RecurrenceDescriptor *RdxDesc; 1054 /// The original instruction being converted to a reduction. 1055 Instruction *I; 1056 /// The VPValue of the vector value to be reduced. 1057 VPValue *VecOp; 1058 /// The VPValue of the scalar Chain being accumulated. 1059 VPValue *ChainOp; 1060 /// Fast math flags to use for the resulting reduction operation. 1061 bool NoNaN; 1062 /// Pointer to the TTI, needed to create the target reduction 1063 const TargetTransformInfo *TTI; 1064 1065 public: 1066 VPReductionRecipe(RecurrenceDescriptor *R, Instruction *I, VPValue *ChainOp, 1067 VPValue *VecOp, bool NoNaN, const TargetTransformInfo *TTI) 1068 : VPRecipeBase(VPReductionSC), RdxDesc(R), I(I), VecOp(VecOp), 1069 ChainOp(ChainOp), NoNaN(NoNaN), TTI(TTI) {} 1070 1071 ~VPReductionRecipe() override = default; 1072 1073 /// Method to support type inquiry through isa, cast, and dyn_cast. 1074 static inline bool classof(const VPRecipeBase *V) { 1075 return V->getVPRecipeID() == VPRecipeBase::VPReductionSC; 1076 } 1077 1078 /// Generate the reduction in the loop 1079 void execute(VPTransformState &State) override; 1080 1081 /// Print the recipe. 1082 void print(raw_ostream &O, const Twine &Indent, 1083 VPSlotTracker &SlotTracker) const override; 1084 }; 1085 1086 /// VPReplicateRecipe replicates a given instruction producing multiple scalar 1087 /// copies of the original scalar type, one per lane, instead of producing a 1088 /// single copy of widened type for all lanes. If the instruction is known to be 1089 /// uniform only one copy, per lane zero, will be generated. 1090 class VPReplicateRecipe : public VPRecipeBase, public VPUser { 1091 /// The instruction being replicated. 1092 Instruction *Ingredient; 1093 1094 /// Indicator if only a single replica per lane is needed. 1095 bool IsUniform; 1096 1097 /// Indicator if the replicas are also predicated. 1098 bool IsPredicated; 1099 1100 /// Indicator if the scalar values should also be packed into a vector. 1101 bool AlsoPack; 1102 1103 public: 1104 template <typename IterT> 1105 VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands, 1106 bool IsUniform, bool IsPredicated = false) 1107 : VPRecipeBase(VPReplicateSC), VPUser(Operands), Ingredient(I), 1108 IsUniform(IsUniform), IsPredicated(IsPredicated) { 1109 // Retain the previous behavior of predicateInstructions(), where an 1110 // insert-element of a predicated instruction got hoisted into the 1111 // predicated basic block iff it was its only user. This is achieved by 1112 // having predicated instructions also pack their values into a vector by 1113 // default unless they have a replicated user which uses their scalar value. 1114 AlsoPack = IsPredicated && !I->use_empty(); 1115 } 1116 1117 ~VPReplicateRecipe() override = default; 1118 1119 /// Method to support type inquiry through isa, cast, and dyn_cast. 1120 static inline bool classof(const VPRecipeBase *V) { 1121 return V->getVPRecipeID() == VPRecipeBase::VPReplicateSC; 1122 } 1123 1124 /// Generate replicas of the desired Ingredient. Replicas will be generated 1125 /// for all parts and lanes unless a specific part and lane are specified in 1126 /// the \p State. 1127 void execute(VPTransformState &State) override; 1128 1129 void setAlsoPack(bool Pack) { AlsoPack = Pack; } 1130 1131 /// Print the recipe. 1132 void print(raw_ostream &O, const Twine &Indent, 1133 VPSlotTracker &SlotTracker) const override; 1134 }; 1135 1136 /// A recipe for generating conditional branches on the bits of a mask. 1137 class VPBranchOnMaskRecipe : public VPRecipeBase, public VPUser { 1138 public: 1139 VPBranchOnMaskRecipe(VPValue *BlockInMask) : VPRecipeBase(VPBranchOnMaskSC) { 1140 if (BlockInMask) // nullptr means all-one mask. 1141 addOperand(BlockInMask); 1142 } 1143 1144 /// Method to support type inquiry through isa, cast, and dyn_cast. 1145 static inline bool classof(const VPRecipeBase *V) { 1146 return V->getVPRecipeID() == VPRecipeBase::VPBranchOnMaskSC; 1147 } 1148 1149 /// Generate the extraction of the appropriate bit from the block mask and the 1150 /// conditional branch. 1151 void execute(VPTransformState &State) override; 1152 1153 /// Print the recipe. 1154 void print(raw_ostream &O, const Twine &Indent, 1155 VPSlotTracker &SlotTracker) const override { 1156 O << " +\n" << Indent << "\"BRANCH-ON-MASK "; 1157 if (VPValue *Mask = getMask()) 1158 Mask->print(O, SlotTracker); 1159 else 1160 O << " All-One"; 1161 O << "\\l\""; 1162 } 1163 1164 /// Return the mask used by this recipe. Note that a full mask is represented 1165 /// by a nullptr. 1166 VPValue *getMask() const { 1167 assert(getNumOperands() <= 1 && "should have either 0 or 1 operands"); 1168 // Mask is optional. 1169 return getNumOperands() == 1 ? getOperand(0) : nullptr; 1170 } 1171 }; 1172 1173 /// VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when 1174 /// control converges back from a Branch-on-Mask. The phi nodes are needed in 1175 /// order to merge values that are set under such a branch and feed their uses. 1176 /// The phi nodes can be scalar or vector depending on the users of the value. 1177 /// This recipe works in concert with VPBranchOnMaskRecipe. 1178 class VPPredInstPHIRecipe : public VPRecipeBase { 1179 Instruction *PredInst; 1180 1181 public: 1182 /// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi 1183 /// nodes after merging back from a Branch-on-Mask. 1184 VPPredInstPHIRecipe(Instruction *PredInst) 1185 : VPRecipeBase(VPPredInstPHISC), PredInst(PredInst) {} 1186 ~VPPredInstPHIRecipe() override = default; 1187 1188 /// Method to support type inquiry through isa, cast, and dyn_cast. 1189 static inline bool classof(const VPRecipeBase *V) { 1190 return V->getVPRecipeID() == VPRecipeBase::VPPredInstPHISC; 1191 } 1192 1193 /// Generates phi nodes for live-outs as needed to retain SSA form. 1194 void execute(VPTransformState &State) override; 1195 1196 /// Print the recipe. 1197 void print(raw_ostream &O, const Twine &Indent, 1198 VPSlotTracker &SlotTracker) const override; 1199 }; 1200 1201 /// A Recipe for widening load/store operations. 1202 /// The recipe uses the following VPValues: 1203 /// - For load: Address, optional mask 1204 /// - For store: Address, stored value, optional mask 1205 /// TODO: We currently execute only per-part unless a specific instance is 1206 /// provided. 1207 class VPWidenMemoryInstructionRecipe : public VPRecipeBase, public VPUser { 1208 Instruction &Instr; 1209 1210 void setMask(VPValue *Mask) { 1211 if (!Mask) 1212 return; 1213 addOperand(Mask); 1214 } 1215 1216 bool isMasked() const { 1217 return (isa<LoadInst>(Instr) && getNumOperands() == 2) || 1218 (isa<StoreInst>(Instr) && getNumOperands() == 3); 1219 } 1220 1221 public: 1222 VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask) 1223 : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr}), Instr(Load) { 1224 setMask(Mask); 1225 } 1226 1227 VPWidenMemoryInstructionRecipe(StoreInst &Store, VPValue *Addr, 1228 VPValue *StoredValue, VPValue *Mask) 1229 : VPRecipeBase(VPWidenMemoryInstructionSC), VPUser({Addr, StoredValue}), 1230 Instr(Store) { 1231 setMask(Mask); 1232 } 1233 1234 /// Method to support type inquiry through isa, cast, and dyn_cast. 1235 static inline bool classof(const VPRecipeBase *V) { 1236 return V->getVPRecipeID() == VPRecipeBase::VPWidenMemoryInstructionSC; 1237 } 1238 1239 /// Return the address accessed by this recipe. 1240 VPValue *getAddr() const { 1241 return getOperand(0); // Address is the 1st, mandatory operand. 1242 } 1243 1244 /// Return the mask used by this recipe. Note that a full mask is represented 1245 /// by a nullptr. 1246 VPValue *getMask() const { 1247 // Mask is optional and therefore the last operand. 1248 return isMasked() ? getOperand(getNumOperands() - 1) : nullptr; 1249 } 1250 1251 /// Return the address accessed by this recipe. 1252 VPValue *getStoredValue() const { 1253 assert(isa<StoreInst>(Instr) && 1254 "Stored value only available for store instructions"); 1255 return getOperand(1); // Stored value is the 2nd, mandatory operand. 1256 } 1257 1258 /// Generate the wide load/store. 1259 void execute(VPTransformState &State) override; 1260 1261 /// Print the recipe. 1262 void print(raw_ostream &O, const Twine &Indent, 1263 VPSlotTracker &SlotTracker) const override; 1264 }; 1265 1266 /// A Recipe for widening the canonical induction variable of the vector loop. 1267 class VPWidenCanonicalIVRecipe : public VPRecipeBase { 1268 /// A VPValue representing the canonical vector IV. 1269 VPValue Val; 1270 1271 public: 1272 VPWidenCanonicalIVRecipe() : VPRecipeBase(VPWidenCanonicalIVSC) {} 1273 ~VPWidenCanonicalIVRecipe() override = default; 1274 1275 /// Return the VPValue representing the canonical vector induction variable of 1276 /// the vector loop. 1277 const VPValue *getVPValue() const { return &Val; } 1278 VPValue *getVPValue() { return &Val; } 1279 1280 /// Method to support type inquiry through isa, cast, and dyn_cast. 1281 static inline bool classof(const VPRecipeBase *V) { 1282 return V->getVPRecipeID() == VPRecipeBase::VPWidenCanonicalIVSC; 1283 } 1284 1285 /// Generate a canonical vector induction variable of the vector loop, with 1286 /// start = {<Part*VF, Part*VF+1, ..., Part*VF+VF-1> for 0 <= Part < UF}, and 1287 /// step = <VF*UF, VF*UF, ..., VF*UF>. 1288 void execute(VPTransformState &State) override; 1289 1290 /// Print the recipe. 1291 void print(raw_ostream &O, const Twine &Indent, 1292 VPSlotTracker &SlotTracker) const override; 1293 }; 1294 1295 /// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It 1296 /// holds a sequence of zero or more VPRecipe's each representing a sequence of 1297 /// output IR instructions. 1298 class VPBasicBlock : public VPBlockBase { 1299 public: 1300 using RecipeListTy = iplist<VPRecipeBase>; 1301 1302 private: 1303 /// The VPRecipes held in the order of output instructions to generate. 1304 RecipeListTy Recipes; 1305 1306 public: 1307 VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr) 1308 : VPBlockBase(VPBasicBlockSC, Name.str()) { 1309 if (Recipe) 1310 appendRecipe(Recipe); 1311 } 1312 1313 ~VPBasicBlock() override { Recipes.clear(); } 1314 1315 /// Instruction iterators... 1316 using iterator = RecipeListTy::iterator; 1317 using const_iterator = RecipeListTy::const_iterator; 1318 using reverse_iterator = RecipeListTy::reverse_iterator; 1319 using const_reverse_iterator = RecipeListTy::const_reverse_iterator; 1320 1321 //===--------------------------------------------------------------------===// 1322 /// Recipe iterator methods 1323 /// 1324 inline iterator begin() { return Recipes.begin(); } 1325 inline const_iterator begin() const { return Recipes.begin(); } 1326 inline iterator end() { return Recipes.end(); } 1327 inline const_iterator end() const { return Recipes.end(); } 1328 1329 inline reverse_iterator rbegin() { return Recipes.rbegin(); } 1330 inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); } 1331 inline reverse_iterator rend() { return Recipes.rend(); } 1332 inline const_reverse_iterator rend() const { return Recipes.rend(); } 1333 1334 inline size_t size() const { return Recipes.size(); } 1335 inline bool empty() const { return Recipes.empty(); } 1336 inline const VPRecipeBase &front() const { return Recipes.front(); } 1337 inline VPRecipeBase &front() { return Recipes.front(); } 1338 inline const VPRecipeBase &back() const { return Recipes.back(); } 1339 inline VPRecipeBase &back() { return Recipes.back(); } 1340 1341 /// Returns a reference to the list of recipes. 1342 RecipeListTy &getRecipeList() { return Recipes; } 1343 1344 /// Returns a pointer to a member of the recipe list. 1345 static RecipeListTy VPBasicBlock::*getSublistAccess(VPRecipeBase *) { 1346 return &VPBasicBlock::Recipes; 1347 } 1348 1349 /// Method to support type inquiry through isa, cast, and dyn_cast. 1350 static inline bool classof(const VPBlockBase *V) { 1351 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC; 1352 } 1353 1354 void insert(VPRecipeBase *Recipe, iterator InsertPt) { 1355 assert(Recipe && "No recipe to append."); 1356 assert(!Recipe->Parent && "Recipe already in VPlan"); 1357 Recipe->Parent = this; 1358 Recipes.insert(InsertPt, Recipe); 1359 } 1360 1361 /// Augment the existing recipes of a VPBasicBlock with an additional 1362 /// \p Recipe as the last recipe. 1363 void appendRecipe(VPRecipeBase *Recipe) { insert(Recipe, end()); } 1364 1365 /// The method which generates the output IR instructions that correspond to 1366 /// this VPBasicBlock, thereby "executing" the VPlan. 1367 void execute(struct VPTransformState *State) override; 1368 1369 /// Replace all operands of VPUsers in the block with \p NewValue and also 1370 /// replaces all uses of VPValues defined in the block with NewValue. 1371 void dropAllReferences(VPValue *NewValue); 1372 1373 private: 1374 /// Create an IR BasicBlock to hold the output instructions generated by this 1375 /// VPBasicBlock, and return it. Update the CFGState accordingly. 1376 BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG); 1377 }; 1378 1379 /// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks 1380 /// which form a Single-Entry-Single-Exit subgraph of the output IR CFG. 1381 /// A VPRegionBlock may indicate that its contents are to be replicated several 1382 /// times. This is designed to support predicated scalarization, in which a 1383 /// scalar if-then code structure needs to be generated VF * UF times. Having 1384 /// this replication indicator helps to keep a single model for multiple 1385 /// candidate VF's. The actual replication takes place only once the desired VF 1386 /// and UF have been determined. 1387 class VPRegionBlock : public VPBlockBase { 1388 /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock. 1389 VPBlockBase *Entry; 1390 1391 /// Hold the Single Exit of the SESE region modelled by the VPRegionBlock. 1392 VPBlockBase *Exit; 1393 1394 /// An indicator whether this region is to generate multiple replicated 1395 /// instances of output IR corresponding to its VPBlockBases. 1396 bool IsReplicator; 1397 1398 public: 1399 VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exit, 1400 const std::string &Name = "", bool IsReplicator = false) 1401 : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exit(Exit), 1402 IsReplicator(IsReplicator) { 1403 assert(Entry->getPredecessors().empty() && "Entry block has predecessors."); 1404 assert(Exit->getSuccessors().empty() && "Exit block has successors."); 1405 Entry->setParent(this); 1406 Exit->setParent(this); 1407 } 1408 VPRegionBlock(const std::string &Name = "", bool IsReplicator = false) 1409 : VPBlockBase(VPRegionBlockSC, Name), Entry(nullptr), Exit(nullptr), 1410 IsReplicator(IsReplicator) {} 1411 1412 ~VPRegionBlock() override { 1413 if (Entry) 1414 deleteCFG(Entry); 1415 } 1416 1417 /// Method to support type inquiry through isa, cast, and dyn_cast. 1418 static inline bool classof(const VPBlockBase *V) { 1419 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC; 1420 } 1421 1422 const VPBlockBase *getEntry() const { return Entry; } 1423 VPBlockBase *getEntry() { return Entry; } 1424 1425 /// Set \p EntryBlock as the entry VPBlockBase of this VPRegionBlock. \p 1426 /// EntryBlock must have no predecessors. 1427 void setEntry(VPBlockBase *EntryBlock) { 1428 assert(EntryBlock->getPredecessors().empty() && 1429 "Entry block cannot have predecessors."); 1430 Entry = EntryBlock; 1431 EntryBlock->setParent(this); 1432 } 1433 1434 // FIXME: DominatorTreeBase is doing 'A->getParent()->front()'. 'front' is a 1435 // specific interface of llvm::Function, instead of using 1436 // GraphTraints::getEntryNode. We should add a new template parameter to 1437 // DominatorTreeBase representing the Graph type. 1438 VPBlockBase &front() const { return *Entry; } 1439 1440 const VPBlockBase *getExit() const { return Exit; } 1441 VPBlockBase *getExit() { return Exit; } 1442 1443 /// Set \p ExitBlock as the exit VPBlockBase of this VPRegionBlock. \p 1444 /// ExitBlock must have no successors. 1445 void setExit(VPBlockBase *ExitBlock) { 1446 assert(ExitBlock->getSuccessors().empty() && 1447 "Exit block cannot have successors."); 1448 Exit = ExitBlock; 1449 ExitBlock->setParent(this); 1450 } 1451 1452 /// An indicator whether this region is to generate multiple replicated 1453 /// instances of output IR corresponding to its VPBlockBases. 1454 bool isReplicator() const { return IsReplicator; } 1455 1456 /// The method which generates the output IR instructions that correspond to 1457 /// this VPRegionBlock, thereby "executing" the VPlan. 1458 void execute(struct VPTransformState *State) override; 1459 }; 1460 1461 //===----------------------------------------------------------------------===// 1462 // GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs // 1463 //===----------------------------------------------------------------------===// 1464 1465 // The following set of template specializations implement GraphTraits to treat 1466 // any VPBlockBase as a node in a graph of VPBlockBases. It's important to note 1467 // that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the 1468 // VPBlockBase is a VPRegionBlock, this specialization provides access to its 1469 // successors/predecessors but not to the blocks inside the region. 1470 1471 template <> struct GraphTraits<VPBlockBase *> { 1472 using NodeRef = VPBlockBase *; 1473 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; 1474 1475 static NodeRef getEntryNode(NodeRef N) { return N; } 1476 1477 static inline ChildIteratorType child_begin(NodeRef N) { 1478 return N->getSuccessors().begin(); 1479 } 1480 1481 static inline ChildIteratorType child_end(NodeRef N) { 1482 return N->getSuccessors().end(); 1483 } 1484 }; 1485 1486 template <> struct GraphTraits<const VPBlockBase *> { 1487 using NodeRef = const VPBlockBase *; 1488 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::const_iterator; 1489 1490 static NodeRef getEntryNode(NodeRef N) { return N; } 1491 1492 static inline ChildIteratorType child_begin(NodeRef N) { 1493 return N->getSuccessors().begin(); 1494 } 1495 1496 static inline ChildIteratorType child_end(NodeRef N) { 1497 return N->getSuccessors().end(); 1498 } 1499 }; 1500 1501 // Inverse order specialization for VPBasicBlocks. Predecessors are used instead 1502 // of successors for the inverse traversal. 1503 template <> struct GraphTraits<Inverse<VPBlockBase *>> { 1504 using NodeRef = VPBlockBase *; 1505 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; 1506 1507 static NodeRef getEntryNode(Inverse<NodeRef> B) { return B.Graph; } 1508 1509 static inline ChildIteratorType child_begin(NodeRef N) { 1510 return N->getPredecessors().begin(); 1511 } 1512 1513 static inline ChildIteratorType child_end(NodeRef N) { 1514 return N->getPredecessors().end(); 1515 } 1516 }; 1517 1518 // The following set of template specializations implement GraphTraits to 1519 // treat VPRegionBlock as a graph and recurse inside its nodes. It's important 1520 // to note that the blocks inside the VPRegionBlock are treated as VPBlockBases 1521 // (i.e., no dyn_cast is performed, VPBlockBases specialization is used), so 1522 // there won't be automatic recursion into other VPBlockBases that turn to be 1523 // VPRegionBlocks. 1524 1525 template <> 1526 struct GraphTraits<VPRegionBlock *> : public GraphTraits<VPBlockBase *> { 1527 using GraphRef = VPRegionBlock *; 1528 using nodes_iterator = df_iterator<NodeRef>; 1529 1530 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } 1531 1532 static nodes_iterator nodes_begin(GraphRef N) { 1533 return nodes_iterator::begin(N->getEntry()); 1534 } 1535 1536 static nodes_iterator nodes_end(GraphRef N) { 1537 // df_iterator::end() returns an empty iterator so the node used doesn't 1538 // matter. 1539 return nodes_iterator::end(N); 1540 } 1541 }; 1542 1543 template <> 1544 struct GraphTraits<const VPRegionBlock *> 1545 : public GraphTraits<const VPBlockBase *> { 1546 using GraphRef = const VPRegionBlock *; 1547 using nodes_iterator = df_iterator<NodeRef>; 1548 1549 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } 1550 1551 static nodes_iterator nodes_begin(GraphRef N) { 1552 return nodes_iterator::begin(N->getEntry()); 1553 } 1554 1555 static nodes_iterator nodes_end(GraphRef N) { 1556 // df_iterator::end() returns an empty iterator so the node used doesn't 1557 // matter. 1558 return nodes_iterator::end(N); 1559 } 1560 }; 1561 1562 template <> 1563 struct GraphTraits<Inverse<VPRegionBlock *>> 1564 : public GraphTraits<Inverse<VPBlockBase *>> { 1565 using GraphRef = VPRegionBlock *; 1566 using nodes_iterator = df_iterator<NodeRef>; 1567 1568 static NodeRef getEntryNode(Inverse<GraphRef> N) { 1569 return N.Graph->getExit(); 1570 } 1571 1572 static nodes_iterator nodes_begin(GraphRef N) { 1573 return nodes_iterator::begin(N->getExit()); 1574 } 1575 1576 static nodes_iterator nodes_end(GraphRef N) { 1577 // df_iterator::end() returns an empty iterator so the node used doesn't 1578 // matter. 1579 return nodes_iterator::end(N); 1580 } 1581 }; 1582 1583 /// VPlan models a candidate for vectorization, encoding various decisions take 1584 /// to produce efficient output IR, including which branches, basic-blocks and 1585 /// output IR instructions to generate, and their cost. VPlan holds a 1586 /// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry 1587 /// VPBlock. 1588 class VPlan { 1589 friend class VPlanPrinter; 1590 friend class VPSlotTracker; 1591 1592 /// Hold the single entry to the Hierarchical CFG of the VPlan. 1593 VPBlockBase *Entry; 1594 1595 /// Holds the VFs applicable to this VPlan. 1596 SmallSetVector<ElementCount, 2> VFs; 1597 1598 /// Holds the name of the VPlan, for printing. 1599 std::string Name; 1600 1601 /// Holds all the external definitions created for this VPlan. 1602 // TODO: Introduce a specific representation for external definitions in 1603 // VPlan. External definitions must be immutable and hold a pointer to its 1604 // underlying IR that will be used to implement its structural comparison 1605 // (operators '==' and '<'). 1606 SmallPtrSet<VPValue *, 16> VPExternalDefs; 1607 1608 /// Represents the backedge taken count of the original loop, for folding 1609 /// the tail. 1610 VPValue *BackedgeTakenCount = nullptr; 1611 1612 /// Holds a mapping between Values and their corresponding VPValue inside 1613 /// VPlan. 1614 Value2VPValueTy Value2VPValue; 1615 1616 /// Holds the VPLoopInfo analysis for this VPlan. 1617 VPLoopInfo VPLInfo; 1618 1619 /// Holds the condition bit values built during VPInstruction to VPRecipe transformation. 1620 SmallVector<VPValue *, 4> VPCBVs; 1621 1622 public: 1623 VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) { 1624 if (Entry) 1625 Entry->setPlan(this); 1626 } 1627 1628 ~VPlan() { 1629 if (Entry) 1630 VPBlockBase::deleteCFG(Entry); 1631 for (auto &MapEntry : Value2VPValue) 1632 delete MapEntry.second; 1633 if (BackedgeTakenCount) 1634 delete BackedgeTakenCount; 1635 for (VPValue *Def : VPExternalDefs) 1636 delete Def; 1637 for (VPValue *CBV : VPCBVs) 1638 delete CBV; 1639 } 1640 1641 /// Generate the IR code for this VPlan. 1642 void execute(struct VPTransformState *State); 1643 1644 VPBlockBase *getEntry() { return Entry; } 1645 const VPBlockBase *getEntry() const { return Entry; } 1646 1647 VPBlockBase *setEntry(VPBlockBase *Block) { 1648 Entry = Block; 1649 Block->setPlan(this); 1650 return Entry; 1651 } 1652 1653 /// The backedge taken count of the original loop. 1654 VPValue *getOrCreateBackedgeTakenCount() { 1655 if (!BackedgeTakenCount) 1656 BackedgeTakenCount = new VPValue(); 1657 return BackedgeTakenCount; 1658 } 1659 1660 void addVF(ElementCount VF) { VFs.insert(VF); } 1661 1662 bool hasVF(ElementCount VF) { return VFs.count(VF); } 1663 1664 const std::string &getName() const { return Name; } 1665 1666 void setName(const Twine &newName) { Name = newName.str(); } 1667 1668 /// Add \p VPVal to the pool of external definitions if it's not already 1669 /// in the pool. 1670 void addExternalDef(VPValue *VPVal) { 1671 VPExternalDefs.insert(VPVal); 1672 } 1673 1674 /// Add \p CBV to the vector of condition bit values. 1675 void addCBV(VPValue *CBV) { 1676 VPCBVs.push_back(CBV); 1677 } 1678 1679 void addVPValue(Value *V) { 1680 assert(V && "Trying to add a null Value to VPlan"); 1681 assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); 1682 Value2VPValue[V] = new VPValue(V); 1683 } 1684 1685 VPValue *getVPValue(Value *V) { 1686 assert(V && "Trying to get the VPValue of a null Value"); 1687 assert(Value2VPValue.count(V) && "Value does not exist in VPlan"); 1688 return Value2VPValue[V]; 1689 } 1690 1691 VPValue *getOrAddVPValue(Value *V) { 1692 assert(V && "Trying to get or add the VPValue of a null Value"); 1693 if (!Value2VPValue.count(V)) 1694 addVPValue(V); 1695 return getVPValue(V); 1696 } 1697 1698 /// Return the VPLoopInfo analysis for this VPlan. 1699 VPLoopInfo &getVPLoopInfo() { return VPLInfo; } 1700 const VPLoopInfo &getVPLoopInfo() const { return VPLInfo; } 1701 1702 /// Dump the plan to stderr (for debugging). 1703 void dump() const; 1704 1705 /// Returns a range mapping the values the range \p Operands to their 1706 /// corresponding VPValues. 1707 iterator_range<mapped_iterator<Use *, std::function<VPValue *(Value *)>>> 1708 mapToVPValues(User::op_range Operands) { 1709 std::function<VPValue *(Value *)> Fn = [this](Value *Op) { 1710 return getOrAddVPValue(Op); 1711 }; 1712 return map_range(Operands, Fn); 1713 } 1714 1715 private: 1716 /// Add to the given dominator tree the header block and every new basic block 1717 /// that was created between it and the latch block, inclusive. 1718 static void updateDominatorTree(DominatorTree *DT, BasicBlock *LoopLatchBB, 1719 BasicBlock *LoopPreHeaderBB, 1720 BasicBlock *LoopExitBB); 1721 }; 1722 1723 /// VPlanPrinter prints a given VPlan to a given output stream. The printing is 1724 /// indented and follows the dot format. 1725 class VPlanPrinter { 1726 friend inline raw_ostream &operator<<(raw_ostream &OS, const VPlan &Plan); 1727 friend inline raw_ostream &operator<<(raw_ostream &OS, 1728 const struct VPlanIngredient &I); 1729 1730 private: 1731 raw_ostream &OS; 1732 const VPlan &Plan; 1733 unsigned Depth = 0; 1734 unsigned TabWidth = 2; 1735 std::string Indent; 1736 unsigned BID = 0; 1737 SmallDenseMap<const VPBlockBase *, unsigned> BlockID; 1738 1739 VPSlotTracker SlotTracker; 1740 1741 VPlanPrinter(raw_ostream &O, const VPlan &P) 1742 : OS(O), Plan(P), SlotTracker(&P) {} 1743 1744 /// Handle indentation. 1745 void bumpIndent(int b) { Indent = std::string((Depth += b) * TabWidth, ' '); } 1746 1747 /// Print a given \p Block of the Plan. 1748 void dumpBlock(const VPBlockBase *Block); 1749 1750 /// Print the information related to the CFG edges going out of a given 1751 /// \p Block, followed by printing the successor blocks themselves. 1752 void dumpEdges(const VPBlockBase *Block); 1753 1754 /// Print a given \p BasicBlock, including its VPRecipes, followed by printing 1755 /// its successor blocks. 1756 void dumpBasicBlock(const VPBasicBlock *BasicBlock); 1757 1758 /// Print a given \p Region of the Plan. 1759 void dumpRegion(const VPRegionBlock *Region); 1760 1761 unsigned getOrCreateBID(const VPBlockBase *Block) { 1762 return BlockID.count(Block) ? BlockID[Block] : BlockID[Block] = BID++; 1763 } 1764 1765 const Twine getOrCreateName(const VPBlockBase *Block); 1766 1767 const Twine getUID(const VPBlockBase *Block); 1768 1769 /// Print the information related to a CFG edge between two VPBlockBases. 1770 void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden, 1771 const Twine &Label); 1772 1773 void dump(); 1774 1775 static void printAsIngredient(raw_ostream &O, Value *V); 1776 }; 1777 1778 struct VPlanIngredient { 1779 Value *V; 1780 1781 VPlanIngredient(Value *V) : V(V) {} 1782 }; 1783 1784 inline raw_ostream &operator<<(raw_ostream &OS, const VPlanIngredient &I) { 1785 VPlanPrinter::printAsIngredient(OS, I.V); 1786 return OS; 1787 } 1788 1789 inline raw_ostream &operator<<(raw_ostream &OS, const VPlan &Plan) { 1790 VPlanPrinter Printer(OS, Plan); 1791 Printer.dump(); 1792 return OS; 1793 } 1794 1795 //===----------------------------------------------------------------------===// 1796 // VPlan Utilities 1797 //===----------------------------------------------------------------------===// 1798 1799 /// Class that provides utilities for VPBlockBases in VPlan. 1800 class VPBlockUtils { 1801 public: 1802 VPBlockUtils() = delete; 1803 1804 /// Insert disconnected VPBlockBase \p NewBlock after \p BlockPtr. Add \p 1805 /// NewBlock as successor of \p BlockPtr and \p BlockPtr as predecessor of \p 1806 /// NewBlock, and propagate \p BlockPtr parent to \p NewBlock. If \p BlockPtr 1807 /// has more than one successor, its conditional bit is propagated to \p 1808 /// NewBlock. \p NewBlock must have neither successors nor predecessors. 1809 static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) { 1810 assert(NewBlock->getSuccessors().empty() && 1811 "Can't insert new block with successors."); 1812 // TODO: move successors from BlockPtr to NewBlock when this functionality 1813 // is necessary. For now, setBlockSingleSuccessor will assert if BlockPtr 1814 // already has successors. 1815 BlockPtr->setOneSuccessor(NewBlock); 1816 NewBlock->setPredecessors({BlockPtr}); 1817 NewBlock->setParent(BlockPtr->getParent()); 1818 } 1819 1820 /// Insert disconnected VPBlockBases \p IfTrue and \p IfFalse after \p 1821 /// BlockPtr. Add \p IfTrue and \p IfFalse as succesors of \p BlockPtr and \p 1822 /// BlockPtr as predecessor of \p IfTrue and \p IfFalse. Propagate \p BlockPtr 1823 /// parent to \p IfTrue and \p IfFalse. \p Condition is set as the successor 1824 /// selector. \p BlockPtr must have no successors and \p IfTrue and \p IfFalse 1825 /// must have neither successors nor predecessors. 1826 static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse, 1827 VPValue *Condition, VPBlockBase *BlockPtr) { 1828 assert(IfTrue->getSuccessors().empty() && 1829 "Can't insert IfTrue with successors."); 1830 assert(IfFalse->getSuccessors().empty() && 1831 "Can't insert IfFalse with successors."); 1832 BlockPtr->setTwoSuccessors(IfTrue, IfFalse, Condition); 1833 IfTrue->setPredecessors({BlockPtr}); 1834 IfFalse->setPredecessors({BlockPtr}); 1835 IfTrue->setParent(BlockPtr->getParent()); 1836 IfFalse->setParent(BlockPtr->getParent()); 1837 } 1838 1839 /// Connect VPBlockBases \p From and \p To bi-directionally. Append \p To to 1840 /// the successors of \p From and \p From to the predecessors of \p To. Both 1841 /// VPBlockBases must have the same parent, which can be null. Both 1842 /// VPBlockBases can be already connected to other VPBlockBases. 1843 static void connectBlocks(VPBlockBase *From, VPBlockBase *To) { 1844 assert((From->getParent() == To->getParent()) && 1845 "Can't connect two block with different parents"); 1846 assert(From->getNumSuccessors() < 2 && 1847 "Blocks can't have more than two successors."); 1848 From->appendSuccessor(To); 1849 To->appendPredecessor(From); 1850 } 1851 1852 /// Disconnect VPBlockBases \p From and \p To bi-directionally. Remove \p To 1853 /// from the successors of \p From and \p From from the predecessors of \p To. 1854 static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To) { 1855 assert(To && "Successor to disconnect is null."); 1856 From->removeSuccessor(To); 1857 To->removePredecessor(From); 1858 } 1859 1860 /// Returns true if the edge \p FromBlock -> \p ToBlock is a back-edge. 1861 static bool isBackEdge(const VPBlockBase *FromBlock, 1862 const VPBlockBase *ToBlock, const VPLoopInfo *VPLI) { 1863 assert(FromBlock->getParent() == ToBlock->getParent() && 1864 FromBlock->getParent() && "Must be in same region"); 1865 const VPLoop *FromLoop = VPLI->getLoopFor(FromBlock); 1866 const VPLoop *ToLoop = VPLI->getLoopFor(ToBlock); 1867 if (!FromLoop || !ToLoop || FromLoop != ToLoop) 1868 return false; 1869 1870 // A back-edge is a branch from the loop latch to its header. 1871 return ToLoop->isLoopLatch(FromBlock) && ToBlock == ToLoop->getHeader(); 1872 } 1873 1874 /// Returns true if \p Block is a loop latch 1875 static bool blockIsLoopLatch(const VPBlockBase *Block, 1876 const VPLoopInfo *VPLInfo) { 1877 if (const VPLoop *ParentVPL = VPLInfo->getLoopFor(Block)) 1878 return ParentVPL->isLoopLatch(Block); 1879 1880 return false; 1881 } 1882 1883 /// Count and return the number of succesors of \p PredBlock excluding any 1884 /// backedges. 1885 static unsigned countSuccessorsNoBE(VPBlockBase *PredBlock, 1886 VPLoopInfo *VPLI) { 1887 unsigned Count = 0; 1888 for (VPBlockBase *SuccBlock : PredBlock->getSuccessors()) { 1889 if (!VPBlockUtils::isBackEdge(PredBlock, SuccBlock, VPLI)) 1890 Count++; 1891 } 1892 return Count; 1893 } 1894 }; 1895 1896 class VPInterleavedAccessInfo { 1897 DenseMap<VPInstruction *, InterleaveGroup<VPInstruction> *> 1898 InterleaveGroupMap; 1899 1900 /// Type for mapping of instruction based interleave groups to VPInstruction 1901 /// interleave groups 1902 using Old2NewTy = DenseMap<InterleaveGroup<Instruction> *, 1903 InterleaveGroup<VPInstruction> *>; 1904 1905 /// Recursively \p Region and populate VPlan based interleave groups based on 1906 /// \p IAI. 1907 void visitRegion(VPRegionBlock *Region, Old2NewTy &Old2New, 1908 InterleavedAccessInfo &IAI); 1909 /// Recursively traverse \p Block and populate VPlan based interleave groups 1910 /// based on \p IAI. 1911 void visitBlock(VPBlockBase *Block, Old2NewTy &Old2New, 1912 InterleavedAccessInfo &IAI); 1913 1914 public: 1915 VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI); 1916 1917 ~VPInterleavedAccessInfo() { 1918 SmallPtrSet<InterleaveGroup<VPInstruction> *, 4> DelSet; 1919 // Avoid releasing a pointer twice. 1920 for (auto &I : InterleaveGroupMap) 1921 DelSet.insert(I.second); 1922 for (auto *Ptr : DelSet) 1923 delete Ptr; 1924 } 1925 1926 /// Get the interleave group that \p Instr belongs to. 1927 /// 1928 /// \returns nullptr if doesn't have such group. 1929 InterleaveGroup<VPInstruction> * 1930 getInterleaveGroup(VPInstruction *Instr) const { 1931 if (InterleaveGroupMap.count(Instr)) 1932 return InterleaveGroupMap.find(Instr)->second; 1933 return nullptr; 1934 } 1935 }; 1936 1937 /// Class that maps (parts of) an existing VPlan to trees of combined 1938 /// VPInstructions. 1939 class VPlanSlp { 1940 enum class OpMode { Failed, Load, Opcode }; 1941 1942 /// A DenseMapInfo implementation for using SmallVector<VPValue *, 4> as 1943 /// DenseMap keys. 1944 struct BundleDenseMapInfo { 1945 static SmallVector<VPValue *, 4> getEmptyKey() { 1946 return {reinterpret_cast<VPValue *>(-1)}; 1947 } 1948 1949 static SmallVector<VPValue *, 4> getTombstoneKey() { 1950 return {reinterpret_cast<VPValue *>(-2)}; 1951 } 1952 1953 static unsigned getHashValue(const SmallVector<VPValue *, 4> &V) { 1954 return static_cast<unsigned>(hash_combine_range(V.begin(), V.end())); 1955 } 1956 1957 static bool isEqual(const SmallVector<VPValue *, 4> &LHS, 1958 const SmallVector<VPValue *, 4> &RHS) { 1959 return LHS == RHS; 1960 } 1961 }; 1962 1963 /// Mapping of values in the original VPlan to a combined VPInstruction. 1964 DenseMap<SmallVector<VPValue *, 4>, VPInstruction *, BundleDenseMapInfo> 1965 BundleToCombined; 1966 1967 VPInterleavedAccessInfo &IAI; 1968 1969 /// Basic block to operate on. For now, only instructions in a single BB are 1970 /// considered. 1971 const VPBasicBlock &BB; 1972 1973 /// Indicates whether we managed to combine all visited instructions or not. 1974 bool CompletelySLP = true; 1975 1976 /// Width of the widest combined bundle in bits. 1977 unsigned WidestBundleBits = 0; 1978 1979 using MultiNodeOpTy = 1980 typename std::pair<VPInstruction *, SmallVector<VPValue *, 4>>; 1981 1982 // Input operand bundles for the current multi node. Each multi node operand 1983 // bundle contains values not matching the multi node's opcode. They will 1984 // be reordered in reorderMultiNodeOps, once we completed building a 1985 // multi node. 1986 SmallVector<MultiNodeOpTy, 4> MultiNodeOps; 1987 1988 /// Indicates whether we are building a multi node currently. 1989 bool MultiNodeActive = false; 1990 1991 /// Check if we can vectorize Operands together. 1992 bool areVectorizable(ArrayRef<VPValue *> Operands) const; 1993 1994 /// Add combined instruction \p New for the bundle \p Operands. 1995 void addCombined(ArrayRef<VPValue *> Operands, VPInstruction *New); 1996 1997 /// Indicate we hit a bundle we failed to combine. Returns nullptr for now. 1998 VPInstruction *markFailed(); 1999 2000 /// Reorder operands in the multi node to maximize sequential memory access 2001 /// and commutative operations. 2002 SmallVector<MultiNodeOpTy, 4> reorderMultiNodeOps(); 2003 2004 /// Choose the best candidate to use for the lane after \p Last. The set of 2005 /// candidates to choose from are values with an opcode matching \p Last's 2006 /// or loads consecutive to \p Last. 2007 std::pair<OpMode, VPValue *> getBest(OpMode Mode, VPValue *Last, 2008 SmallPtrSetImpl<VPValue *> &Candidates, 2009 VPInterleavedAccessInfo &IAI); 2010 2011 /// Print bundle \p Values to dbgs(). 2012 void dumpBundle(ArrayRef<VPValue *> Values); 2013 2014 public: 2015 VPlanSlp(VPInterleavedAccessInfo &IAI, VPBasicBlock &BB) : IAI(IAI), BB(BB) {} 2016 2017 ~VPlanSlp() = default; 2018 2019 /// Tries to build an SLP tree rooted at \p Operands and returns a 2020 /// VPInstruction combining \p Operands, if they can be combined. 2021 VPInstruction *buildGraph(ArrayRef<VPValue *> Operands); 2022 2023 /// Return the width of the widest combined bundle in bits. 2024 unsigned getWidestBundleBits() const { return WidestBundleBits; } 2025 2026 /// Return true if all visited instruction can be combined. 2027 bool isCompletelySLP() const { return CompletelySLP; } 2028 }; 2029 } // end namespace llvm 2030 2031 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H 2032