1 //===- VPlanValue.h - Represent Values in Vectorizer Plan -----------------===// 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 entities induced by Vectorization 11 /// Plans, e.g. the instructions the VPlan intends to generate if executed. 12 /// VPlan models the following entities: 13 /// VPValue VPUser VPDef 14 /// | | 15 /// VPInstruction 16 /// These are documented in docs/VectorizationPlan.rst. 17 /// 18 //===----------------------------------------------------------------------===// 19 20 #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H 21 #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H 22 23 #include "llvm/ADT/DenseMap.h" 24 #include "llvm/ADT/STLExtras.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/StringMap.h" 27 #include "llvm/ADT/TinyPtrVector.h" 28 #include "llvm/ADT/iterator_range.h" 29 30 namespace llvm { 31 32 // Forward declarations. 33 class raw_ostream; 34 class Value; 35 class VPDef; 36 struct VPDoubleValueDef; 37 class VPSlotTracker; 38 class VPUser; 39 class VPRecipeBase; 40 class VPInterleaveRecipe; 41 42 // This is the base class of the VPlan Def/Use graph, used for modeling the data 43 // flow into, within and out of the VPlan. VPValues can stand for live-ins 44 // coming from the input IR and instructions which VPlan will generate if 45 // executed. 46 class VPValue { 47 friend class VPBuilder; 48 friend class VPDef; 49 friend struct VPDoubleValueDef; 50 friend class VPInstruction; 51 friend class VPInterleaveRecipe; 52 friend struct VPlanTransforms; 53 friend class VPBasicBlock; 54 friend class VPInterleavedAccessInfo; 55 friend class VPSlotTracker; 56 friend class VPRecipeBase; 57 friend class VPlan; 58 59 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast). 60 61 SmallVector<VPUser *, 1> Users; 62 63 protected: 64 // Hold the underlying Value, if any, attached to this VPValue. 65 Value *UnderlyingVal; 66 67 /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the 68 /// VPValue is not defined by any recipe modeled in VPlan. 69 VPDef *Def; 70 71 VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr); 72 73 /// Create a live-in VPValue. 74 VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV, nullptr) {} 75 /// Create a VPValue for a \p Def which is a subclass of VPValue. 76 VPValue(VPDef *Def, Value *UV = nullptr) : VPValue(VPVRecipeSC, UV, Def) {} 77 /// Create a VPValue for a \p Def which defines multiple values. 78 VPValue(Value *UV, VPDef *Def) : VPValue(VPValueSC, UV, Def) {} 79 80 // DESIGN PRINCIPLE: Access to the underlying IR must be strictly limited to 81 // the front-end and back-end of VPlan so that the middle-end is as 82 // independent as possible of the underlying IR. We grant access to the 83 // underlying IR using friendship. In that way, we should be able to use VPlan 84 // for multiple underlying IRs (Polly?) by providing a new VPlan front-end, 85 // back-end and analysis information for the new IR. 86 87 public: 88 /// Return the underlying Value attached to this VPValue. 89 Value *getUnderlyingValue() const { return UnderlyingVal; } 90 91 /// An enumeration for keeping track of the concrete subclass of VPValue that 92 /// are actually instantiated. 93 enum { 94 VPValueSC, /// A generic VPValue, like live-in values or defined by a recipe 95 /// that defines multiple values. 96 VPVRecipeSC /// A VPValue sub-class that is a VPRecipeBase. 97 }; 98 99 VPValue(const VPValue &) = delete; 100 VPValue &operator=(const VPValue &) = delete; 101 102 virtual ~VPValue(); 103 104 /// \return an ID for the concrete type of this object. 105 /// This is used to implement the classof checks. This should not be used 106 /// for any other purpose, as the values may change as LLVM evolves. 107 unsigned getVPValueID() const { return SubclassID; } 108 109 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 110 void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const; 111 void print(raw_ostream &OS, VPSlotTracker &Tracker) const; 112 113 /// Dump the value to stderr (for debugging). 114 void dump() const; 115 #endif 116 117 unsigned getNumUsers() const { return Users.size(); } 118 void addUser(VPUser &User) { Users.push_back(&User); } 119 120 /// Remove a single \p User from the list of users. 121 void removeUser(VPUser &User) { 122 // The same user can be added multiple times, e.g. because the same VPValue 123 // is used twice by the same VPUser. Remove a single one. 124 auto *I = find(Users, &User); 125 if (I != Users.end()) 126 Users.erase(I); 127 } 128 129 typedef SmallVectorImpl<VPUser *>::iterator user_iterator; 130 typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator; 131 typedef iterator_range<user_iterator> user_range; 132 typedef iterator_range<const_user_iterator> const_user_range; 133 134 user_iterator user_begin() { return Users.begin(); } 135 const_user_iterator user_begin() const { return Users.begin(); } 136 user_iterator user_end() { return Users.end(); } 137 const_user_iterator user_end() const { return Users.end(); } 138 user_range users() { return user_range(user_begin(), user_end()); } 139 const_user_range users() const { 140 return const_user_range(user_begin(), user_end()); 141 } 142 143 /// Returns true if the value has more than one unique user. 144 bool hasMoreThanOneUniqueUser() const { 145 if (getNumUsers() == 0) 146 return false; 147 148 // Check if all users match the first user. 149 auto Current = std::next(user_begin()); 150 while (Current != user_end() && *user_begin() == *Current) 151 Current++; 152 return Current != user_end(); 153 } 154 155 void replaceAllUsesWith(VPValue *New); 156 157 /// Go through the uses list for this VPValue and make each use point to \p 158 /// New if the callback ShouldReplace returns true for the given use specified 159 /// by a pair of (VPUser, the use index). 160 void replaceUsesWithIf( 161 VPValue *New, 162 llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace); 163 164 /// Returns the recipe defining this VPValue or nullptr if it is not defined 165 /// by a recipe, i.e. is a live-in. 166 VPRecipeBase *getDefiningRecipe(); 167 const VPRecipeBase *getDefiningRecipe() const; 168 169 /// Returns true if this VPValue is defined by a recipe. 170 bool hasDefiningRecipe() const { return getDefiningRecipe(); } 171 172 /// Returns true if this VPValue is a live-in, i.e. defined outside the VPlan. 173 bool isLiveIn() const { return !hasDefiningRecipe(); } 174 175 /// Returns the underlying IR value, if this VPValue is defined outside the 176 /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef 177 /// inside a VPlan. 178 Value *getLiveInIRValue() { 179 assert(isLiveIn() && 180 "VPValue is not a live-in; it is defined by a VPDef inside a VPlan"); 181 return getUnderlyingValue(); 182 } 183 const Value *getLiveInIRValue() const { 184 assert(isLiveIn() && 185 "VPValue is not a live-in; it is defined by a VPDef inside a VPlan"); 186 return getUnderlyingValue(); 187 } 188 189 /// Returns true if the VPValue is defined outside any loop region. 190 bool isDefinedOutsideLoopRegions() const; 191 192 // Set \p Val as the underlying Value of this VPValue. 193 void setUnderlyingValue(Value *Val) { 194 assert(!UnderlyingVal && "Underlying Value is already set."); 195 UnderlyingVal = Val; 196 } 197 }; 198 199 typedef DenseMap<Value *, VPValue *> Value2VPValueTy; 200 typedef DenseMap<VPValue *, Value *> VPValue2ValueTy; 201 202 raw_ostream &operator<<(raw_ostream &OS, const VPValue &V); 203 204 /// This class augments VPValue with operands which provide the inverse def-use 205 /// edges from VPValue's users to their defs. 206 class VPUser { 207 SmallVector<VPValue *, 2> Operands; 208 209 protected: 210 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 211 /// Print the operands to \p O. 212 void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const; 213 #endif 214 215 VPUser(ArrayRef<VPValue *> Operands) { 216 for (VPValue *Operand : Operands) 217 addOperand(Operand); 218 } 219 220 VPUser(std::initializer_list<VPValue *> Operands) 221 : VPUser(ArrayRef<VPValue *>(Operands)) {} 222 223 template <typename IterT> VPUser(iterator_range<IterT> Operands) { 224 for (VPValue *Operand : Operands) 225 addOperand(Operand); 226 } 227 228 public: 229 VPUser() = delete; 230 VPUser(const VPUser &) = delete; 231 VPUser &operator=(const VPUser &) = delete; 232 virtual ~VPUser() { 233 for (VPValue *Op : operands()) 234 Op->removeUser(*this); 235 } 236 237 void addOperand(VPValue *Operand) { 238 Operands.push_back(Operand); 239 Operand->addUser(*this); 240 } 241 242 unsigned getNumOperands() const { return Operands.size(); } 243 inline VPValue *getOperand(unsigned N) const { 244 assert(N < Operands.size() && "Operand index out of bounds"); 245 return Operands[N]; 246 } 247 248 void setOperand(unsigned I, VPValue *New) { 249 Operands[I]->removeUser(*this); 250 Operands[I] = New; 251 New->addUser(*this); 252 } 253 254 typedef SmallVectorImpl<VPValue *>::iterator operand_iterator; 255 typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator; 256 typedef iterator_range<operand_iterator> operand_range; 257 typedef iterator_range<const_operand_iterator> const_operand_range; 258 259 operand_iterator op_begin() { return Operands.begin(); } 260 const_operand_iterator op_begin() const { return Operands.begin(); } 261 operand_iterator op_end() { return Operands.end(); } 262 const_operand_iterator op_end() const { return Operands.end(); } 263 operand_range operands() { return operand_range(op_begin(), op_end()); } 264 const_operand_range operands() const { 265 return const_operand_range(op_begin(), op_end()); 266 } 267 268 /// Returns true if the VPUser uses scalars of operand \p Op. Conservatively 269 /// returns if only first (scalar) lane is used, as default. 270 virtual bool usesScalars(const VPValue *Op) const { 271 assert(is_contained(operands(), Op) && 272 "Op must be an operand of the recipe"); 273 return onlyFirstLaneUsed(Op); 274 } 275 276 /// Returns true if the VPUser only uses the first lane of operand \p Op. 277 /// Conservatively returns false. 278 virtual bool onlyFirstLaneUsed(const VPValue *Op) const { 279 assert(is_contained(operands(), Op) && 280 "Op must be an operand of the recipe"); 281 return false; 282 } 283 284 /// Returns true if the VPUser only uses the first part of operand \p Op. 285 /// Conservatively returns false. 286 virtual bool onlyFirstPartUsed(const VPValue *Op) const { 287 assert(is_contained(operands(), Op) && 288 "Op must be an operand of the recipe"); 289 return false; 290 } 291 }; 292 293 /// This class augments a recipe with a set of VPValues defined by the recipe. 294 /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns 295 /// the VPValues it defines and is responsible for deleting its defined values. 296 /// Single-value VPDefs that also inherit from VPValue must make sure to inherit 297 /// from VPDef before VPValue. 298 class VPDef { 299 friend class VPValue; 300 301 /// Subclass identifier (for isa/dyn_cast). 302 const unsigned char SubclassID; 303 304 /// The VPValues defined by this VPDef. 305 TinyPtrVector<VPValue *> DefinedValues; 306 307 /// Add \p V as a defined value by this VPDef. 308 void addDefinedValue(VPValue *V) { 309 assert(V->Def == this && 310 "can only add VPValue already linked with this VPDef"); 311 DefinedValues.push_back(V); 312 } 313 314 /// Remove \p V from the values defined by this VPDef. \p V must be a defined 315 /// value of this VPDef. 316 void removeDefinedValue(VPValue *V) { 317 assert(V->Def == this && "can only remove VPValue linked with this VPDef"); 318 assert(is_contained(DefinedValues, V) && 319 "VPValue to remove must be in DefinedValues"); 320 llvm::erase(DefinedValues, V); 321 V->Def = nullptr; 322 } 323 324 public: 325 /// An enumeration for keeping track of the concrete subclass of VPRecipeBase 326 /// that is actually instantiated. Values of this enumeration are kept in the 327 /// SubclassID field of the VPRecipeBase objects. They are used for concrete 328 /// type identification. 329 using VPRecipeTy = enum { 330 VPBranchOnMaskSC, 331 VPDerivedIVSC, 332 VPExpandSCEVSC, 333 VPIRInstructionSC, 334 VPInstructionSC, 335 VPInterleaveSC, 336 VPReductionEVLSC, 337 VPReductionSC, 338 VPPartialReductionSC, 339 VPReplicateSC, 340 VPScalarCastSC, 341 VPScalarIVStepsSC, 342 VPVectorPointerSC, 343 VPReverseVectorPointerSC, 344 VPWidenCallSC, 345 VPWidenCanonicalIVSC, 346 VPWidenCastSC, 347 VPWidenGEPSC, 348 VPWidenIntrinsicSC, 349 VPWidenLoadEVLSC, 350 VPWidenLoadSC, 351 VPWidenStoreEVLSC, 352 VPWidenStoreSC, 353 VPWidenSC, 354 VPWidenEVLSC, 355 VPWidenSelectSC, 356 VPBlendSC, 357 VPHistogramSC, 358 // START: Phi-like recipes. Need to be kept together. 359 VPWidenPHISC, 360 VPPredInstPHISC, 361 // START: SubclassID for recipes that inherit VPHeaderPHIRecipe. 362 // VPHeaderPHIRecipe need to be kept together. 363 VPCanonicalIVPHISC, 364 VPActiveLaneMaskPHISC, 365 VPEVLBasedIVPHISC, 366 VPFirstOrderRecurrencePHISC, 367 VPWidenIntOrFpInductionSC, 368 VPWidenPointerInductionSC, 369 VPScalarPHISC, 370 VPReductionPHISC, 371 // END: SubclassID for recipes that inherit VPHeaderPHIRecipe 372 // END: Phi-like recipes 373 VPFirstPHISC = VPWidenPHISC, 374 VPFirstHeaderPHISC = VPCanonicalIVPHISC, 375 VPLastHeaderPHISC = VPReductionPHISC, 376 VPLastPHISC = VPReductionPHISC, 377 }; 378 379 VPDef(const unsigned char SC) : SubclassID(SC) {} 380 381 virtual ~VPDef() { 382 for (VPValue *D : make_early_inc_range(DefinedValues)) { 383 assert(D->Def == this && 384 "all defined VPValues should point to the containing VPDef"); 385 assert(D->getNumUsers() == 0 && 386 "all defined VPValues should have no more users"); 387 D->Def = nullptr; 388 delete D; 389 } 390 } 391 392 /// Returns the only VPValue defined by the VPDef. Can only be called for 393 /// VPDefs with a single defined value. 394 VPValue *getVPSingleValue() { 395 assert(DefinedValues.size() == 1 && "must have exactly one defined value"); 396 assert(DefinedValues[0] && "defined value must be non-null"); 397 return DefinedValues[0]; 398 } 399 const VPValue *getVPSingleValue() const { 400 assert(DefinedValues.size() == 1 && "must have exactly one defined value"); 401 assert(DefinedValues[0] && "defined value must be non-null"); 402 return DefinedValues[0]; 403 } 404 405 /// Returns the VPValue with index \p I defined by the VPDef. 406 VPValue *getVPValue(unsigned I) { 407 assert(DefinedValues[I] && "defined value must be non-null"); 408 return DefinedValues[I]; 409 } 410 const VPValue *getVPValue(unsigned I) const { 411 assert(DefinedValues[I] && "defined value must be non-null"); 412 return DefinedValues[I]; 413 } 414 415 /// Returns an ArrayRef of the values defined by the VPDef. 416 ArrayRef<VPValue *> definedValues() { return DefinedValues; } 417 /// Returns an ArrayRef of the values defined by the VPDef. 418 ArrayRef<VPValue *> definedValues() const { return DefinedValues; } 419 420 /// Returns the number of values defined by the VPDef. 421 unsigned getNumDefinedValues() const { return DefinedValues.size(); } 422 423 /// \return an ID for the concrete type of this object. 424 /// This is used to implement the classof checks. This should not be used 425 /// for any other purpose, as the values may change as LLVM evolves. 426 unsigned getVPDefID() const { return SubclassID; } 427 428 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 429 /// Dump the VPDef to stderr (for debugging). 430 void dump() const; 431 432 /// Each concrete VPDef prints itself. 433 virtual void print(raw_ostream &O, const Twine &Indent, 434 VPSlotTracker &SlotTracker) const = 0; 435 #endif 436 }; 437 438 class VPlan; 439 class VPBasicBlock; 440 441 /// This class can be used to assign names to VPValues. For VPValues without 442 /// underlying value, assign consecutive numbers and use those as names (wrapped 443 /// in vp<>). Otherwise, use the name from the underlying value (wrapped in 444 /// ir<>), appending a .V version number if there are multiple uses of the same 445 /// name. Allows querying names for VPValues for printing, similar to the 446 /// ModuleSlotTracker for IR values. 447 class VPSlotTracker { 448 /// Keep track of versioned names assigned to VPValues with underlying IR 449 /// values. 450 DenseMap<const VPValue *, std::string> VPValue2Name; 451 /// Keep track of the next number to use to version the base name. 452 StringMap<unsigned> BaseName2Version; 453 454 /// Number to assign to the next VPValue without underlying value. 455 unsigned NextSlot = 0; 456 457 void assignName(const VPValue *V); 458 void assignNames(const VPlan &Plan); 459 void assignNames(const VPBasicBlock *VPBB); 460 461 public: 462 VPSlotTracker(const VPlan *Plan = nullptr) { 463 if (Plan) 464 assignNames(*Plan); 465 } 466 467 /// Returns the name assigned to \p V, if there is one, otherwise try to 468 /// construct one from the underlying value, if there's one; else return 469 /// <badref>. 470 std::string getOrCreateName(const VPValue *V) const; 471 }; 472 473 } // namespace llvm 474 475 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H 476