@@ -1135,7 +1135,9 @@ class VPPhiAccessors {
1135
1135
const VPBasicBlock *getIncomingBlock (unsigned Idx) const ;
1136
1136
1137
1137
// / 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
+ }
1139
1141
1140
1142
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1141
1143
// / Print the recipe.
@@ -1234,7 +1236,7 @@ class VPIRInstruction : public VPRecipeBase {
1234
1236
// / cast/dyn_cast/isa and execute() implementation. A single VPValue operand is
1235
1237
// / allowed, and it is used to add a new incoming value for the single
1236
1238
// / predecessor VPBB.
1237
- struct VPIRPhi : public VPIRInstruction {
1239
+ struct VPIRPhi : public VPIRInstruction , public VPPhiAccessors {
1238
1240
VPIRPhi (PHINode &PN) : VPIRInstruction(PN) {}
1239
1241
1240
1242
static inline bool classof (const VPRecipeBase *U) {
@@ -1251,6 +1253,9 @@ struct VPIRPhi : public VPIRInstruction {
1251
1253
void print (raw_ostream &O, const Twine &Indent,
1252
1254
VPSlotTracker &SlotTracker) const override ;
1253
1255
#endif
1256
+
1257
+ protected:
1258
+ const VPRecipeBase *getAsRecipe () const override { return this ; }
1254
1259
};
1255
1260
1256
1261
// / Helper to manage IR metadata for recipes. It filters out metadata that
@@ -1785,13 +1790,15 @@ class VPVectorPointerRecipe : public VPRecipeWithIRFlags,
1785
1790
// / * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
1786
1791
// / pointer induction. Produces either a vector PHI per-part or scalar values
1787
1792
// / per-lane based on the canonical induction.
1788
- class VPHeaderPHIRecipe : public VPSingleDefRecipe {
1793
+ class VPHeaderPHIRecipe : public VPSingleDefRecipe , public VPPhiAccessors {
1789
1794
protected:
1790
1795
VPHeaderPHIRecipe (unsigned char VPDefID, Instruction *UnderlyingInstr,
1791
1796
VPValue *Start, DebugLoc DL = {})
1792
1797
: VPSingleDefRecipe(VPDefID, ArrayRef<VPValue *>({Start}), UnderlyingInstr, DL) {
1793
1798
}
1794
1799
1800
+ const VPRecipeBase *getAsRecipe () const override { return this ; }
1801
+
1795
1802
public:
1796
1803
~VPHeaderPHIRecipe () override = default ;
1797
1804
@@ -1980,6 +1987,11 @@ class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {
1980
1987
return isUnrolled () ? getOperand (getNumOperands () - 2 ) : nullptr ;
1981
1988
}
1982
1989
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
+
1983
1995
// / Returns the first defined value as TruncInst, if it is one or nullptr
1984
1996
// / otherwise.
1985
1997
TruncInst *getTruncInst () { return Trunc; }
@@ -3283,6 +3295,46 @@ class VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
3283
3295
}
3284
3296
};
3285
3297
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
+
3286
3338
// / VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
3287
3339
// / holds a sequence of zero or more VPRecipe's each representing a sequence of
3288
3340
// / output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
0 commit comments