@@ -1089,6 +1089,62 @@ class VPIRInstruction : public VPRecipeBase {
1089
1089
void extractLastLaneOfOperand (VPBuilder &Builder);
1090
1090
};
1091
1091
1092
+ // / Helper type to provide functions to access incoming values and blocks for
1093
+ // / phi-like recipes. RecipeTy must be a sub-class of VPRecipeBase.
1094
+ template <typename RecipeTy> class VPPhiAccessors {
1095
+ // / Return a VPRecipeBase* to the current object.
1096
+ const VPRecipeBase *getAsRecipe () const {
1097
+ return static_cast <const RecipeTy *>(this );
1098
+ }
1099
+
1100
+ public:
1101
+ // / Returns the \p I th incoming VPValue.
1102
+ VPValue *getIncomingValue (unsigned I) const {
1103
+ return getAsRecipe ()->getOperand (I);
1104
+ }
1105
+
1106
+ // / Returns an interator range over the incoming values
1107
+ VPUser::const_operand_range incoming_values () const {
1108
+ return getAsRecipe ()->operands ();
1109
+ }
1110
+
1111
+ // / Returns the \p I th incoming block.
1112
+ const VPBasicBlock *getIncomingBlock (unsigned Idx) const ;
1113
+
1114
+ using const_incoming_block_iterator =
1115
+ mapped_iterator<detail::index_iterator,
1116
+ std::function<const VPBasicBlock *(size_t )>>;
1117
+ using const_incoming_blocks_range =
1118
+ iterator_range<const_incoming_block_iterator>;
1119
+
1120
+ const_incoming_block_iterator incoming_block_begin () const {
1121
+ return const_incoming_block_iterator (
1122
+ detail::index_iterator (0 ),
1123
+ [this ](size_t Idx) { return getIncomingBlock (Idx); });
1124
+ }
1125
+ const_incoming_block_iterator incoming_block_end () const {
1126
+ return const_incoming_block_iterator (
1127
+ detail::index_iterator (getAsRecipe ()->getVPDefID () ==
1128
+ VPDef::VPWidenIntOrFpInductionSC
1129
+ ? 2
1130
+ : getAsRecipe ()->getNumOperands ()),
1131
+ [this ](size_t Idx) { return getIncomingBlock (Idx); });
1132
+ }
1133
+
1134
+ // / Returns an iterator range over the incoming blocks.
1135
+ const_incoming_blocks_range incoming_blocks () const {
1136
+ return make_range (incoming_block_begin (), incoming_block_end ());
1137
+ }
1138
+
1139
+ // / Returns an iterator range over pairs of incoming values and corrsponding
1140
+ // / incoming blocks.
1141
+ detail::zippy<llvm::detail::zip_shortest, VPUser::const_operand_range,
1142
+ const_incoming_blocks_range>
1143
+ incoming_values_and_blocks () const {
1144
+ return zip (incoming_values (), incoming_blocks ());
1145
+ }
1146
+ };
1147
+
1092
1148
// / An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use
1093
1149
// / cast/dyn_cast/isa and execute() implementation.
1094
1150
struct VPIRPhi : public VPIRInstruction {
@@ -1947,7 +2003,8 @@ class VPScalarPHIRecipe : public VPHeaderPHIRecipe {
1947
2003
// / recipe is placed in an entry block to a (non-replicate) region, it must have
1948
2004
// / exactly 2 incoming values, the first from the predecessor of the region and
1949
2005
// / the second from the exiting block of the region.
1950
- class VPWidenPHIRecipe : public VPSingleDefRecipe {
2006
+ class VPWidenPHIRecipe : public VPSingleDefRecipe ,
2007
+ public VPPhiAccessors<VPWidenPHIRecipe> {
1951
2008
// / Name to use for the generated IR instruction for the widened phi.
1952
2009
std::string Name;
1953
2010
@@ -1978,12 +2035,6 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe {
1978
2035
void print (raw_ostream &O, const Twine &Indent,
1979
2036
VPSlotTracker &SlotTracker) const override ;
1980
2037
#endif
1981
-
1982
- // / Returns the \p I th incoming VPBasicBlock.
1983
- VPBasicBlock *getIncomingBlock (unsigned I);
1984
-
1985
- // / Returns the \p I th incoming VPValue.
1986
- VPValue *getIncomingValue (unsigned I) { return getOperand (I); }
1987
2038
};
1988
2039
1989
2040
// / A recipe for handling first-order recurrence phis. The start value is the
0 commit comments