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 /// Insert an unlinked recipe into a basic block immediately before 657 /// the specified recipe. 658 void insertBefore(VPRecipeBase *InsertPos); 659 660 /// Insert an unlinked Recipe into a basic block immediately after 661 /// the specified Recipe. 662 void insertAfter(VPRecipeBase *InsertPos); 663 664 /// Unlink this recipe from its current VPBasicBlock and insert it into 665 /// the VPBasicBlock that MovePos lives in, right after MovePos. 666 void moveAfter(VPRecipeBase *MovePos); 667 668 /// This method unlinks 'this' from the containing basic block, but does not 669 /// delete it. 670 void removeFromParent(); 671 672 /// This method unlinks 'this' from the containing basic block and deletes it. 673 /// 674 /// \returns an iterator pointing to the element after the erased one 675 iplist<VPRecipeBase>::iterator eraseFromParent(); 676 }; 677 678 /// This is a concrete Recipe that models a single VPlan-level instruction. 679 /// While as any Recipe it may generate a sequence of IR instructions when 680 /// executed, these instructions would always form a single-def expression as 681 /// the VPInstruction is also a single def-use vertex. 682 class VPInstruction : public VPUser, public VPRecipeBase { 683 friend class VPlanSlp; 684 685 public: 686 /// VPlan opcodes, extending LLVM IR with idiomatics instructions. 687 enum { 688 Not = Instruction::OtherOpsEnd + 1, 689 ICmpULE, 690 SLPLoad, 691 SLPStore, 692 ActiveLaneMask, 693 }; 694 695 private: 696 typedef unsigned char OpcodeTy; 697 OpcodeTy Opcode; 698 699 /// Utility method serving execute(): generates a single instance of the 700 /// modeled instruction. 701 void generateInstruction(VPTransformState &State, unsigned Part); 702 703 protected: 704 Instruction *getUnderlyingInstr() { 705 return cast_or_null<Instruction>(getUnderlyingValue()); 706 } 707 708 void setUnderlyingInstr(Instruction *I) { setUnderlyingValue(I); } 709 710 public: 711 VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands) 712 : VPUser(VPValue::VPInstructionSC, Operands), 713 VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {} 714 715 VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands) 716 : VPInstruction(Opcode, ArrayRef<VPValue *>(Operands)) {} 717 718 /// Method to support type inquiry through isa, cast, and dyn_cast. 719 static inline bool classof(const VPValue *V) { 720 return V->getVPValueID() == VPValue::VPInstructionSC; 721 } 722 723 VPInstruction *clone() const { 724 SmallVector<VPValue *, 2> Operands(operands()); 725 return new VPInstruction(Opcode, Operands); 726 } 727 728 /// Method to support type inquiry through isa, cast, and dyn_cast. 729 static inline bool classof(const VPRecipeBase *R) { 730 return R->getVPRecipeID() == VPRecipeBase::VPInstructionSC; 731 } 732 733 unsigned getOpcode() const { return Opcode; } 734 735 /// Generate the instruction. 736 /// TODO: We currently execute only per-part unless a specific instance is 737 /// provided. 738 void execute(VPTransformState &State) override; 739 740 /// Print the Recipe. 741 void print(raw_ostream &O, const Twine &Indent, 742 VPSlotTracker &SlotTracker) const override; 743 744 /// Print the VPInstruction. 745 void print(raw_ostream &O) const; 746 void print(raw_ostream &O, VPSlotTracker &SlotTracker) const; 747 748 /// Return true if this instruction may modify memory. 749 bool mayWriteToMemory() const { 750 // TODO: we can use attributes of the called function to rule out memory 751 // modifications. 752 return Opcode == Instruction::Store || Opcode == Instruction::Call || 753 Opcode == Instruction::Invoke || Opcode == SLPStore; 754 } 755 756 bool hasResult() const { 757 // CallInst may or may not have a result, depending on the called function. 758 // Conservatively return calls have results for now. 759 switch (getOpcode()) { 760 case Instruction::Ret: 761 case Instruction::Br: 762 case Instruction::Store: 763 case Instruction::Switch: 764 case Instruction::IndirectBr: 765 case Instruction::Resume: 766 case Instruction::CatchRet: 767 case Instruction::Unreachable: 768 case Instruction::Fence: 769 case Instruction::AtomicRMW: 770 return false; 771 default: 772 return true; 773 } 774 } 775 }; 776 777 /// VPWidenRecipe is a recipe for producing a copy of vector type its 778 /// ingredient. This recipe covers most of the traditional vectorization cases 779 /// where each ingredient transforms into a vectorized version of itself. 780 class VPWidenRecipe : public VPRecipeBase { 781 /// Hold the instruction to be widened. 782 Instruction &Ingredient; 783 784 /// Hold VPValues for the operands of the ingredient. 785 VPUser User; 786 787 public: 788 template <typename IterT> 789 VPWidenRecipe(Instruction &I, iterator_range<IterT> Operands) 790 : VPRecipeBase(VPWidenSC), Ingredient(I), User(Operands) {} 791 792 ~VPWidenRecipe() override = default; 793 794 /// Method to support type inquiry through isa, cast, and dyn_cast. 795 static inline bool classof(const VPRecipeBase *V) { 796 return V->getVPRecipeID() == VPRecipeBase::VPWidenSC; 797 } 798 799 /// Produce widened copies of all Ingredients. 800 void execute(VPTransformState &State) override; 801 802 /// Print the recipe. 803 void print(raw_ostream &O, const Twine &Indent, 804 VPSlotTracker &SlotTracker) const override; 805 }; 806 807 /// A recipe for widening Call instructions. 808 class VPWidenCallRecipe : public VPRecipeBase { 809 /// Hold the call to be widened. 810 CallInst &Ingredient; 811 812 /// Hold VPValues for the arguments of the call. 813 VPUser User; 814 815 public: 816 template <typename IterT> 817 VPWidenCallRecipe(CallInst &I, iterator_range<IterT> CallArguments) 818 : VPRecipeBase(VPWidenCallSC), Ingredient(I), User(CallArguments) {} 819 820 ~VPWidenCallRecipe() override = default; 821 822 /// Method to support type inquiry through isa, cast, and dyn_cast. 823 static inline bool classof(const VPRecipeBase *V) { 824 return V->getVPRecipeID() == VPRecipeBase::VPWidenCallSC; 825 } 826 827 /// Produce a widened version of the call instruction. 828 void execute(VPTransformState &State) override; 829 830 /// Print the recipe. 831 void print(raw_ostream &O, const Twine &Indent, 832 VPSlotTracker &SlotTracker) const override; 833 }; 834 835 /// A recipe for widening select instructions. 836 class VPWidenSelectRecipe : public VPRecipeBase { 837 private: 838 /// Hold the select to be widened. 839 SelectInst &Ingredient; 840 841 /// Hold VPValues for the operands of the select. 842 VPUser User; 843 844 /// Is the condition of the select loop invariant? 845 bool InvariantCond; 846 847 public: 848 template <typename IterT> 849 VPWidenSelectRecipe(SelectInst &I, iterator_range<IterT> Operands, 850 bool InvariantCond) 851 : VPRecipeBase(VPWidenSelectSC), Ingredient(I), User(Operands), 852 InvariantCond(InvariantCond) {} 853 854 ~VPWidenSelectRecipe() override = default; 855 856 /// Method to support type inquiry through isa, cast, and dyn_cast. 857 static inline bool classof(const VPRecipeBase *V) { 858 return V->getVPRecipeID() == VPRecipeBase::VPWidenSelectSC; 859 } 860 861 /// Produce a widened version of the select instruction. 862 void execute(VPTransformState &State) override; 863 864 /// Print the recipe. 865 void print(raw_ostream &O, const Twine &Indent, 866 VPSlotTracker &SlotTracker) const override; 867 }; 868 869 /// A recipe for handling GEP instructions. 870 class VPWidenGEPRecipe : public VPRecipeBase { 871 GetElementPtrInst *GEP; 872 873 /// Hold VPValues for the base and indices of the GEP. 874 VPUser User; 875 876 bool IsPtrLoopInvariant; 877 SmallBitVector IsIndexLoopInvariant; 878 879 public: 880 template <typename IterT> 881 VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands, 882 Loop *OrigLoop) 883 : VPRecipeBase(VPWidenGEPSC), GEP(GEP), User(Operands), 884 IsIndexLoopInvariant(GEP->getNumIndices(), false) { 885 IsPtrLoopInvariant = OrigLoop->isLoopInvariant(GEP->getPointerOperand()); 886 for (auto Index : enumerate(GEP->indices())) 887 IsIndexLoopInvariant[Index.index()] = 888 OrigLoop->isLoopInvariant(Index.value().get()); 889 } 890 ~VPWidenGEPRecipe() override = default; 891 892 /// Method to support type inquiry through isa, cast, and dyn_cast. 893 static inline bool classof(const VPRecipeBase *V) { 894 return V->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC; 895 } 896 897 /// Generate the gep nodes. 898 void execute(VPTransformState &State) override; 899 900 /// Print the recipe. 901 void print(raw_ostream &O, const Twine &Indent, 902 VPSlotTracker &SlotTracker) const override; 903 }; 904 905 /// A recipe for handling phi nodes of integer and floating-point inductions, 906 /// producing their vector and scalar values. 907 class VPWidenIntOrFpInductionRecipe : public VPRecipeBase { 908 PHINode *IV; 909 TruncInst *Trunc; 910 911 public: 912 VPWidenIntOrFpInductionRecipe(PHINode *IV, TruncInst *Trunc = nullptr) 913 : VPRecipeBase(VPWidenIntOrFpInductionSC), IV(IV), Trunc(Trunc) {} 914 ~VPWidenIntOrFpInductionRecipe() override = default; 915 916 /// Method to support type inquiry through isa, cast, and dyn_cast. 917 static inline bool classof(const VPRecipeBase *V) { 918 return V->getVPRecipeID() == VPRecipeBase::VPWidenIntOrFpInductionSC; 919 } 920 921 /// Generate the vectorized and scalarized versions of the phi node as 922 /// needed by their users. 923 void execute(VPTransformState &State) override; 924 925 /// Print the recipe. 926 void print(raw_ostream &O, const Twine &Indent, 927 VPSlotTracker &SlotTracker) const override; 928 }; 929 930 /// A recipe for handling all phi nodes except for integer and FP inductions. 931 class VPWidenPHIRecipe : public VPRecipeBase { 932 PHINode *Phi; 933 934 public: 935 VPWidenPHIRecipe(PHINode *Phi) : VPRecipeBase(VPWidenPHISC), Phi(Phi) {} 936 ~VPWidenPHIRecipe() override = default; 937 938 /// Method to support type inquiry through isa, cast, and dyn_cast. 939 static inline bool classof(const VPRecipeBase *V) { 940 return V->getVPRecipeID() == VPRecipeBase::VPWidenPHISC; 941 } 942 943 /// Generate the phi/select nodes. 944 void execute(VPTransformState &State) override; 945 946 /// Print the recipe. 947 void print(raw_ostream &O, const Twine &Indent, 948 VPSlotTracker &SlotTracker) const override; 949 }; 950 951 /// A recipe for vectorizing a phi-node as a sequence of mask-based select 952 /// instructions. 953 class VPBlendRecipe : public VPRecipeBase { 954 PHINode *Phi; 955 956 /// The blend operation is a User of the incoming values and of their 957 /// respective masks, ordered [I0, M0, I1, M1, ...]. Note that a single value 958 /// might be incoming with a full mask for which there is no VPValue. 959 VPUser User; 960 961 public: 962 VPBlendRecipe(PHINode *Phi, ArrayRef<VPValue *> Operands) 963 : VPRecipeBase(VPBlendSC), Phi(Phi), User(Operands) { 964 assert(Operands.size() > 0 && 965 ((Operands.size() == 1) || (Operands.size() % 2 == 0)) && 966 "Expected either a single incoming value or a positive even number " 967 "of operands"); 968 } 969 970 /// Method to support type inquiry through isa, cast, and dyn_cast. 971 static inline bool classof(const VPRecipeBase *V) { 972 return V->getVPRecipeID() == VPRecipeBase::VPBlendSC; 973 } 974 975 /// Return the number of incoming values, taking into account that a single 976 /// incoming value has no mask. 977 unsigned getNumIncomingValues() const { 978 return (User.getNumOperands() + 1) / 2; 979 } 980 981 /// Return incoming value number \p Idx. 982 VPValue *getIncomingValue(unsigned Idx) const { 983 return User.getOperand(Idx * 2); 984 } 985 986 /// Return mask number \p Idx. 987 VPValue *getMask(unsigned Idx) const { return User.getOperand(Idx * 2 + 1); } 988 989 /// Generate the phi/select nodes. 990 void execute(VPTransformState &State) override; 991 992 /// Print the recipe. 993 void print(raw_ostream &O, const Twine &Indent, 994 VPSlotTracker &SlotTracker) const override; 995 }; 996 997 /// VPInterleaveRecipe is a recipe for transforming an interleave group of load 998 /// or stores into one wide load/store and shuffles. 999 class VPInterleaveRecipe : public VPRecipeBase { 1000 const InterleaveGroup<Instruction> *IG; 1001 VPUser User; 1002 1003 public: 1004 VPInterleaveRecipe(const InterleaveGroup<Instruction> *IG, VPValue *Addr, 1005 VPValue *Mask) 1006 : VPRecipeBase(VPInterleaveSC), IG(IG), User({Addr}) { 1007 if (Mask) 1008 User.addOperand(Mask); 1009 } 1010 ~VPInterleaveRecipe() override = default; 1011 1012 /// Method to support type inquiry through isa, cast, and dyn_cast. 1013 static inline bool classof(const VPRecipeBase *V) { 1014 return V->getVPRecipeID() == VPRecipeBase::VPInterleaveSC; 1015 } 1016 1017 /// Return the address accessed by this recipe. 1018 VPValue *getAddr() const { 1019 return User.getOperand(0); // Address is the 1st, mandatory operand. 1020 } 1021 1022 /// Return the mask used by this recipe. Note that a full mask is represented 1023 /// by a nullptr. 1024 VPValue *getMask() const { 1025 // Mask is optional and therefore the last, currently 2nd operand. 1026 return User.getNumOperands() == 2 ? User.getOperand(1) : nullptr; 1027 } 1028 1029 /// Generate the wide load or store, and shuffles. 1030 void execute(VPTransformState &State) override; 1031 1032 /// Print the recipe. 1033 void print(raw_ostream &O, const Twine &Indent, 1034 VPSlotTracker &SlotTracker) const override; 1035 1036 const InterleaveGroup<Instruction> *getInterleaveGroup() { return IG; } 1037 }; 1038 1039 /// A recipe to represent inloop reduction operations, performing a reduction on 1040 /// a vector operand into a scalar value, and adding the result to a chain. 1041 class VPReductionRecipe : public VPRecipeBase { 1042 /// The recurrence decriptor for the reduction in question. 1043 RecurrenceDescriptor *RdxDesc; 1044 /// The original instruction being converted to a reduction. 1045 Instruction *I; 1046 /// The VPValue of the vector value to be reduced. 1047 VPValue *VecOp; 1048 /// The VPValue of the scalar Chain being accumulated. 1049 VPValue *ChainOp; 1050 /// Fast math flags to use for the resulting reduction operation. 1051 bool NoNaN; 1052 /// Pointer to the TTI, needed to create the target reduction 1053 const TargetTransformInfo *TTI; 1054 1055 public: 1056 VPReductionRecipe(RecurrenceDescriptor *R, Instruction *I, VPValue *ChainOp, 1057 VPValue *VecOp, bool NoNaN, const TargetTransformInfo *TTI) 1058 : VPRecipeBase(VPReductionSC), RdxDesc(R), I(I), VecOp(VecOp), 1059 ChainOp(ChainOp), NoNaN(NoNaN), TTI(TTI) {} 1060 1061 ~VPReductionRecipe() override = default; 1062 1063 /// Method to support type inquiry through isa, cast, and dyn_cast. 1064 static inline bool classof(const VPRecipeBase *V) { 1065 return V->getVPRecipeID() == VPRecipeBase::VPReductionSC; 1066 } 1067 1068 /// Generate the reduction in the loop 1069 void execute(VPTransformState &State) override; 1070 1071 /// Print the recipe. 1072 void print(raw_ostream &O, const Twine &Indent, 1073 VPSlotTracker &SlotTracker) const override; 1074 }; 1075 1076 /// VPReplicateRecipe replicates a given instruction producing multiple scalar 1077 /// copies of the original scalar type, one per lane, instead of producing a 1078 /// single copy of widened type for all lanes. If the instruction is known to be 1079 /// uniform only one copy, per lane zero, will be generated. 1080 class VPReplicateRecipe : public VPRecipeBase { 1081 /// The instruction being replicated. 1082 Instruction *Ingredient; 1083 1084 /// Hold VPValues for the operands of the ingredient. 1085 VPUser User; 1086 1087 /// Indicator if only a single replica per lane is needed. 1088 bool IsUniform; 1089 1090 /// Indicator if the replicas are also predicated. 1091 bool IsPredicated; 1092 1093 /// Indicator if the scalar values should also be packed into a vector. 1094 bool AlsoPack; 1095 1096 public: 1097 template <typename IterT> 1098 VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands, 1099 bool IsUniform, bool IsPredicated = false) 1100 : VPRecipeBase(VPReplicateSC), Ingredient(I), User(Operands), 1101 IsUniform(IsUniform), IsPredicated(IsPredicated) { 1102 // Retain the previous behavior of predicateInstructions(), where an 1103 // insert-element of a predicated instruction got hoisted into the 1104 // predicated basic block iff it was its only user. This is achieved by 1105 // having predicated instructions also pack their values into a vector by 1106 // default unless they have a replicated user which uses their scalar value. 1107 AlsoPack = IsPredicated && !I->use_empty(); 1108 } 1109 1110 ~VPReplicateRecipe() override = default; 1111 1112 /// Method to support type inquiry through isa, cast, and dyn_cast. 1113 static inline bool classof(const VPRecipeBase *V) { 1114 return V->getVPRecipeID() == VPRecipeBase::VPReplicateSC; 1115 } 1116 1117 /// Generate replicas of the desired Ingredient. Replicas will be generated 1118 /// for all parts and lanes unless a specific part and lane are specified in 1119 /// the \p State. 1120 void execute(VPTransformState &State) override; 1121 1122 void setAlsoPack(bool Pack) { AlsoPack = Pack; } 1123 1124 /// Print the recipe. 1125 void print(raw_ostream &O, const Twine &Indent, 1126 VPSlotTracker &SlotTracker) const override; 1127 }; 1128 1129 /// A recipe for generating conditional branches on the bits of a mask. 1130 class VPBranchOnMaskRecipe : public VPRecipeBase { 1131 VPUser User; 1132 1133 public: 1134 VPBranchOnMaskRecipe(VPValue *BlockInMask) : VPRecipeBase(VPBranchOnMaskSC) { 1135 if (BlockInMask) // nullptr means all-one mask. 1136 User.addOperand(BlockInMask); 1137 } 1138 1139 /// Method to support type inquiry through isa, cast, and dyn_cast. 1140 static inline bool classof(const VPRecipeBase *V) { 1141 return V->getVPRecipeID() == VPRecipeBase::VPBranchOnMaskSC; 1142 } 1143 1144 /// Generate the extraction of the appropriate bit from the block mask and the 1145 /// conditional branch. 1146 void execute(VPTransformState &State) override; 1147 1148 /// Print the recipe. 1149 void print(raw_ostream &O, const Twine &Indent, 1150 VPSlotTracker &SlotTracker) const override { 1151 O << " +\n" << Indent << "\"BRANCH-ON-MASK "; 1152 if (VPValue *Mask = getMask()) 1153 Mask->print(O, SlotTracker); 1154 else 1155 O << " All-One"; 1156 O << "\\l\""; 1157 } 1158 1159 /// Return the mask used by this recipe. Note that a full mask is represented 1160 /// by a nullptr. 1161 VPValue *getMask() const { 1162 assert(User.getNumOperands() <= 1 && "should have either 0 or 1 operands"); 1163 // Mask is optional. 1164 return User.getNumOperands() == 1 ? User.getOperand(0) : nullptr; 1165 } 1166 }; 1167 1168 /// VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when 1169 /// control converges back from a Branch-on-Mask. The phi nodes are needed in 1170 /// order to merge values that are set under such a branch and feed their uses. 1171 /// The phi nodes can be scalar or vector depending on the users of the value. 1172 /// This recipe works in concert with VPBranchOnMaskRecipe. 1173 class VPPredInstPHIRecipe : public VPRecipeBase { 1174 Instruction *PredInst; 1175 1176 public: 1177 /// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi 1178 /// nodes after merging back from a Branch-on-Mask. 1179 VPPredInstPHIRecipe(Instruction *PredInst) 1180 : VPRecipeBase(VPPredInstPHISC), PredInst(PredInst) {} 1181 ~VPPredInstPHIRecipe() override = default; 1182 1183 /// Method to support type inquiry through isa, cast, and dyn_cast. 1184 static inline bool classof(const VPRecipeBase *V) { 1185 return V->getVPRecipeID() == VPRecipeBase::VPPredInstPHISC; 1186 } 1187 1188 /// Generates phi nodes for live-outs as needed to retain SSA form. 1189 void execute(VPTransformState &State) override; 1190 1191 /// Print the recipe. 1192 void print(raw_ostream &O, const Twine &Indent, 1193 VPSlotTracker &SlotTracker) const override; 1194 }; 1195 1196 /// A Recipe for widening load/store operations. 1197 /// The recipe uses the following VPValues: 1198 /// - For load: Address, optional mask 1199 /// - For store: Address, stored value, optional mask 1200 /// TODO: We currently execute only per-part unless a specific instance is 1201 /// provided. 1202 class VPWidenMemoryInstructionRecipe : public VPRecipeBase { 1203 Instruction &Instr; 1204 VPUser User; 1205 1206 void setMask(VPValue *Mask) { 1207 if (!Mask) 1208 return; 1209 User.addOperand(Mask); 1210 } 1211 1212 bool isMasked() const { 1213 return (isa<LoadInst>(Instr) && User.getNumOperands() == 2) || 1214 (isa<StoreInst>(Instr) && User.getNumOperands() == 3); 1215 } 1216 1217 public: 1218 VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask) 1219 : VPRecipeBase(VPWidenMemoryInstructionSC), Instr(Load), User({Addr}) { 1220 setMask(Mask); 1221 } 1222 1223 VPWidenMemoryInstructionRecipe(StoreInst &Store, VPValue *Addr, 1224 VPValue *StoredValue, VPValue *Mask) 1225 : VPRecipeBase(VPWidenMemoryInstructionSC), Instr(Store), 1226 User({Addr, StoredValue}) { 1227 setMask(Mask); 1228 } 1229 1230 /// Method to support type inquiry through isa, cast, and dyn_cast. 1231 static inline bool classof(const VPRecipeBase *V) { 1232 return V->getVPRecipeID() == VPRecipeBase::VPWidenMemoryInstructionSC; 1233 } 1234 1235 /// Return the address accessed by this recipe. 1236 VPValue *getAddr() const { 1237 return User.getOperand(0); // Address is the 1st, mandatory operand. 1238 } 1239 1240 /// Return the mask used by this recipe. Note that a full mask is represented 1241 /// by a nullptr. 1242 VPValue *getMask() const { 1243 // Mask is optional and therefore the last operand. 1244 return isMasked() ? User.getOperand(User.getNumOperands() - 1) : nullptr; 1245 } 1246 1247 /// Return the address accessed by this recipe. 1248 VPValue *getStoredValue() const { 1249 assert(isa<StoreInst>(Instr) && 1250 "Stored value only available for store instructions"); 1251 return User.getOperand(1); // Stored value is the 2nd, mandatory operand. 1252 } 1253 1254 /// Generate the wide load/store. 1255 void execute(VPTransformState &State) override; 1256 1257 /// Print the recipe. 1258 void print(raw_ostream &O, const Twine &Indent, 1259 VPSlotTracker &SlotTracker) const override; 1260 }; 1261 1262 /// A Recipe for widening the canonical induction variable of the vector loop. 1263 class VPWidenCanonicalIVRecipe : public VPRecipeBase { 1264 /// A VPValue representing the canonical vector IV. 1265 VPValue Val; 1266 1267 public: 1268 VPWidenCanonicalIVRecipe() : VPRecipeBase(VPWidenCanonicalIVSC) {} 1269 ~VPWidenCanonicalIVRecipe() override = default; 1270 1271 /// Return the VPValue representing the canonical vector induction variable of 1272 /// the vector loop. 1273 const VPValue *getVPValue() const { return &Val; } 1274 VPValue *getVPValue() { return &Val; } 1275 1276 /// Method to support type inquiry through isa, cast, and dyn_cast. 1277 static inline bool classof(const VPRecipeBase *V) { 1278 return V->getVPRecipeID() == VPRecipeBase::VPWidenCanonicalIVSC; 1279 } 1280 1281 /// Generate a canonical vector induction variable of the vector loop, with 1282 /// start = {<Part*VF, Part*VF+1, ..., Part*VF+VF-1> for 0 <= Part < UF}, and 1283 /// step = <VF*UF, VF*UF, ..., VF*UF>. 1284 void execute(VPTransformState &State) override; 1285 1286 /// Print the recipe. 1287 void print(raw_ostream &O, const Twine &Indent, 1288 VPSlotTracker &SlotTracker) const override; 1289 }; 1290 1291 /// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It 1292 /// holds a sequence of zero or more VPRecipe's each representing a sequence of 1293 /// output IR instructions. 1294 class VPBasicBlock : public VPBlockBase { 1295 public: 1296 using RecipeListTy = iplist<VPRecipeBase>; 1297 1298 private: 1299 /// The VPRecipes held in the order of output instructions to generate. 1300 RecipeListTy Recipes; 1301 1302 public: 1303 VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr) 1304 : VPBlockBase(VPBasicBlockSC, Name.str()) { 1305 if (Recipe) 1306 appendRecipe(Recipe); 1307 } 1308 1309 ~VPBasicBlock() override { Recipes.clear(); } 1310 1311 /// Instruction iterators... 1312 using iterator = RecipeListTy::iterator; 1313 using const_iterator = RecipeListTy::const_iterator; 1314 using reverse_iterator = RecipeListTy::reverse_iterator; 1315 using const_reverse_iterator = RecipeListTy::const_reverse_iterator; 1316 1317 //===--------------------------------------------------------------------===// 1318 /// Recipe iterator methods 1319 /// 1320 inline iterator begin() { return Recipes.begin(); } 1321 inline const_iterator begin() const { return Recipes.begin(); } 1322 inline iterator end() { return Recipes.end(); } 1323 inline const_iterator end() const { return Recipes.end(); } 1324 1325 inline reverse_iterator rbegin() { return Recipes.rbegin(); } 1326 inline const_reverse_iterator rbegin() const { return Recipes.rbegin(); } 1327 inline reverse_iterator rend() { return Recipes.rend(); } 1328 inline const_reverse_iterator rend() const { return Recipes.rend(); } 1329 1330 inline size_t size() const { return Recipes.size(); } 1331 inline bool empty() const { return Recipes.empty(); } 1332 inline const VPRecipeBase &front() const { return Recipes.front(); } 1333 inline VPRecipeBase &front() { return Recipes.front(); } 1334 inline const VPRecipeBase &back() const { return Recipes.back(); } 1335 inline VPRecipeBase &back() { return Recipes.back(); } 1336 1337 /// Returns a reference to the list of recipes. 1338 RecipeListTy &getRecipeList() { return Recipes; } 1339 1340 /// Returns a pointer to a member of the recipe list. 1341 static RecipeListTy VPBasicBlock::*getSublistAccess(VPRecipeBase *) { 1342 return &VPBasicBlock::Recipes; 1343 } 1344 1345 /// Method to support type inquiry through isa, cast, and dyn_cast. 1346 static inline bool classof(const VPBlockBase *V) { 1347 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC; 1348 } 1349 1350 void insert(VPRecipeBase *Recipe, iterator InsertPt) { 1351 assert(Recipe && "No recipe to append."); 1352 assert(!Recipe->Parent && "Recipe already in VPlan"); 1353 Recipe->Parent = this; 1354 Recipes.insert(InsertPt, Recipe); 1355 } 1356 1357 /// Augment the existing recipes of a VPBasicBlock with an additional 1358 /// \p Recipe as the last recipe. 1359 void appendRecipe(VPRecipeBase *Recipe) { insert(Recipe, end()); } 1360 1361 /// The method which generates the output IR instructions that correspond to 1362 /// this VPBasicBlock, thereby "executing" the VPlan. 1363 void execute(struct VPTransformState *State) override; 1364 1365 private: 1366 /// Create an IR BasicBlock to hold the output instructions generated by this 1367 /// VPBasicBlock, and return it. Update the CFGState accordingly. 1368 BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG); 1369 }; 1370 1371 /// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks 1372 /// which form a Single-Entry-Single-Exit subgraph of the output IR CFG. 1373 /// A VPRegionBlock may indicate that its contents are to be replicated several 1374 /// times. This is designed to support predicated scalarization, in which a 1375 /// scalar if-then code structure needs to be generated VF * UF times. Having 1376 /// this replication indicator helps to keep a single model for multiple 1377 /// candidate VF's. The actual replication takes place only once the desired VF 1378 /// and UF have been determined. 1379 class VPRegionBlock : public VPBlockBase { 1380 /// Hold the Single Entry of the SESE region modelled by the VPRegionBlock. 1381 VPBlockBase *Entry; 1382 1383 /// Hold the Single Exit of the SESE region modelled by the VPRegionBlock. 1384 VPBlockBase *Exit; 1385 1386 /// An indicator whether this region is to generate multiple replicated 1387 /// instances of output IR corresponding to its VPBlockBases. 1388 bool IsReplicator; 1389 1390 public: 1391 VPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exit, 1392 const std::string &Name = "", bool IsReplicator = false) 1393 : VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exit(Exit), 1394 IsReplicator(IsReplicator) { 1395 assert(Entry->getPredecessors().empty() && "Entry block has predecessors."); 1396 assert(Exit->getSuccessors().empty() && "Exit block has successors."); 1397 Entry->setParent(this); 1398 Exit->setParent(this); 1399 } 1400 VPRegionBlock(const std::string &Name = "", bool IsReplicator = false) 1401 : VPBlockBase(VPRegionBlockSC, Name), Entry(nullptr), Exit(nullptr), 1402 IsReplicator(IsReplicator) {} 1403 1404 ~VPRegionBlock() override { 1405 if (Entry) 1406 deleteCFG(Entry); 1407 } 1408 1409 /// Method to support type inquiry through isa, cast, and dyn_cast. 1410 static inline bool classof(const VPBlockBase *V) { 1411 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC; 1412 } 1413 1414 const VPBlockBase *getEntry() const { return Entry; } 1415 VPBlockBase *getEntry() { return Entry; } 1416 1417 /// Set \p EntryBlock as the entry VPBlockBase of this VPRegionBlock. \p 1418 /// EntryBlock must have no predecessors. 1419 void setEntry(VPBlockBase *EntryBlock) { 1420 assert(EntryBlock->getPredecessors().empty() && 1421 "Entry block cannot have predecessors."); 1422 Entry = EntryBlock; 1423 EntryBlock->setParent(this); 1424 } 1425 1426 // FIXME: DominatorTreeBase is doing 'A->getParent()->front()'. 'front' is a 1427 // specific interface of llvm::Function, instead of using 1428 // GraphTraints::getEntryNode. We should add a new template parameter to 1429 // DominatorTreeBase representing the Graph type. 1430 VPBlockBase &front() const { return *Entry; } 1431 1432 const VPBlockBase *getExit() const { return Exit; } 1433 VPBlockBase *getExit() { return Exit; } 1434 1435 /// Set \p ExitBlock as the exit VPBlockBase of this VPRegionBlock. \p 1436 /// ExitBlock must have no successors. 1437 void setExit(VPBlockBase *ExitBlock) { 1438 assert(ExitBlock->getSuccessors().empty() && 1439 "Exit block cannot have successors."); 1440 Exit = ExitBlock; 1441 ExitBlock->setParent(this); 1442 } 1443 1444 /// An indicator whether this region is to generate multiple replicated 1445 /// instances of output IR corresponding to its VPBlockBases. 1446 bool isReplicator() const { return IsReplicator; } 1447 1448 /// The method which generates the output IR instructions that correspond to 1449 /// this VPRegionBlock, thereby "executing" the VPlan. 1450 void execute(struct VPTransformState *State) override; 1451 }; 1452 1453 //===----------------------------------------------------------------------===// 1454 // GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs // 1455 //===----------------------------------------------------------------------===// 1456 1457 // The following set of template specializations implement GraphTraits to treat 1458 // any VPBlockBase as a node in a graph of VPBlockBases. It's important to note 1459 // that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the 1460 // VPBlockBase is a VPRegionBlock, this specialization provides access to its 1461 // successors/predecessors but not to the blocks inside the region. 1462 1463 template <> struct GraphTraits<VPBlockBase *> { 1464 using NodeRef = VPBlockBase *; 1465 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; 1466 1467 static NodeRef getEntryNode(NodeRef N) { return N; } 1468 1469 static inline ChildIteratorType child_begin(NodeRef N) { 1470 return N->getSuccessors().begin(); 1471 } 1472 1473 static inline ChildIteratorType child_end(NodeRef N) { 1474 return N->getSuccessors().end(); 1475 } 1476 }; 1477 1478 template <> struct GraphTraits<const VPBlockBase *> { 1479 using NodeRef = const VPBlockBase *; 1480 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::const_iterator; 1481 1482 static NodeRef getEntryNode(NodeRef N) { return N; } 1483 1484 static inline ChildIteratorType child_begin(NodeRef N) { 1485 return N->getSuccessors().begin(); 1486 } 1487 1488 static inline ChildIteratorType child_end(NodeRef N) { 1489 return N->getSuccessors().end(); 1490 } 1491 }; 1492 1493 // Inverse order specialization for VPBasicBlocks. Predecessors are used instead 1494 // of successors for the inverse traversal. 1495 template <> struct GraphTraits<Inverse<VPBlockBase *>> { 1496 using NodeRef = VPBlockBase *; 1497 using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; 1498 1499 static NodeRef getEntryNode(Inverse<NodeRef> B) { return B.Graph; } 1500 1501 static inline ChildIteratorType child_begin(NodeRef N) { 1502 return N->getPredecessors().begin(); 1503 } 1504 1505 static inline ChildIteratorType child_end(NodeRef N) { 1506 return N->getPredecessors().end(); 1507 } 1508 }; 1509 1510 // The following set of template specializations implement GraphTraits to 1511 // treat VPRegionBlock as a graph and recurse inside its nodes. It's important 1512 // to note that the blocks inside the VPRegionBlock are treated as VPBlockBases 1513 // (i.e., no dyn_cast is performed, VPBlockBases specialization is used), so 1514 // there won't be automatic recursion into other VPBlockBases that turn to be 1515 // VPRegionBlocks. 1516 1517 template <> 1518 struct GraphTraits<VPRegionBlock *> : public GraphTraits<VPBlockBase *> { 1519 using GraphRef = VPRegionBlock *; 1520 using nodes_iterator = df_iterator<NodeRef>; 1521 1522 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } 1523 1524 static nodes_iterator nodes_begin(GraphRef N) { 1525 return nodes_iterator::begin(N->getEntry()); 1526 } 1527 1528 static nodes_iterator nodes_end(GraphRef N) { 1529 // df_iterator::end() returns an empty iterator so the node used doesn't 1530 // matter. 1531 return nodes_iterator::end(N); 1532 } 1533 }; 1534 1535 template <> 1536 struct GraphTraits<const VPRegionBlock *> 1537 : public GraphTraits<const VPBlockBase *> { 1538 using GraphRef = const VPRegionBlock *; 1539 using nodes_iterator = df_iterator<NodeRef>; 1540 1541 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } 1542 1543 static nodes_iterator nodes_begin(GraphRef N) { 1544 return nodes_iterator::begin(N->getEntry()); 1545 } 1546 1547 static nodes_iterator nodes_end(GraphRef N) { 1548 // df_iterator::end() returns an empty iterator so the node used doesn't 1549 // matter. 1550 return nodes_iterator::end(N); 1551 } 1552 }; 1553 1554 template <> 1555 struct GraphTraits<Inverse<VPRegionBlock *>> 1556 : public GraphTraits<Inverse<VPBlockBase *>> { 1557 using GraphRef = VPRegionBlock *; 1558 using nodes_iterator = df_iterator<NodeRef>; 1559 1560 static NodeRef getEntryNode(Inverse<GraphRef> N) { 1561 return N.Graph->getExit(); 1562 } 1563 1564 static nodes_iterator nodes_begin(GraphRef N) { 1565 return nodes_iterator::begin(N->getExit()); 1566 } 1567 1568 static nodes_iterator nodes_end(GraphRef N) { 1569 // df_iterator::end() returns an empty iterator so the node used doesn't 1570 // matter. 1571 return nodes_iterator::end(N); 1572 } 1573 }; 1574 1575 /// VPlan models a candidate for vectorization, encoding various decisions take 1576 /// to produce efficient output IR, including which branches, basic-blocks and 1577 /// output IR instructions to generate, and their cost. VPlan holds a 1578 /// Hierarchical-CFG of VPBasicBlocks and VPRegionBlocks rooted at an Entry 1579 /// VPBlock. 1580 class VPlan { 1581 friend class VPlanPrinter; 1582 friend class VPSlotTracker; 1583 1584 /// Hold the single entry to the Hierarchical CFG of the VPlan. 1585 VPBlockBase *Entry; 1586 1587 /// Holds the VFs applicable to this VPlan. 1588 SmallSetVector<ElementCount, 2> VFs; 1589 1590 /// Holds the name of the VPlan, for printing. 1591 std::string Name; 1592 1593 /// Holds all the external definitions created for this VPlan. 1594 // TODO: Introduce a specific representation for external definitions in 1595 // VPlan. External definitions must be immutable and hold a pointer to its 1596 // underlying IR that will be used to implement its structural comparison 1597 // (operators '==' and '<'). 1598 SmallPtrSet<VPValue *, 16> VPExternalDefs; 1599 1600 /// Represents the backedge taken count of the original loop, for folding 1601 /// the tail. 1602 VPValue *BackedgeTakenCount = nullptr; 1603 1604 /// Holds a mapping between Values and their corresponding VPValue inside 1605 /// VPlan. 1606 Value2VPValueTy Value2VPValue; 1607 1608 /// Holds the VPLoopInfo analysis for this VPlan. 1609 VPLoopInfo VPLInfo; 1610 1611 /// Holds the condition bit values built during VPInstruction to VPRecipe transformation. 1612 SmallVector<VPValue *, 4> VPCBVs; 1613 1614 public: 1615 VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) { 1616 if (Entry) 1617 Entry->setPlan(this); 1618 } 1619 1620 ~VPlan() { 1621 if (Entry) 1622 VPBlockBase::deleteCFG(Entry); 1623 for (auto &MapEntry : Value2VPValue) 1624 delete MapEntry.second; 1625 if (BackedgeTakenCount) 1626 delete BackedgeTakenCount; 1627 for (VPValue *Def : VPExternalDefs) 1628 delete Def; 1629 for (VPValue *CBV : VPCBVs) 1630 delete CBV; 1631 } 1632 1633 /// Generate the IR code for this VPlan. 1634 void execute(struct VPTransformState *State); 1635 1636 VPBlockBase *getEntry() { return Entry; } 1637 const VPBlockBase *getEntry() const { return Entry; } 1638 1639 VPBlockBase *setEntry(VPBlockBase *Block) { 1640 Entry = Block; 1641 Block->setPlan(this); 1642 return Entry; 1643 } 1644 1645 /// The backedge taken count of the original loop. 1646 VPValue *getOrCreateBackedgeTakenCount() { 1647 if (!BackedgeTakenCount) 1648 BackedgeTakenCount = new VPValue(); 1649 return BackedgeTakenCount; 1650 } 1651 1652 void addVF(ElementCount VF) { VFs.insert(VF); } 1653 1654 bool hasVF(ElementCount VF) { return VFs.count(VF); } 1655 1656 const std::string &getName() const { return Name; } 1657 1658 void setName(const Twine &newName) { Name = newName.str(); } 1659 1660 /// Add \p VPVal to the pool of external definitions if it's not already 1661 /// in the pool. 1662 void addExternalDef(VPValue *VPVal) { 1663 VPExternalDefs.insert(VPVal); 1664 } 1665 1666 /// Add \p CBV to the vector of condition bit values. 1667 void addCBV(VPValue *CBV) { 1668 VPCBVs.push_back(CBV); 1669 } 1670 1671 void addVPValue(Value *V) { 1672 assert(V && "Trying to add a null Value to VPlan"); 1673 assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); 1674 Value2VPValue[V] = new VPValue(V); 1675 } 1676 1677 VPValue *getVPValue(Value *V) { 1678 assert(V && "Trying to get the VPValue of a null Value"); 1679 assert(Value2VPValue.count(V) && "Value does not exist in VPlan"); 1680 return Value2VPValue[V]; 1681 } 1682 1683 VPValue *getOrAddVPValue(Value *V) { 1684 assert(V && "Trying to get or add the VPValue of a null Value"); 1685 if (!Value2VPValue.count(V)) 1686 addVPValue(V); 1687 return getVPValue(V); 1688 } 1689 1690 /// Return the VPLoopInfo analysis for this VPlan. 1691 VPLoopInfo &getVPLoopInfo() { return VPLInfo; } 1692 const VPLoopInfo &getVPLoopInfo() const { return VPLInfo; } 1693 1694 /// Dump the plan to stderr (for debugging). 1695 void dump() const; 1696 1697 /// Returns a range mapping the values the range \p Operands to their 1698 /// corresponding VPValues. 1699 iterator_range<mapped_iterator<Use *, std::function<VPValue *(Value *)>>> 1700 mapToVPValues(User::op_range Operands) { 1701 std::function<VPValue *(Value *)> Fn = [this](Value *Op) { 1702 return getOrAddVPValue(Op); 1703 }; 1704 return map_range(Operands, Fn); 1705 } 1706 1707 private: 1708 /// Add to the given dominator tree the header block and every new basic block 1709 /// that was created between it and the latch block, inclusive. 1710 static void updateDominatorTree(DominatorTree *DT, BasicBlock *LoopLatchBB, 1711 BasicBlock *LoopPreHeaderBB, 1712 BasicBlock *LoopExitBB); 1713 }; 1714 1715 /// VPlanPrinter prints a given VPlan to a given output stream. The printing is 1716 /// indented and follows the dot format. 1717 class VPlanPrinter { 1718 friend inline raw_ostream &operator<<(raw_ostream &OS, const VPlan &Plan); 1719 friend inline raw_ostream &operator<<(raw_ostream &OS, 1720 const struct VPlanIngredient &I); 1721 1722 private: 1723 raw_ostream &OS; 1724 const VPlan &Plan; 1725 unsigned Depth = 0; 1726 unsigned TabWidth = 2; 1727 std::string Indent; 1728 unsigned BID = 0; 1729 SmallDenseMap<const VPBlockBase *, unsigned> BlockID; 1730 1731 VPSlotTracker SlotTracker; 1732 1733 VPlanPrinter(raw_ostream &O, const VPlan &P) 1734 : OS(O), Plan(P), SlotTracker(&P) {} 1735 1736 /// Handle indentation. 1737 void bumpIndent(int b) { Indent = std::string((Depth += b) * TabWidth, ' '); } 1738 1739 /// Print a given \p Block of the Plan. 1740 void dumpBlock(const VPBlockBase *Block); 1741 1742 /// Print the information related to the CFG edges going out of a given 1743 /// \p Block, followed by printing the successor blocks themselves. 1744 void dumpEdges(const VPBlockBase *Block); 1745 1746 /// Print a given \p BasicBlock, including its VPRecipes, followed by printing 1747 /// its successor blocks. 1748 void dumpBasicBlock(const VPBasicBlock *BasicBlock); 1749 1750 /// Print a given \p Region of the Plan. 1751 void dumpRegion(const VPRegionBlock *Region); 1752 1753 unsigned getOrCreateBID(const VPBlockBase *Block) { 1754 return BlockID.count(Block) ? BlockID[Block] : BlockID[Block] = BID++; 1755 } 1756 1757 const Twine getOrCreateName(const VPBlockBase *Block); 1758 1759 const Twine getUID(const VPBlockBase *Block); 1760 1761 /// Print the information related to a CFG edge between two VPBlockBases. 1762 void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden, 1763 const Twine &Label); 1764 1765 void dump(); 1766 1767 static void printAsIngredient(raw_ostream &O, Value *V); 1768 }; 1769 1770 struct VPlanIngredient { 1771 Value *V; 1772 1773 VPlanIngredient(Value *V) : V(V) {} 1774 }; 1775 1776 inline raw_ostream &operator<<(raw_ostream &OS, const VPlanIngredient &I) { 1777 VPlanPrinter::printAsIngredient(OS, I.V); 1778 return OS; 1779 } 1780 1781 inline raw_ostream &operator<<(raw_ostream &OS, const VPlan &Plan) { 1782 VPlanPrinter Printer(OS, Plan); 1783 Printer.dump(); 1784 return OS; 1785 } 1786 1787 //===----------------------------------------------------------------------===// 1788 // VPlan Utilities 1789 //===----------------------------------------------------------------------===// 1790 1791 /// Class that provides utilities for VPBlockBases in VPlan. 1792 class VPBlockUtils { 1793 public: 1794 VPBlockUtils() = delete; 1795 1796 /// Insert disconnected VPBlockBase \p NewBlock after \p BlockPtr. Add \p 1797 /// NewBlock as successor of \p BlockPtr and \p BlockPtr as predecessor of \p 1798 /// NewBlock, and propagate \p BlockPtr parent to \p NewBlock. If \p BlockPtr 1799 /// has more than one successor, its conditional bit is propagated to \p 1800 /// NewBlock. \p NewBlock must have neither successors nor predecessors. 1801 static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) { 1802 assert(NewBlock->getSuccessors().empty() && 1803 "Can't insert new block with successors."); 1804 // TODO: move successors from BlockPtr to NewBlock when this functionality 1805 // is necessary. For now, setBlockSingleSuccessor will assert if BlockPtr 1806 // already has successors. 1807 BlockPtr->setOneSuccessor(NewBlock); 1808 NewBlock->setPredecessors({BlockPtr}); 1809 NewBlock->setParent(BlockPtr->getParent()); 1810 } 1811 1812 /// Insert disconnected VPBlockBases \p IfTrue and \p IfFalse after \p 1813 /// BlockPtr. Add \p IfTrue and \p IfFalse as succesors of \p BlockPtr and \p 1814 /// BlockPtr as predecessor of \p IfTrue and \p IfFalse. Propagate \p BlockPtr 1815 /// parent to \p IfTrue and \p IfFalse. \p Condition is set as the successor 1816 /// selector. \p BlockPtr must have no successors and \p IfTrue and \p IfFalse 1817 /// must have neither successors nor predecessors. 1818 static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse, 1819 VPValue *Condition, VPBlockBase *BlockPtr) { 1820 assert(IfTrue->getSuccessors().empty() && 1821 "Can't insert IfTrue with successors."); 1822 assert(IfFalse->getSuccessors().empty() && 1823 "Can't insert IfFalse with successors."); 1824 BlockPtr->setTwoSuccessors(IfTrue, IfFalse, Condition); 1825 IfTrue->setPredecessors({BlockPtr}); 1826 IfFalse->setPredecessors({BlockPtr}); 1827 IfTrue->setParent(BlockPtr->getParent()); 1828 IfFalse->setParent(BlockPtr->getParent()); 1829 } 1830 1831 /// Connect VPBlockBases \p From and \p To bi-directionally. Append \p To to 1832 /// the successors of \p From and \p From to the predecessors of \p To. Both 1833 /// VPBlockBases must have the same parent, which can be null. Both 1834 /// VPBlockBases can be already connected to other VPBlockBases. 1835 static void connectBlocks(VPBlockBase *From, VPBlockBase *To) { 1836 assert((From->getParent() == To->getParent()) && 1837 "Can't connect two block with different parents"); 1838 assert(From->getNumSuccessors() < 2 && 1839 "Blocks can't have more than two successors."); 1840 From->appendSuccessor(To); 1841 To->appendPredecessor(From); 1842 } 1843 1844 /// Disconnect VPBlockBases \p From and \p To bi-directionally. Remove \p To 1845 /// from the successors of \p From and \p From from the predecessors of \p To. 1846 static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To) { 1847 assert(To && "Successor to disconnect is null."); 1848 From->removeSuccessor(To); 1849 To->removePredecessor(From); 1850 } 1851 1852 /// Returns true if the edge \p FromBlock -> \p ToBlock is a back-edge. 1853 static bool isBackEdge(const VPBlockBase *FromBlock, 1854 const VPBlockBase *ToBlock, const VPLoopInfo *VPLI) { 1855 assert(FromBlock->getParent() == ToBlock->getParent() && 1856 FromBlock->getParent() && "Must be in same region"); 1857 const VPLoop *FromLoop = VPLI->getLoopFor(FromBlock); 1858 const VPLoop *ToLoop = VPLI->getLoopFor(ToBlock); 1859 if (!FromLoop || !ToLoop || FromLoop != ToLoop) 1860 return false; 1861 1862 // A back-edge is a branch from the loop latch to its header. 1863 return ToLoop->isLoopLatch(FromBlock) && ToBlock == ToLoop->getHeader(); 1864 } 1865 1866 /// Returns true if \p Block is a loop latch 1867 static bool blockIsLoopLatch(const VPBlockBase *Block, 1868 const VPLoopInfo *VPLInfo) { 1869 if (const VPLoop *ParentVPL = VPLInfo->getLoopFor(Block)) 1870 return ParentVPL->isLoopLatch(Block); 1871 1872 return false; 1873 } 1874 1875 /// Count and return the number of succesors of \p PredBlock excluding any 1876 /// backedges. 1877 static unsigned countSuccessorsNoBE(VPBlockBase *PredBlock, 1878 VPLoopInfo *VPLI) { 1879 unsigned Count = 0; 1880 for (VPBlockBase *SuccBlock : PredBlock->getSuccessors()) { 1881 if (!VPBlockUtils::isBackEdge(PredBlock, SuccBlock, VPLI)) 1882 Count++; 1883 } 1884 return Count; 1885 } 1886 }; 1887 1888 class VPInterleavedAccessInfo { 1889 DenseMap<VPInstruction *, InterleaveGroup<VPInstruction> *> 1890 InterleaveGroupMap; 1891 1892 /// Type for mapping of instruction based interleave groups to VPInstruction 1893 /// interleave groups 1894 using Old2NewTy = DenseMap<InterleaveGroup<Instruction> *, 1895 InterleaveGroup<VPInstruction> *>; 1896 1897 /// Recursively \p Region and populate VPlan based interleave groups based on 1898 /// \p IAI. 1899 void visitRegion(VPRegionBlock *Region, Old2NewTy &Old2New, 1900 InterleavedAccessInfo &IAI); 1901 /// Recursively traverse \p Block and populate VPlan based interleave groups 1902 /// based on \p IAI. 1903 void visitBlock(VPBlockBase *Block, Old2NewTy &Old2New, 1904 InterleavedAccessInfo &IAI); 1905 1906 public: 1907 VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI); 1908 1909 ~VPInterleavedAccessInfo() { 1910 SmallPtrSet<InterleaveGroup<VPInstruction> *, 4> DelSet; 1911 // Avoid releasing a pointer twice. 1912 for (auto &I : InterleaveGroupMap) 1913 DelSet.insert(I.second); 1914 for (auto *Ptr : DelSet) 1915 delete Ptr; 1916 } 1917 1918 /// Get the interleave group that \p Instr belongs to. 1919 /// 1920 /// \returns nullptr if doesn't have such group. 1921 InterleaveGroup<VPInstruction> * 1922 getInterleaveGroup(VPInstruction *Instr) const { 1923 if (InterleaveGroupMap.count(Instr)) 1924 return InterleaveGroupMap.find(Instr)->second; 1925 return nullptr; 1926 } 1927 }; 1928 1929 /// Class that maps (parts of) an existing VPlan to trees of combined 1930 /// VPInstructions. 1931 class VPlanSlp { 1932 enum class OpMode { Failed, Load, Opcode }; 1933 1934 /// A DenseMapInfo implementation for using SmallVector<VPValue *, 4> as 1935 /// DenseMap keys. 1936 struct BundleDenseMapInfo { 1937 static SmallVector<VPValue *, 4> getEmptyKey() { 1938 return {reinterpret_cast<VPValue *>(-1)}; 1939 } 1940 1941 static SmallVector<VPValue *, 4> getTombstoneKey() { 1942 return {reinterpret_cast<VPValue *>(-2)}; 1943 } 1944 1945 static unsigned getHashValue(const SmallVector<VPValue *, 4> &V) { 1946 return static_cast<unsigned>(hash_combine_range(V.begin(), V.end())); 1947 } 1948 1949 static bool isEqual(const SmallVector<VPValue *, 4> &LHS, 1950 const SmallVector<VPValue *, 4> &RHS) { 1951 return LHS == RHS; 1952 } 1953 }; 1954 1955 /// Mapping of values in the original VPlan to a combined VPInstruction. 1956 DenseMap<SmallVector<VPValue *, 4>, VPInstruction *, BundleDenseMapInfo> 1957 BundleToCombined; 1958 1959 VPInterleavedAccessInfo &IAI; 1960 1961 /// Basic block to operate on. For now, only instructions in a single BB are 1962 /// considered. 1963 const VPBasicBlock &BB; 1964 1965 /// Indicates whether we managed to combine all visited instructions or not. 1966 bool CompletelySLP = true; 1967 1968 /// Width of the widest combined bundle in bits. 1969 unsigned WidestBundleBits = 0; 1970 1971 using MultiNodeOpTy = 1972 typename std::pair<VPInstruction *, SmallVector<VPValue *, 4>>; 1973 1974 // Input operand bundles for the current multi node. Each multi node operand 1975 // bundle contains values not matching the multi node's opcode. They will 1976 // be reordered in reorderMultiNodeOps, once we completed building a 1977 // multi node. 1978 SmallVector<MultiNodeOpTy, 4> MultiNodeOps; 1979 1980 /// Indicates whether we are building a multi node currently. 1981 bool MultiNodeActive = false; 1982 1983 /// Check if we can vectorize Operands together. 1984 bool areVectorizable(ArrayRef<VPValue *> Operands) const; 1985 1986 /// Add combined instruction \p New for the bundle \p Operands. 1987 void addCombined(ArrayRef<VPValue *> Operands, VPInstruction *New); 1988 1989 /// Indicate we hit a bundle we failed to combine. Returns nullptr for now. 1990 VPInstruction *markFailed(); 1991 1992 /// Reorder operands in the multi node to maximize sequential memory access 1993 /// and commutative operations. 1994 SmallVector<MultiNodeOpTy, 4> reorderMultiNodeOps(); 1995 1996 /// Choose the best candidate to use for the lane after \p Last. The set of 1997 /// candidates to choose from are values with an opcode matching \p Last's 1998 /// or loads consecutive to \p Last. 1999 std::pair<OpMode, VPValue *> getBest(OpMode Mode, VPValue *Last, 2000 SmallPtrSetImpl<VPValue *> &Candidates, 2001 VPInterleavedAccessInfo &IAI); 2002 2003 /// Print bundle \p Values to dbgs(). 2004 void dumpBundle(ArrayRef<VPValue *> Values); 2005 2006 public: 2007 VPlanSlp(VPInterleavedAccessInfo &IAI, VPBasicBlock &BB) : IAI(IAI), BB(BB) {} 2008 2009 ~VPlanSlp() { 2010 for (auto &KV : BundleToCombined) 2011 delete KV.second; 2012 } 2013 2014 /// Tries to build an SLP tree rooted at \p Operands and returns a 2015 /// VPInstruction combining \p Operands, if they can be combined. 2016 VPInstruction *buildGraph(ArrayRef<VPValue *> Operands); 2017 2018 /// Return the width of the widest combined bundle in bits. 2019 unsigned getWidestBundleBits() const { return WidestBundleBits; } 2020 2021 /// Return true if all visited instruction can be combined. 2022 bool isCompletelySLP() const { return CompletelySLP; } 2023 }; 2024 } // end namespace llvm 2025 2026 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H 2027