xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Vectorize/VPlanValue.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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