Skip to content

Commit 31923f6

Browse files
committed
[VPlan] Disconnect VPValue and VPUser.
This refactors VPuser to not inherit from VPValue to facilitate introducing operations that introduce multiple VPValues (e.g. VPInterleaveRecipe). Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D84679
1 parent 9691806 commit 31923f6

File tree

4 files changed

+24
-33
lines changed

4 files changed

+24
-33
lines changed

llvm/docs/Proposals/VectorizationPlan.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,8 @@ The low-level design of VPlan comprises of the following classes.
151151
VPUser, but no operands.
152152

153153
:VPUser:
154-
A VPValue representing a general vertex in the def-use graph of VPlan. It has
155-
operands which are of type VPValue. When instantiated, it represents a
156-
live-out Instruction that exists outside VPlan. VPUser is similar in some
157-
aspects to LLVM's User class.
154+
A VPUser represents an entity that uses a number of VPValues as operands.
155+
VPUser is similar in some aspects to LLVM's User class.
158156

159157
:VPInstruction:
160158
A VPInstruction is both a VPRecipe and a VPUser. It models a single

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock> {
682682
/// While as any Recipe it may generate a sequence of IR instructions when
683683
/// executed, these instructions would always form a single-def expression as
684684
/// the VPInstruction is also a single def-use vertex.
685-
class VPInstruction : public VPUser, public VPRecipeBase {
685+
class VPInstruction : public VPUser, public VPValue, public VPRecipeBase {
686686
friend class VPlanSlp;
687687

688688
public:
@@ -712,7 +712,7 @@ class VPInstruction : public VPUser, public VPRecipeBase {
712712

713713
public:
714714
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
715-
: VPUser(VPValue::VPInstructionSC, Operands),
715+
: VPUser(Operands), VPValue(VPValue::VPInstructionSC),
716716
VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {}
717717

718718
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands)

llvm/lib/Transforms/Vectorize/VPlanSLP.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ static SmallVector<VPValue *, 4> getOperands(ArrayRef<VPValue *> Values,
161161
unsigned OperandIndex) {
162162
SmallVector<VPValue *, 4> Operands;
163163
for (VPValue *V : Values) {
164-
auto *U = cast<VPUser>(V);
164+
// Currently we only support VPInstructions.
165+
auto *U = cast<VPInstruction>(V);
165166
Operands.push_back(U->getOperand(OperandIndex));
166167
}
167168
return Operands;
@@ -222,18 +223,20 @@ static bool areConsecutiveOrMatch(VPInstruction *A, VPInstruction *B,
222223
/// Traverses and compares operands of V1 and V2 to MaxLevel.
223224
static unsigned getLAScore(VPValue *V1, VPValue *V2, unsigned MaxLevel,
224225
VPInterleavedAccessInfo &IAI) {
225-
if (!isa<VPInstruction>(V1) || !isa<VPInstruction>(V2))
226+
auto *I1 = dyn_cast<VPInstruction>(V1);
227+
auto *I2 = dyn_cast<VPInstruction>(V2);
228+
// Currently we only support VPInstructions.
229+
if (!I1 || !I2)
226230
return 0;
227231

228232
if (MaxLevel == 0)
229-
return (unsigned)areConsecutiveOrMatch(cast<VPInstruction>(V1),
230-
cast<VPInstruction>(V2), IAI);
233+
return (unsigned)areConsecutiveOrMatch(I1, I2, IAI);
231234

232235
unsigned Score = 0;
233-
for (unsigned I = 0, EV1 = cast<VPUser>(V1)->getNumOperands(); I < EV1; ++I)
234-
for (unsigned J = 0, EV2 = cast<VPUser>(V2)->getNumOperands(); J < EV2; ++J)
235-
Score += getLAScore(cast<VPUser>(V1)->getOperand(I),
236-
cast<VPUser>(V2)->getOperand(J), MaxLevel - 1, IAI);
236+
for (unsigned I = 0, EV1 = I1->getNumOperands(); I < EV1; ++I)
237+
for (unsigned J = 0, EV2 = I2->getNumOperands(); J < EV2; ++J)
238+
Score +=
239+
getLAScore(I1->getOperand(I), I2->getOperand(J), MaxLevel - 1, IAI);
237240
return Score;
238241
}
239242

llvm/lib/Transforms/Vectorize/VPlanValue.h

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
/// This file contains the declarations of the entities induced by Vectorization
1111
/// Plans, e.g. the instructions the VPlan intends to generate if executed.
1212
/// VPlan models the following entities:
13-
/// VPValue
14-
/// |-- VPUser
15-
/// | |-- VPInstruction
13+
/// VPValue VPUser
14+
/// | |
15+
/// VPInstruction
1616
/// These are documented in docs/VectorizationPlan.rst.
1717
///
1818
//===----------------------------------------------------------------------===//
@@ -76,7 +76,7 @@ class VPValue {
7676
/// are actually instantiated. Values of this enumeration are kept in the
7777
/// SubclassID field of the VPValue objects. They are used for concrete
7878
/// type identification.
79-
enum { VPValueSC, VPUserSC, VPInstructionSC };
79+
enum { VPValueSC, VPInstructionSC };
8080

8181
VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV) {}
8282
VPValue(const VPValue &) = delete;
@@ -132,36 +132,26 @@ raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
132132

133133
/// This class augments VPValue with operands which provide the inverse def-use
134134
/// edges from VPValue's users to their defs.
135-
class VPUser : public VPValue {
135+
class VPUser {
136136
SmallVector<VPValue *, 2> Operands;
137137

138-
protected:
139-
VPUser(const unsigned char SC) : VPValue(SC) {}
140-
VPUser(const unsigned char SC, ArrayRef<VPValue *> Operands) : VPValue(SC) {
138+
public:
139+
VPUser() {}
140+
VPUser(ArrayRef<VPValue *> Operands) {
141141
for (VPValue *Operand : Operands)
142142
addOperand(Operand);
143143
}
144144

145-
public:
146-
VPUser() : VPValue(VPValue::VPUserSC) {}
147-
VPUser(ArrayRef<VPValue *> Operands) : VPUser(VPValue::VPUserSC, Operands) {}
148145
VPUser(std::initializer_list<VPValue *> Operands)
149146
: VPUser(ArrayRef<VPValue *>(Operands)) {}
150-
template <typename IterT>
151-
VPUser(iterator_range<IterT> Operands) : VPValue(VPValue::VPUserSC) {
147+
template <typename IterT> VPUser(iterator_range<IterT> Operands) {
152148
for (VPValue *Operand : Operands)
153149
addOperand(Operand);
154150
}
155151

156152
VPUser(const VPUser &) = delete;
157153
VPUser &operator=(const VPUser &) = delete;
158154

159-
/// Method to support type inquiry through isa, cast, and dyn_cast.
160-
static inline bool classof(const VPValue *V) {
161-
return V->getVPValueID() >= VPUserSC &&
162-
V->getVPValueID() <= VPInstructionSC;
163-
}
164-
165155
void addOperand(VPValue *Operand) {
166156
Operands.push_back(Operand);
167157
Operand->addUser(*this);

0 commit comments

Comments
 (0)