xref: /llvm-project/llvm/lib/Transforms/Vectorize/VPlanValue.h (revision 65cd9e4c2f85bd119eb039df1c90e8c97cbffb0c)
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