mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[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
This commit is contained in:
parent
2e5f4ba2ce
commit
64c733fe5d
@ -151,10 +151,8 @@ The low-level design of VPlan comprises of the following classes.
|
|||||||
VPUser, but no operands.
|
VPUser, but no operands.
|
||||||
|
|
||||||
:VPUser:
|
:VPUser:
|
||||||
A VPValue representing a general vertex in the def-use graph of VPlan. It has
|
A VPUser represents an entity that uses a number of VPValues as operands.
|
||||||
operands which are of type VPValue. When instantiated, it represents a
|
VPUser is similar in some aspects to LLVM's User class.
|
||||||
live-out Instruction that exists outside VPlan. VPUser is similar in some
|
|
||||||
aspects to LLVM's User class.
|
|
||||||
|
|
||||||
:VPInstruction:
|
:VPInstruction:
|
||||||
A VPInstruction is both a VPRecipe and a VPUser. It models a single
|
A VPInstruction is both a VPRecipe and a VPUser. It models a single
|
||||||
|
@ -682,7 +682,7 @@ public:
|
|||||||
/// While as any Recipe it may generate a sequence of IR instructions when
|
/// While as any Recipe it may generate a sequence of IR instructions when
|
||||||
/// executed, these instructions would always form a single-def expression as
|
/// executed, these instructions would always form a single-def expression as
|
||||||
/// the VPInstruction is also a single def-use vertex.
|
/// the VPInstruction is also a single def-use vertex.
|
||||||
class VPInstruction : public VPUser, public VPRecipeBase {
|
class VPInstruction : public VPUser, public VPValue, public VPRecipeBase {
|
||||||
friend class VPlanSlp;
|
friend class VPlanSlp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -712,7 +712,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
|
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
|
||||||
: VPUser(VPValue::VPInstructionSC, Operands),
|
: VPUser(Operands), VPValue(VPValue::VPInstructionSC),
|
||||||
VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {}
|
VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {}
|
||||||
|
|
||||||
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands)
|
VPInstruction(unsigned Opcode, std::initializer_list<VPValue *> Operands)
|
||||||
|
@ -161,7 +161,8 @@ static SmallVector<VPValue *, 4> getOperands(ArrayRef<VPValue *> Values,
|
|||||||
unsigned OperandIndex) {
|
unsigned OperandIndex) {
|
||||||
SmallVector<VPValue *, 4> Operands;
|
SmallVector<VPValue *, 4> Operands;
|
||||||
for (VPValue *V : Values) {
|
for (VPValue *V : Values) {
|
||||||
auto *U = cast<VPUser>(V);
|
// Currently we only support VPInstructions.
|
||||||
|
auto *U = cast<VPInstruction>(V);
|
||||||
Operands.push_back(U->getOperand(OperandIndex));
|
Operands.push_back(U->getOperand(OperandIndex));
|
||||||
}
|
}
|
||||||
return Operands;
|
return Operands;
|
||||||
@ -222,18 +223,20 @@ static bool areConsecutiveOrMatch(VPInstruction *A, VPInstruction *B,
|
|||||||
/// Traverses and compares operands of V1 and V2 to MaxLevel.
|
/// Traverses and compares operands of V1 and V2 to MaxLevel.
|
||||||
static unsigned getLAScore(VPValue *V1, VPValue *V2, unsigned MaxLevel,
|
static unsigned getLAScore(VPValue *V1, VPValue *V2, unsigned MaxLevel,
|
||||||
VPInterleavedAccessInfo &IAI) {
|
VPInterleavedAccessInfo &IAI) {
|
||||||
if (!isa<VPInstruction>(V1) || !isa<VPInstruction>(V2))
|
auto *I1 = dyn_cast<VPInstruction>(V1);
|
||||||
|
auto *I2 = dyn_cast<VPInstruction>(V2);
|
||||||
|
// Currently we only support VPInstructions.
|
||||||
|
if (!I1 || !I2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (MaxLevel == 0)
|
if (MaxLevel == 0)
|
||||||
return (unsigned)areConsecutiveOrMatch(cast<VPInstruction>(V1),
|
return (unsigned)areConsecutiveOrMatch(I1, I2, IAI);
|
||||||
cast<VPInstruction>(V2), IAI);
|
|
||||||
|
|
||||||
unsigned Score = 0;
|
unsigned Score = 0;
|
||||||
for (unsigned I = 0, EV1 = cast<VPUser>(V1)->getNumOperands(); I < EV1; ++I)
|
for (unsigned I = 0, EV1 = I1->getNumOperands(); I < EV1; ++I)
|
||||||
for (unsigned J = 0, EV2 = cast<VPUser>(V2)->getNumOperands(); J < EV2; ++J)
|
for (unsigned J = 0, EV2 = I2->getNumOperands(); J < EV2; ++J)
|
||||||
Score += getLAScore(cast<VPUser>(V1)->getOperand(I),
|
Score +=
|
||||||
cast<VPUser>(V2)->getOperand(J), MaxLevel - 1, IAI);
|
getLAScore(I1->getOperand(I), I2->getOperand(J), MaxLevel - 1, IAI);
|
||||||
return Score;
|
return Score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
/// This file contains the declarations of the entities induced by Vectorization
|
/// This file contains the declarations of the entities induced by Vectorization
|
||||||
/// Plans, e.g. the instructions the VPlan intends to generate if executed.
|
/// Plans, e.g. the instructions the VPlan intends to generate if executed.
|
||||||
/// VPlan models the following entities:
|
/// VPlan models the following entities:
|
||||||
/// VPValue
|
/// VPValue VPUser
|
||||||
/// |-- VPUser
|
/// | |
|
||||||
/// | |-- VPInstruction
|
/// VPInstruction
|
||||||
/// These are documented in docs/VectorizationPlan.rst.
|
/// These are documented in docs/VectorizationPlan.rst.
|
||||||
///
|
///
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -76,7 +76,7 @@ public:
|
|||||||
/// are actually instantiated. Values of this enumeration are kept in the
|
/// are actually instantiated. Values of this enumeration are kept in the
|
||||||
/// SubclassID field of the VPValue objects. They are used for concrete
|
/// SubclassID field of the VPValue objects. They are used for concrete
|
||||||
/// type identification.
|
/// type identification.
|
||||||
enum { VPValueSC, VPUserSC, VPInstructionSC };
|
enum { VPValueSC, VPInstructionSC };
|
||||||
|
|
||||||
VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV) {}
|
VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV) {}
|
||||||
VPValue(const VPValue &) = delete;
|
VPValue(const VPValue &) = delete;
|
||||||
@ -132,23 +132,19 @@ raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
|
|||||||
|
|
||||||
/// This class augments VPValue with operands which provide the inverse def-use
|
/// This class augments VPValue with operands which provide the inverse def-use
|
||||||
/// edges from VPValue's users to their defs.
|
/// edges from VPValue's users to their defs.
|
||||||
class VPUser : public VPValue {
|
class VPUser {
|
||||||
SmallVector<VPValue *, 2> Operands;
|
SmallVector<VPValue *, 2> Operands;
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
VPUser(const unsigned char SC) : VPValue(SC) {}
|
VPUser() {}
|
||||||
VPUser(const unsigned char SC, ArrayRef<VPValue *> Operands) : VPValue(SC) {
|
VPUser(ArrayRef<VPValue *> Operands) {
|
||||||
for (VPValue *Operand : Operands)
|
for (VPValue *Operand : Operands)
|
||||||
addOperand(Operand);
|
addOperand(Operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
VPUser() : VPValue(VPValue::VPUserSC) {}
|
|
||||||
VPUser(ArrayRef<VPValue *> Operands) : VPUser(VPValue::VPUserSC, Operands) {}
|
|
||||||
VPUser(std::initializer_list<VPValue *> Operands)
|
VPUser(std::initializer_list<VPValue *> Operands)
|
||||||
: VPUser(ArrayRef<VPValue *>(Operands)) {}
|
: VPUser(ArrayRef<VPValue *>(Operands)) {}
|
||||||
template <typename IterT>
|
template <typename IterT> VPUser(iterator_range<IterT> Operands) {
|
||||||
VPUser(iterator_range<IterT> Operands) : VPValue(VPValue::VPUserSC) {
|
|
||||||
for (VPValue *Operand : Operands)
|
for (VPValue *Operand : Operands)
|
||||||
addOperand(Operand);
|
addOperand(Operand);
|
||||||
}
|
}
|
||||||
@ -156,12 +152,6 @@ public:
|
|||||||
VPUser(const VPUser &) = delete;
|
VPUser(const VPUser &) = delete;
|
||||||
VPUser &operator=(const VPUser &) = delete;
|
VPUser &operator=(const VPUser &) = delete;
|
||||||
|
|
||||||
/// Method to support type inquiry through isa, cast, and dyn_cast.
|
|
||||||
static inline bool classof(const VPValue *V) {
|
|
||||||
return V->getVPValueID() >= VPUserSC &&
|
|
||||||
V->getVPValueID() <= VPInstructionSC;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addOperand(VPValue *Operand) {
|
void addOperand(VPValue *Operand) {
|
||||||
Operands.push_back(Operand);
|
Operands.push_back(Operand);
|
||||||
Operand->addUser(*this);
|
Operand->addUser(*this);
|
||||||
|
Loading…
Reference in New Issue
Block a user