1
0
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:
Florian Hahn 2020-09-23 14:44:31 +01:00
parent 2e5f4ba2ce
commit 64c733fe5d
4 changed files with 24 additions and 33 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
} }

View File

@ -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);