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 #include "llvm/Support/Compiler.h" 30 31 namespace llvm { 32 33 // Forward declarations. 34 class raw_ostream; 35 class Value; 36 class VPDef; 37 struct VPDoubleValueDef; 38 class VPSlotTracker; 39 class VPUser; 40 class VPRecipeBase; 41 class VPInterleaveRecipe; 42 class VPPhiAccessors; 43 44 // This is the base class of the VPlan Def/Use graph, used for modeling the data 45 // flow into, within and out of the VPlan. VPValues can stand for live-ins 46 // coming from the input IR and instructions which VPlan will generate if 47 // executed. 48 class LLVM_ABI_FOR_TEST VPValue { 49 friend class VPDef; 50 friend struct VPDoubleValueDef; 51 friend class VPInterleaveRecipe; 52 friend class VPlan; 53 friend class VPExpressionRecipe; 54 55 const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast). 56 57 SmallVector<VPUser *, 1> Users; 58 59 protected: 60 // Hold the underlying Value, if any, attached to this VPValue. 61 Value *UnderlyingVal; 62 63 /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the 64 /// VPValue is not defined by any recipe modeled in VPlan. 65 VPDef *Def; 66 67 VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr); 68 69 /// Create a live-in VPValue. VPValue(VPValueSC,UV,nullptr)70 VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV, nullptr) {} 71 /// Create a VPValue for a \p Def which is a subclass of VPValue. VPValue(VPVRecipeSC,UV,Def)72 VPValue(VPDef *Def, Value *UV = nullptr) : VPValue(VPVRecipeSC, UV, Def) {} 73 /// Create a VPValue for a \p Def which defines multiple values. VPValue(Value * UV,VPDef * Def)74 VPValue(Value *UV, VPDef *Def) : VPValue(VPValueSC, UV, Def) {} 75 76 // DESIGN PRINCIPLE: Access to the underlying IR must be strictly limited to 77 // the front-end and back-end of VPlan so that the middle-end is as 78 // independent as possible of the underlying IR. We grant access to the 79 // underlying IR using friendship. In that way, we should be able to use VPlan 80 // for multiple underlying IRs (Polly?) by providing a new VPlan front-end, 81 // back-end and analysis information for the new IR. 82 83 public: 84 /// Return the underlying Value attached to this VPValue. getUnderlyingValue()85 Value *getUnderlyingValue() const { return UnderlyingVal; } 86 87 /// An enumeration for keeping track of the concrete subclass of VPValue that 88 /// are actually instantiated. 89 enum { 90 VPValueSC, /// A generic VPValue, like live-in values or defined by a recipe 91 /// that defines multiple values. 92 VPVRecipeSC /// A VPValue sub-class that is a VPRecipeBase. 93 }; 94 95 VPValue(const VPValue &) = delete; 96 VPValue &operator=(const VPValue &) = delete; 97 98 virtual ~VPValue(); 99 100 /// \return an ID for the concrete type of this object. 101 /// This is used to implement the classof checks. This should not be used 102 /// for any other purpose, as the values may change as LLVM evolves. getVPValueID()103 unsigned getVPValueID() const { return SubclassID; } 104 105 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 106 void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const; 107 void print(raw_ostream &OS, VPSlotTracker &Tracker) const; 108 109 /// Dump the value to stderr (for debugging). 110 void dump() const; 111 #endif 112 getNumUsers()113 unsigned getNumUsers() const { return Users.size(); } addUser(VPUser & User)114 void addUser(VPUser &User) { Users.push_back(&User); } 115 116 /// Remove a single \p User from the list of users. removeUser(VPUser & User)117 void removeUser(VPUser &User) { 118 // The same user can be added multiple times, e.g. because the same VPValue 119 // is used twice by the same VPUser. Remove a single one. 120 auto *I = find(Users, &User); 121 if (I != Users.end()) 122 Users.erase(I); 123 } 124 125 typedef SmallVectorImpl<VPUser *>::iterator user_iterator; 126 typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator; 127 typedef iterator_range<user_iterator> user_range; 128 typedef iterator_range<const_user_iterator> const_user_range; 129 user_begin()130 user_iterator user_begin() { return Users.begin(); } user_begin()131 const_user_iterator user_begin() const { return Users.begin(); } user_end()132 user_iterator user_end() { return Users.end(); } user_end()133 const_user_iterator user_end() const { return Users.end(); } users()134 user_range users() { return user_range(user_begin(), user_end()); } users()135 const_user_range users() const { 136 return const_user_range(user_begin(), user_end()); 137 } 138 139 /// Returns true if the value has more than one unique user. hasMoreThanOneUniqueUser()140 bool hasMoreThanOneUniqueUser() const { 141 if (getNumUsers() == 0) 142 return false; 143 144 // Check if all users match the first user. 145 auto Current = std::next(user_begin()); 146 while (Current != user_end() && *user_begin() == *Current) 147 Current++; 148 return Current != user_end(); 149 } 150 151 void replaceAllUsesWith(VPValue *New); 152 153 /// Go through the uses list for this VPValue and make each use point to \p 154 /// New if the callback ShouldReplace returns true for the given use specified 155 /// by a pair of (VPUser, the use index). 156 void replaceUsesWithIf( 157 VPValue *New, 158 llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace); 159 160 /// Returns the recipe defining this VPValue or nullptr if it is not defined 161 /// by a recipe, i.e. is a live-in. 162 VPRecipeBase *getDefiningRecipe(); 163 const VPRecipeBase *getDefiningRecipe() const; 164 165 /// Returns true if this VPValue is defined by a recipe. hasDefiningRecipe()166 bool hasDefiningRecipe() const { return getDefiningRecipe(); } 167 168 /// Returns true if this VPValue is a live-in, i.e. defined outside the VPlan. isLiveIn()169 bool isLiveIn() const { return !hasDefiningRecipe(); } 170 171 /// Returns the underlying IR value, if this VPValue is defined outside the 172 /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef 173 /// inside a VPlan. getLiveInIRValue()174 Value *getLiveInIRValue() const { 175 assert(isLiveIn() && 176 "VPValue is not a live-in; it is defined by a VPDef inside a VPlan"); 177 return getUnderlyingValue(); 178 } 179 180 /// Returns true if the VPValue is defined outside any loop. 181 bool isDefinedOutsideLoopRegions() const; 182 183 // Set \p Val as the underlying Value of this VPValue. setUnderlyingValue(Value * Val)184 void setUnderlyingValue(Value *Val) { 185 assert(!UnderlyingVal && "Underlying Value is already set."); 186 UnderlyingVal = Val; 187 } 188 }; 189 190 typedef DenseMap<Value *, VPValue *> Value2VPValueTy; 191 typedef DenseMap<VPValue *, Value *> VPValue2ValueTy; 192 193 raw_ostream &operator<<(raw_ostream &OS, const VPRecipeBase &R); 194 195 /// This class augments VPValue with operands which provide the inverse def-use 196 /// edges from VPValue's users to their defs. 197 class VPUser { 198 /// Grant access to removeOperand for VPPhiAccessors, the only supported user. 199 friend class VPPhiAccessors; 200 201 SmallVector<VPValue *, 2> Operands; 202 203 /// Removes the operand at index \p Idx. This also removes the VPUser from the 204 /// use-list of the operand. removeOperand(unsigned Idx)205 void removeOperand(unsigned Idx) { 206 getOperand(Idx)->removeUser(*this); 207 Operands.erase(Operands.begin() + Idx); 208 } 209 210 protected: 211 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 212 /// Print the operands to \p O. 213 void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const; 214 #endif 215 VPUser(ArrayRef<VPValue * > Operands)216 VPUser(ArrayRef<VPValue *> Operands) { 217 for (VPValue *Operand : Operands) 218 addOperand(Operand); 219 } 220 221 public: 222 VPUser() = delete; 223 VPUser(const VPUser &) = delete; 224 VPUser &operator=(const VPUser &) = delete; ~VPUser()225 virtual ~VPUser() { 226 for (VPValue *Op : operands()) 227 Op->removeUser(*this); 228 } 229 addOperand(VPValue * Operand)230 void addOperand(VPValue *Operand) { 231 Operands.push_back(Operand); 232 Operand->addUser(*this); 233 } 234 getNumOperands()235 unsigned getNumOperands() const { return Operands.size(); } getOperand(unsigned N)236 inline VPValue *getOperand(unsigned N) const { 237 assert(N < Operands.size() && "Operand index out of bounds"); 238 return Operands[N]; 239 } 240 setOperand(unsigned I,VPValue * New)241 void setOperand(unsigned I, VPValue *New) { 242 Operands[I]->removeUser(*this); 243 Operands[I] = New; 244 New->addUser(*this); 245 } 246 247 /// Swap operands of the VPUser. It must have exactly 2 operands. swapOperands()248 void swapOperands() { 249 assert(Operands.size() == 2 && "must have 2 operands to swap"); 250 std::swap(Operands[0], Operands[1]); 251 } 252 253 /// Replaces all uses of \p From in the VPUser with \p To. 254 void replaceUsesOfWith(VPValue *From, VPValue *To); 255 256 typedef SmallVectorImpl<VPValue *>::iterator operand_iterator; 257 typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator; 258 typedef iterator_range<operand_iterator> operand_range; 259 typedef iterator_range<const_operand_iterator> const_operand_range; 260 op_begin()261 operand_iterator op_begin() { return Operands.begin(); } op_begin()262 const_operand_iterator op_begin() const { return Operands.begin(); } op_end()263 operand_iterator op_end() { return Operands.end(); } op_end()264 const_operand_iterator op_end() const { return Operands.end(); } operands()265 operand_range operands() { return operand_range(op_begin(), op_end()); } operands()266 const_operand_range operands() const { 267 return const_operand_range(op_begin(), op_end()); 268 } 269 270 /// Returns true if the VPUser uses scalars of operand \p Op. Conservatively 271 /// returns if only first (scalar) lane is used, as default. usesScalars(const VPValue * Op)272 virtual bool usesScalars(const VPValue *Op) const { 273 assert(is_contained(operands(), Op) && 274 "Op must be an operand of the recipe"); 275 return onlyFirstLaneUsed(Op); 276 } 277 278 /// Returns true if the VPUser only uses the first lane of operand \p Op. 279 /// Conservatively returns false. onlyFirstLaneUsed(const VPValue * Op)280 virtual bool onlyFirstLaneUsed(const VPValue *Op) const { 281 assert(is_contained(operands(), Op) && 282 "Op must be an operand of the recipe"); 283 return false; 284 } 285 286 /// Returns true if the VPUser only uses the first part of operand \p Op. 287 /// Conservatively returns false. onlyFirstPartUsed(const VPValue * Op)288 virtual bool onlyFirstPartUsed(const VPValue *Op) const { 289 assert(is_contained(operands(), Op) && 290 "Op must be an operand of the recipe"); 291 return false; 292 } 293 }; 294 295 /// This class augments a recipe with a set of VPValues defined by the recipe. 296 /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns 297 /// the VPValues it defines and is responsible for deleting its defined values. 298 /// Single-value VPDefs that also inherit from VPValue must make sure to inherit 299 /// from VPDef before VPValue. 300 class VPDef { 301 friend class VPValue; 302 303 /// Subclass identifier (for isa/dyn_cast). 304 const unsigned char SubclassID; 305 306 /// The VPValues defined by this VPDef. 307 TinyPtrVector<VPValue *> DefinedValues; 308 309 /// Add \p V as a defined value by this VPDef. addDefinedValue(VPValue * V)310 void addDefinedValue(VPValue *V) { 311 assert(V->Def == this && 312 "can only add VPValue already linked with this VPDef"); 313 DefinedValues.push_back(V); 314 } 315 316 /// Remove \p V from the values defined by this VPDef. \p V must be a defined 317 /// value of this VPDef. removeDefinedValue(VPValue * V)318 void removeDefinedValue(VPValue *V) { 319 assert(V->Def == this && "can only remove VPValue linked with this VPDef"); 320 assert(is_contained(DefinedValues, V) && 321 "VPValue to remove must be in DefinedValues"); 322 llvm::erase(DefinedValues, V); 323 V->Def = nullptr; 324 } 325 326 public: 327 /// An enumeration for keeping track of the concrete subclass of VPRecipeBase 328 /// that is actually instantiated. Values of this enumeration are kept in the 329 /// SubclassID field of the VPRecipeBase objects. They are used for concrete 330 /// type identification. 331 using VPRecipeTy = enum { 332 VPBranchOnMaskSC, 333 VPDerivedIVSC, 334 VPExpandSCEVSC, 335 VPExpressionSC, 336 VPIRInstructionSC, 337 VPInstructionSC, 338 VPInterleaveSC, 339 VPReductionEVLSC, 340 VPReductionSC, 341 VPPartialReductionSC, 342 VPReplicateSC, 343 VPScalarIVStepsSC, 344 VPVectorPointerSC, 345 VPVectorEndPointerSC, 346 VPWidenCallSC, 347 VPWidenCanonicalIVSC, 348 VPWidenCastSC, 349 VPWidenGEPSC, 350 VPWidenIntrinsicSC, 351 VPWidenLoadEVLSC, 352 VPWidenLoadSC, 353 VPWidenStoreEVLSC, 354 VPWidenStoreSC, 355 VPWidenSC, 356 VPWidenSelectSC, 357 VPBlendSC, 358 VPHistogramSC, 359 // START: Phi-like recipes. Need to be kept together. 360 VPWidenPHISC, 361 VPPredInstPHISC, 362 // START: SubclassID for recipes that inherit VPHeaderPHIRecipe. 363 // VPHeaderPHIRecipe need to be kept together. 364 VPCanonicalIVPHISC, 365 VPActiveLaneMaskPHISC, 366 VPEVLBasedIVPHISC, 367 VPFirstOrderRecurrencePHISC, 368 VPWidenIntOrFpInductionSC, 369 VPWidenPointerInductionSC, 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 VPDef(const unsigned char SC)379 VPDef(const unsigned char SC) : SubclassID(SC) {} 380 ~VPDef()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. getVPSingleValue()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 } getVPSingleValue()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. getVPValue(unsigned I)406 VPValue *getVPValue(unsigned I) { 407 assert(DefinedValues[I] && "defined value must be non-null"); 408 return DefinedValues[I]; 409 } getVPValue(unsigned I)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. definedValues()416 ArrayRef<VPValue *> definedValues() { return DefinedValues; } 417 /// Returns an ArrayRef of the values defined by the VPDef. definedValues()418 ArrayRef<VPValue *> definedValues() const { return DefinedValues; } 419 420 /// Returns the number of values defined by the VPDef. getNumDefinedValues()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. getVPDefID()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 } // namespace llvm 439 440 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H 441