@@ -1135,7 +1135,9 @@ class VPPhiAccessors {
11351135 const VPBasicBlock *getIncomingBlock (unsigned Idx) const ;
11361136
11371137 // / Returns the number of incoming values, also number of incoming blocks.
1138- unsigned getNumIncoming () const { return getAsRecipe ()->getNumOperands (); }
1138+ virtual unsigned getNumIncoming () const {
1139+ return getAsRecipe ()->getNumOperands ();
1140+ }
11391141
11401142#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
11411143 // / Print the recipe.
@@ -1234,7 +1236,7 @@ class VPIRInstruction : public VPRecipeBase {
12341236// / cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
12351237// / allowed, and it is used to add a new incoming value for the single
12361238// / predecessor VPBB.
1237- struct VPIRPhi : public VPIRInstruction {
1239+ struct VPIRPhi : public VPIRInstruction , public VPPhiAccessors {
12381240 VPIRPhi (PHINode &PN) : VPIRInstruction(PN) {}
12391241
12401242 static inline bool classof (const VPRecipeBase *U) {
@@ -1251,6 +1253,9 @@ struct VPIRPhi : public VPIRInstruction {
12511253 void print (raw_ostream &O, const Twine &Indent,
12521254 VPSlotTracker &SlotTracker) const override ;
12531255#endif
1256+
1257+ protected:
1258+ const VPRecipeBase *getAsRecipe () const override { return this ; }
12541259};
12551260
12561261// / Helper to manage IR metadata for recipes. It filters out metadata that
@@ -1785,13 +1790,15 @@ class VPVectorPointerRecipe : public VPRecipeWithIRFlags,
17851790// / * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
17861791// / pointer induction. Produces either a vector PHI per-part or scalar values
17871792// / per-lane based on the canonical induction.
1788- class VPHeaderPHIRecipe : public VPSingleDefRecipe {
1793+ class VPHeaderPHIRecipe : public VPSingleDefRecipe , public VPPhiAccessors {
17891794protected:
17901795 VPHeaderPHIRecipe (unsigned char VPDefID, Instruction *UnderlyingInstr,
17911796 VPValue *Start, DebugLoc DL = {})
17921797 : VPSingleDefRecipe(VPDefID, ArrayRef<VPValue *>({Start}), UnderlyingInstr, DL) {
17931798 }
17941799
1800+ const VPRecipeBase *getAsRecipe () const override { return this ; }
1801+
17951802public:
17961803 ~VPHeaderPHIRecipe () override = default ;
17971804
@@ -1980,6 +1987,11 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {
19801987 return isUnrolled () ? getOperand (getNumOperands () - 2 ) : nullptr ;
19811988 }
19821989
1990+ // / Returns the number of incoming values, also number of incoming blocks.
1991+ // / Note that at the moment, VPWidenIntOrFpInductionRecipes only have a single
1992+ // / incoming value, its start value.
1993+ unsigned getNumIncoming () const override { return 1 ; }
1994+
19831995 // / Returns the first defined value as TruncInst, if it is one or nullptr
19841996 // / otherwise.
19851997 TruncInst *getTruncInst () { return Trunc; }
@@ -3283,6 +3295,46 @@ class VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
32833295 }
32843296};
32853297
3298+ // / Casting from VPRecipeBase -> VPPhiAccessors is supported for all recipe
3299+ // / types implementing VPPhiAccessors. Used by isa<> & co.
3300+ template <> struct CastIsPossible <VPPhiAccessors, const VPRecipeBase *> {
3301+ static inline bool isPossible (const VPRecipeBase *f) {
3302+ // TODO: include VPPredInstPHIRecipe too, once it implements VPPhiAccessors.
3303+ return isa<VPIRPhi, VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPhi>(f);
3304+ }
3305+ };
3306+ // / Support casting from VPRecipeBase -> VPPhiAccessors, by down-casting to the
3307+ // / recipe types implementing VPPhiAccessors. Used by cast<>, dyn_cast<> & co.
3308+ template <>
3309+ struct CastInfo <VPPhiAccessors, const VPRecipeBase *>
3310+ : public CastIsPossible<VPPhiAccessors, const VPRecipeBase *> {
3311+
3312+ using Self = CastInfo<VPPhiAccessors, const VPRecipeBase *>;
3313+
3314+ // / doCast is used by cast<>.
3315+ static inline VPPhiAccessors *doCast (const VPRecipeBase *R) {
3316+ return const_cast <VPPhiAccessors *>([R]() -> const VPPhiAccessors * {
3317+ switch (R->getVPDefID ()) {
3318+ case VPDef::VPInstructionSC:
3319+ return cast<VPPhi>(R);
3320+ case VPDef::VPIRInstructionSC:
3321+ return cast<VPIRPhi>(R);
3322+ case VPDef::VPWidenPHISC:
3323+ return cast<VPWidenPHIRecipe>(R);
3324+ default :
3325+ return cast<VPHeaderPHIRecipe>(R);
3326+ }
3327+ }());
3328+ }
3329+
3330+ // / doCastIfPossible is used by dyn_cast<>.
3331+ static inline VPPhiAccessors *doCastIfPossible (const VPRecipeBase *f) {
3332+ if (!Self::isPossible (f))
3333+ return nullptr ;
3334+ return doCast (f);
3335+ }
3336+ };
3337+
32863338// / VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
32873339// / holds a sequence of zero or more VPRecipe's each representing a sequence of
32883340// / output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
0 commit comments