@@ -1088,6 +1088,62 @@ class VPIRInstruction : public VPRecipeBase {
1088
1088
void extractLastLaneOfOperand (VPBuilder &Builder);
1089
1089
};
1090
1090
1091
+ // / Helper type to provide functions to access incoming values and blocks for
1092
+ // / phi-like recipes. RecipeTy must be a sub-class of VPRecipeBase.
1093
+ template <typename RecipeTy> class VPPhiAccessors {
1094
+ // / Return a VPRecipeBase* to the current object.
1095
+ const VPRecipeBase *getAsRecipe () const {
1096
+ return static_cast <const RecipeTy *>(this );
1097
+ }
1098
+
1099
+ public:
1100
+ // / Returns the \p I th incoming VPValue.
1101
+ VPValue *getIncomingValue (unsigned I) const {
1102
+ return getAsRecipe ()->getOperand (I);
1103
+ }
1104
+
1105
+ // / Returns an interator range over the incoming values
1106
+ VPUser::const_operand_range incoming_values () const {
1107
+ return getAsRecipe ()->operands ();
1108
+ }
1109
+
1110
+ // / Returns the \p I th incoming block.
1111
+ const VPBasicBlock *getIncomingBlock (unsigned Idx) const ;
1112
+
1113
+ using const_incoming_block_iterator =
1114
+ mapped_iterator<detail::index_iterator,
1115
+ std::function<const VPBasicBlock *(size_t )>>;
1116
+ using const_incoming_blocks_range =
1117
+ iterator_range<const_incoming_block_iterator>;
1118
+
1119
+ const_incoming_block_iterator incoming_block_begin () const {
1120
+ return const_incoming_block_iterator (
1121
+ detail::index_iterator (0 ),
1122
+ [this ](size_t Idx) { return getIncomingBlock (Idx); });
1123
+ }
1124
+ const_incoming_block_iterator incoming_block_end () const {
1125
+ return const_incoming_block_iterator (
1126
+ detail::index_iterator (getAsRecipe ()->getVPDefID () ==
1127
+ VPDef::VPWidenIntOrFpInductionSC
1128
+ ? 2
1129
+ : getAsRecipe ()->getNumOperands ()),
1130
+ [this ](size_t Idx) { return getIncomingBlock (Idx); });
1131
+ }
1132
+
1133
+ // / Returns an iterator range over the incoming blocks.
1134
+ const_incoming_blocks_range incoming_blocks () const {
1135
+ return make_range (incoming_block_begin (), incoming_block_end ());
1136
+ }
1137
+
1138
+ // / Returns an iterator range over pairs of incoming values and corrsponding
1139
+ // / incoming blocks.
1140
+ detail::zippy<llvm::detail::zip_shortest, VPUser::const_operand_range,
1141
+ const_incoming_blocks_range>
1142
+ incoming_values_and_blocks () const {
1143
+ return zip (incoming_values (), incoming_blocks ());
1144
+ }
1145
+ };
1146
+
1091
1147
// / An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
1092
1148
// / cast/dyn_cast/isa and execute() implementation.
1093
1149
struct VPIRPhi : public VPIRInstruction {
@@ -1968,7 +2024,8 @@ class VPScalarPHIRecipe : public VPHeaderPHIRecipe {
1968
2024
// / recipe is placed in an entry block to a (non-replicate) region, it must have
1969
2025
// / exactly 2 incoming values, the first from the predecessor of the region and
1970
2026
// / the second from the exiting block of the region.
1971
- class VPWidenPHIRecipe : public VPSingleDefRecipe {
2027
+ class VPWidenPHIRecipe : public VPSingleDefRecipe ,
2028
+ public VPPhiAccessors<VPWidenPHIRecipe> {
1972
2029
public:
1973
2030
// / Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
1974
2031
// / debug location \p DL.
@@ -1994,12 +2051,6 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe {
1994
2051
void print (raw_ostream &O, const Twine &Indent,
1995
2052
VPSlotTracker &SlotTracker) const override ;
1996
2053
#endif
1997
-
1998
- // / Returns the \p I th incoming VPBasicBlock.
1999
- VPBasicBlock *getIncomingBlock (unsigned I);
2000
-
2001
- // / Returns the \p I th incoming VPValue.
2002
- VPValue *getIncomingValue (unsigned I) { return getOperand (I); }
2003
2054
};
2004
2055
2005
2056
// / A recipe for handling first-order recurrence phis. The start value is the
0 commit comments