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