1 //===- VPlanValue.h - Represent Values in Vectorizer Plan -----------------===//
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
7 //===----------------------------------------------------------------------===//
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
16 /// These are documented in docs/VectorizationPlan.rst.
18 //===----------------------------------------------------------------------===//
20 #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
21 #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
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"
32 // Forward declarations.
40 // This is the base class of the VPlan Def/Use graph, used for modeling the data
41 // flow into, within and out of the VPlan. VPValues can stand for live-ins
42 // coming from the input IR and instructions which VPlan will generate if
45 friend class VPBuilder
;
47 friend class VPInstruction
;
48 friend struct VPlanTransforms
;
49 friend class VPBasicBlock
;
50 friend class VPInterleavedAccessInfo
;
51 friend class VPSlotTracker
;
52 friend class VPRecipeBase
;
54 const unsigned char SubclassID
; ///< Subclass identifier (for isa/dyn_cast).
56 SmallVector
<VPUser
*, 1> Users
;
59 // Hold the underlying Value, if any, attached to this VPValue.
62 /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the
63 /// VPValue is not defined by any recipe modeled in VPlan.
66 VPValue(const unsigned char SC
, Value
*UV
= nullptr, VPDef
*Def
= nullptr);
68 // DESIGN PRINCIPLE: Access to the underlying IR must be strictly limited to
69 // the front-end and back-end of VPlan so that the middle-end is as
70 // independent as possible of the underlying IR. We grant access to the
71 // underlying IR using friendship. In that way, we should be able to use VPlan
72 // for multiple underlying IRs (Polly?) by providing a new VPlan front-end,
73 // back-end and analysis information for the new IR.
76 /// Return the underlying Value attached to this VPValue.
77 Value
*getUnderlyingValue() const { return UnderlyingVal
; }
79 /// An enumeration for keeping track of the concrete subclass of VPValue that
80 /// are actually instantiated.
82 VPValueSC
, /// A generic VPValue, like live-in values or defined by a recipe
83 /// that defines multiple values.
84 VPVRecipeSC
/// A VPValue sub-class that is a VPRecipeBase.
87 /// Create a live-in VPValue.
88 VPValue(Value
*UV
= nullptr) : VPValue(VPValueSC
, UV
, nullptr) {}
89 /// Create a VPValue for a \p Def which is a subclass of VPValue.
90 VPValue(VPDef
*Def
, Value
*UV
= nullptr) : VPValue(VPVRecipeSC
, UV
, Def
) {}
91 /// Create a VPValue for a \p Def which defines multiple values.
92 VPValue(Value
*UV
, VPDef
*Def
) : VPValue(VPValueSC
, UV
, Def
) {}
93 VPValue(const VPValue
&) = delete;
94 VPValue
&operator=(const VPValue
&) = delete;
98 /// \return an ID for the concrete type of this object.
99 /// This is used to implement the classof checks. This should not be used
100 /// for any other purpose, as the values may change as LLVM evolves.
101 unsigned getVPValueID() const { return SubclassID
; }
103 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
104 void printAsOperand(raw_ostream
&OS
, VPSlotTracker
&Tracker
) const;
105 void print(raw_ostream
&OS
, VPSlotTracker
&Tracker
) const;
107 /// Dump the value to stderr (for debugging).
111 unsigned getNumUsers() const { return Users
.size(); }
112 void addUser(VPUser
&User
) { Users
.push_back(&User
); }
114 /// Remove a single \p User from the list of users.
115 void removeUser(VPUser
&User
) {
116 // The same user can be added multiple times, e.g. because the same VPValue
117 // is used twice by the same VPUser. Remove a single one.
118 auto *I
= find(Users
, &User
);
119 if (I
!= Users
.end())
123 typedef SmallVectorImpl
<VPUser
*>::iterator user_iterator
;
124 typedef SmallVectorImpl
<VPUser
*>::const_iterator const_user_iterator
;
125 typedef iterator_range
<user_iterator
> user_range
;
126 typedef iterator_range
<const_user_iterator
> const_user_range
;
128 user_iterator
user_begin() { return Users
.begin(); }
129 const_user_iterator
user_begin() const { return Users
.begin(); }
130 user_iterator
user_end() { return Users
.end(); }
131 const_user_iterator
user_end() const { return Users
.end(); }
132 user_range
users() { return user_range(user_begin(), user_end()); }
133 const_user_range
users() const {
134 return const_user_range(user_begin(), user_end());
137 /// Returns true if the value has more than one unique user.
138 bool hasMoreThanOneUniqueUser() const {
139 if (getNumUsers() == 0)
142 // Check if all users match the first user.
143 auto Current
= std::next(user_begin());
144 while (Current
!= user_end() && *user_begin() == *Current
)
146 return Current
!= user_end();
149 void replaceAllUsesWith(VPValue
*New
);
151 /// Go through the uses list for this VPValue and make each use point to \p
152 /// New if the callback ShouldReplace returns true for the given use specified
153 /// by a pair of (VPUser, the use index).
154 void replaceUsesWithIf(
156 llvm::function_ref
<bool(VPUser
&U
, unsigned Idx
)> ShouldReplace
);
158 /// Returns the recipe defining this VPValue or nullptr if it is not defined
159 /// by a recipe, i.e. is a live-in.
160 VPRecipeBase
*getDefiningRecipe();
161 const VPRecipeBase
*getDefiningRecipe() const;
163 /// Returns true if this VPValue is defined by a recipe.
164 bool hasDefiningRecipe() const { return getDefiningRecipe(); }
166 /// Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
167 bool isLiveIn() const { return !hasDefiningRecipe(); }
169 /// Returns the underlying IR value, if this VPValue is defined outside the
170 /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
172 Value
*getLiveInIRValue() {
174 "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
175 return getUnderlyingValue();
177 const Value
*getLiveInIRValue() const {
179 "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
180 return getUnderlyingValue();
183 /// Returns true if the VPValue is defined outside any loop region.
184 bool isDefinedOutsideLoopRegions() const;
186 // Set \p Val as the underlying Value of this VPValue.
187 void setUnderlyingValue(Value
*Val
) {
188 assert(!UnderlyingVal
&& "Underlying Value is already set.");
193 typedef DenseMap
<Value
*, VPValue
*> Value2VPValueTy
;
194 typedef DenseMap
<VPValue
*, Value
*> VPValue2ValueTy
;
196 raw_ostream
&operator<<(raw_ostream
&OS
, const VPValue
&V
);
198 /// This class augments VPValue with operands which provide the inverse def-use
199 /// edges from VPValue's users to their defs.
201 SmallVector
<VPValue
*, 2> Operands
;
204 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
205 /// Print the operands to \p O.
206 void printOperands(raw_ostream
&O
, VPSlotTracker
&SlotTracker
) const;
209 VPUser(ArrayRef
<VPValue
*> Operands
) {
210 for (VPValue
*Operand
: Operands
)
214 VPUser(std::initializer_list
<VPValue
*> Operands
)
215 : VPUser(ArrayRef
<VPValue
*>(Operands
)) {}
217 template <typename IterT
> VPUser(iterator_range
<IterT
> Operands
) {
218 for (VPValue
*Operand
: Operands
)
224 VPUser(const VPUser
&) = delete;
225 VPUser
&operator=(const VPUser
&) = delete;
227 for (VPValue
*Op
: operands())
228 Op
->removeUser(*this);
231 void addOperand(VPValue
*Operand
) {
232 Operands
.push_back(Operand
);
233 Operand
->addUser(*this);
236 unsigned getNumOperands() const { return Operands
.size(); }
237 inline VPValue
*getOperand(unsigned N
) const {
238 assert(N
< Operands
.size() && "Operand index out of bounds");
242 void setOperand(unsigned I
, VPValue
*New
) {
243 Operands
[I
]->removeUser(*this);
248 typedef SmallVectorImpl
<VPValue
*>::iterator operand_iterator
;
249 typedef SmallVectorImpl
<VPValue
*>::const_iterator const_operand_iterator
;
250 typedef iterator_range
<operand_iterator
> operand_range
;
251 typedef iterator_range
<const_operand_iterator
> const_operand_range
;
253 operand_iterator
op_begin() { return Operands
.begin(); }
254 const_operand_iterator
op_begin() const { return Operands
.begin(); }
255 operand_iterator
op_end() { return Operands
.end(); }
256 const_operand_iterator
op_end() const { return Operands
.end(); }
257 operand_range
operands() { return operand_range(op_begin(), op_end()); }
258 const_operand_range
operands() const {
259 return const_operand_range(op_begin(), op_end());
262 /// Returns true if the VPUser uses scalars of operand \p Op. Conservatively
263 /// returns if only first (scalar) lane is used, as default.
264 virtual bool usesScalars(const VPValue
*Op
) const {
265 assert(is_contained(operands(), Op
) &&
266 "Op must be an operand of the recipe");
267 return onlyFirstLaneUsed(Op
);
270 /// Returns true if the VPUser only uses the first lane of operand \p Op.
271 /// Conservatively returns false.
272 virtual bool onlyFirstLaneUsed(const VPValue
*Op
) const {
273 assert(is_contained(operands(), Op
) &&
274 "Op must be an operand of the recipe");
278 /// Returns true if the VPUser only uses the first part of operand \p Op.
279 /// Conservatively returns false.
280 virtual bool onlyFirstPartUsed(const VPValue
*Op
) const {
281 assert(is_contained(operands(), Op
) &&
282 "Op must be an operand of the recipe");
287 /// This class augments a recipe with a set of VPValues defined by the recipe.
288 /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
289 /// the VPValues it defines and is responsible for deleting its defined values.
290 /// Single-value VPDefs that also inherit from VPValue must make sure to inherit
291 /// from VPDef before VPValue.
293 friend class VPValue
;
295 /// Subclass identifier (for isa/dyn_cast).
296 const unsigned char SubclassID
;
298 /// The VPValues defined by this VPDef.
299 TinyPtrVector
<VPValue
*> DefinedValues
;
301 /// Add \p V as a defined value by this VPDef.
302 void addDefinedValue(VPValue
*V
) {
303 assert(V
->Def
== this &&
304 "can only add VPValue already linked with this VPDef");
305 DefinedValues
.push_back(V
);
308 /// Remove \p V from the values defined by this VPDef. \p V must be a defined
309 /// value of this VPDef.
310 void removeDefinedValue(VPValue
*V
) {
311 assert(V
->Def
== this && "can only remove VPValue linked with this VPDef");
312 assert(is_contained(DefinedValues
, V
) &&
313 "VPValue to remove must be in DefinedValues");
314 llvm::erase(DefinedValues
, V
);
319 /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
320 /// that is actually instantiated. Values of this enumeration are kept in the
321 /// SubclassID field of the VPRecipeBase objects. They are used for concrete
322 /// type identification.
323 using VPRecipeTy
= enum {
336 VPReverseVectorPointerSC
,
338 VPWidenCanonicalIVSC
,
351 // START: Phi-like recipes. Need to be kept together.
354 // START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
355 // VPHeaderPHIRecipe need to be kept together.
357 VPActiveLaneMaskPHISC
,
359 VPFirstOrderRecurrencePHISC
,
360 VPWidenIntOrFpInductionSC
,
361 VPWidenPointerInductionSC
,
364 // END: SubclassID for recipes that inherit VPHeaderPHIRecipe
365 // END: Phi-like recipes
366 VPFirstPHISC
= VPWidenPHISC
,
367 VPFirstHeaderPHISC
= VPCanonicalIVPHISC
,
368 VPLastHeaderPHISC
= VPReductionPHISC
,
369 VPLastPHISC
= VPReductionPHISC
,
372 VPDef(const unsigned char SC
) : SubclassID(SC
) {}
375 for (VPValue
*D
: make_early_inc_range(DefinedValues
)) {
376 assert(D
->Def
== this &&
377 "all defined VPValues should point to the containing VPDef");
378 assert(D
->getNumUsers() == 0 &&
379 "all defined VPValues should have no more users");
385 /// Returns the only VPValue defined by the VPDef. Can only be called for
386 /// VPDefs with a single defined value.
387 VPValue
*getVPSingleValue() {
388 assert(DefinedValues
.size() == 1 && "must have exactly one defined value");
389 assert(DefinedValues
[0] && "defined value must be non-null");
390 return DefinedValues
[0];
392 const VPValue
*getVPSingleValue() const {
393 assert(DefinedValues
.size() == 1 && "must have exactly one defined value");
394 assert(DefinedValues
[0] && "defined value must be non-null");
395 return DefinedValues
[0];
398 /// Returns the VPValue with index \p I defined by the VPDef.
399 VPValue
*getVPValue(unsigned I
) {
400 assert(DefinedValues
[I
] && "defined value must be non-null");
401 return DefinedValues
[I
];
403 const VPValue
*getVPValue(unsigned I
) const {
404 assert(DefinedValues
[I
] && "defined value must be non-null");
405 return DefinedValues
[I
];
408 /// Returns an ArrayRef of the values defined by the VPDef.
409 ArrayRef
<VPValue
*> definedValues() { return DefinedValues
; }
410 /// Returns an ArrayRef of the values defined by the VPDef.
411 ArrayRef
<VPValue
*> definedValues() const { return DefinedValues
; }
413 /// Returns the number of values defined by the VPDef.
414 unsigned getNumDefinedValues() const { return DefinedValues
.size(); }
416 /// \return an ID for the concrete type of this object.
417 /// This is used to implement the classof checks. This should not be used
418 /// for any other purpose, as the values may change as LLVM evolves.
419 unsigned getVPDefID() const { return SubclassID
; }
421 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
422 /// Dump the VPDef to stderr (for debugging).
425 /// Each concrete VPDef prints itself.
426 virtual void print(raw_ostream
&O
, const Twine
&Indent
,
427 VPSlotTracker
&SlotTracker
) const = 0;
434 /// This class can be used to assign names to VPValues. For VPValues without
435 /// underlying value, assign consecutive numbers and use those as names (wrapped
436 /// in vp<>). Otherwise, use the name from the underlying value (wrapped in
437 /// ir<>), appending a .V version number if there are multiple uses of the same
438 /// name. Allows querying names for VPValues for printing, similar to the
439 /// ModuleSlotTracker for IR values.
440 class VPSlotTracker
{
441 /// Keep track of versioned names assigned to VPValues with underlying IR
443 DenseMap
<const VPValue
*, std::string
> VPValue2Name
;
444 /// Keep track of the next number to use to version the base name.
445 StringMap
<unsigned> BaseName2Version
;
447 /// Number to assign to the next VPValue without underlying value.
448 unsigned NextSlot
= 0;
450 void assignName(const VPValue
*V
);
451 void assignNames(const VPlan
&Plan
);
452 void assignNames(const VPBasicBlock
*VPBB
);
455 VPSlotTracker(const VPlan
*Plan
= nullptr) {
460 /// Returns the name assigned to \p V, if there is one, otherwise try to
461 /// construct one from the underlying value, if there's one; else return
463 std::string
getOrCreateName(const VPValue
*V
) const;
468 #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H