diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -620,18 +620,18 @@ public VPUser { friend VPBasicBlock; friend class VPBlockUtils; - + friend class VPUser; /// Each VPRecipe belongs to a single VPBasicBlock. VPBasicBlock *Parent = nullptr; public: VPRecipeBase(const unsigned char SC, ArrayRef Operands) - : VPDef(SC), VPUser(Operands) {} + : VPDef(SC), VPUser(Operands, VPUser::VPUserID::Recipe) {} template VPRecipeBase(const unsigned char SC, iterator_range Operands) - : VPDef(SC), VPUser(Operands) {} + : VPDef(SC), VPUser(Operands, VPUser::VPUserID::Recipe) {} virtual ~VPRecipeBase() = default; /// \return the VPBasicBlock which this VPRecipe belongs to. @@ -683,6 +683,10 @@ return true; } + static inline bool classof(const VPUser *U) { + return U->getVPUserID() == VPUser::VPUserID::Recipe; + } + /// Returns true if the recipe may have side-effects. bool mayHaveSideEffects() const; }; diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h --- a/llvm/lib/Transforms/Vectorize/VPlanValue.h +++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h @@ -191,8 +191,22 @@ /// This class augments VPValue with operands which provide the inverse def-use /// edges from VPValue's users to their defs. class VPUser { + friend class VPRecipeBase; + SmallVector Operands; + /// Subclass identifier (for isa/dyn_cast). + enum class VPUserID { + Recipe, + // TODO: Currently VPUsers are used in VPBlockBase, but in the future the + // only VPUsers should either be recipes or live-outs. + Other + }; + + VPUserID ID; + + VPUserID getVPUserID() const { return ID; } + protected: #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print the operands to \p O. @@ -200,15 +214,19 @@ #endif public: - VPUser() {} - VPUser(ArrayRef Operands) { + VPUser() : ID(VPUserID::Recipe) {} + VPUser(ArrayRef Operands, VPUserID ID = VPUserID::Other) : ID(ID) { for (VPValue *Operand : Operands) addOperand(Operand); } - VPUser(std::initializer_list Operands) - : VPUser(ArrayRef(Operands)) {} - template VPUser(iterator_range Operands) { + VPUser(std::initializer_list Operands, + VPUserID ID = VPUserID::Other) + : VPUser(ArrayRef(Operands), ID) {} + + template + VPUser(iterator_range Operands, VPUserID ID = VPUserID::Other) + : ID(ID) { for (VPValue *Operand : Operands) addOperand(Operand); } @@ -260,6 +278,8 @@ static inline bool classof(const VPDef *Recipe); }; +static_assert(sizeof(VPUser) <= 48, "size of VPUser changed"); + /// This class augments a recipe with a set of VPValues defined by the recipe. /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns /// the VPValues it defines and is responsible for deleting its defined values.