@@ -1632,6 +1632,74 @@ class VPScalarCastRecipe : public VPSingleDefRecipe {
16321632 }
16331633};
16341634
1635+ // / A for splatting a scalar value to a vector.
1636+ class VPSplatRecipe : public VPSingleDefRecipe {
1637+ public:
1638+ VPSplatRecipe (VPValue *Op) : VPSingleDefRecipe(VPDef::VPSplatSC, {Op}) {}
1639+
1640+ ~VPSplatRecipe () override = default ;
1641+
1642+ VPSplatRecipe *clone () override { return new VPSplatRecipe (getOperand (0 )); }
1643+
1644+ VP_CLASSOF_IMPL (VPDef::VPSplatSC)
1645+
1646+ void execute (VPTransformState &State) override ;
1647+
1648+ // / Return the cost of this VPSplatRecipe.
1649+ InstructionCost computeCost (ElementCount VF,
1650+ VPCostContext &Ctx) const override {
1651+ // TODO: Compute accurate cost after retiring the legacy cost model.
1652+ return 0 ;
1653+ }
1654+
1655+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1656+ void print (raw_ostream &O, const Twine &Indent,
1657+ VPSlotTracker &SlotTracker) const override ;
1658+ #endif
1659+
1660+ // / Returns true if the recipe only uses the first lane of operand \p Op.
1661+ bool onlyFirstLaneUsed (const VPValue *Op) const override {
1662+ assert (is_contained (operands (), Op) &&
1663+ " Op must be an operand of the recipe" );
1664+ return true ;
1665+ }
1666+ };
1667+
1668+ // / A recipe for generating a step vector.
1669+ class VPStepVectorRecipe : public VPSingleDefRecipe {
1670+ // / Scalar return type of the intrinsic.
1671+ Type *ScalarTy;
1672+
1673+ public:
1674+ VPStepVectorRecipe (Type *Ty)
1675+ : VPSingleDefRecipe(VPDef::VPStepVectorSC, {}), ScalarTy(Ty) {}
1676+
1677+ ~VPStepVectorRecipe () override = default ;
1678+
1679+ VPStepVectorRecipe *clone () override {
1680+ return new VPStepVectorRecipe (ScalarTy);
1681+ }
1682+
1683+ VP_CLASSOF_IMPL (VPDef::VPStepVectorSC)
1684+
1685+ void execute (VPTransformState &State) override ;
1686+
1687+ // / Return the cost of this VPStepVectorRecipe.
1688+ InstructionCost computeCost (ElementCount VF,
1689+ VPCostContext &Ctx) const override {
1690+ // TODO: Compute accurate cost after retiring the legacy cost model.
1691+ return 0 ;
1692+ }
1693+
1694+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1695+ void print (raw_ostream &O, const Twine &Indent,
1696+ VPSlotTracker &SlotTracker) const override ;
1697+ #endif
1698+
1699+ // / Return the scalar return type of the intrinsic.
1700+ Type *getScalarType () const { return ScalarTy; }
1701+ };
1702+
16351703// / A recipe for widening vector intrinsics.
16361704class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
16371705 // / ID of the vector intrinsic to widen.
@@ -2183,59 +2251,10 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
21832251 }
21842252
21852253 // / Returns the VPValue representing the value of this induction at
2186- // / the last unrolled part, if it exists. Returns nullptr if unrolling did not
2254+ // / the last unrolled part, if it exists. Returns itself if unrolling did not
21872255 // / take place.
21882256 VPValue *getLastUnrolledPartOperand () {
2189- return getNumOperands () == 5 ? getOperand (4 ) : nullptr ;
2190- }
2191- };
2192-
2193- // / A recipe to compute the initial value for a widened IV, expanded from
2194- // / VPWidenIntOrFpInductionRecipe.
2195- class VPWidenIntOrFpInductionInitialRecipe : public VPSingleDefRecipe {
2196- Instruction *IV;
2197- const InductionDescriptor &ID;
2198-
2199- public:
2200- VPWidenIntOrFpInductionInitialRecipe (Instruction *IV, VPValue *Start,
2201- VPValue *Step,
2202- const InductionDescriptor &ID)
2203- : VPSingleDefRecipe(VPDef::VPWidenIntOrFpInductionStartSC, {Start, Step}),
2204- IV (IV), ID(ID) {
2205- assert ((isa<PHINode>(IV) || isa<TruncInst>(IV)) &&
2206- " Expected either an induction phi-node or a truncate of it!" );
2207- }
2208-
2209- ~VPWidenIntOrFpInductionInitialRecipe () override = default ;
2210-
2211- VPWidenIntOrFpInductionInitialRecipe *clone () override {
2212- return new VPWidenIntOrFpInductionInitialRecipe (IV, getOperand (0 ),
2213- getOperand (1 ), ID);
2214- }
2215-
2216- VP_CLASSOF_IMPL (VPDef::VPWidenIntOrFpInductionStartSC)
2217-
2218- void execute (VPTransformState &State) override ;
2219-
2220- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2221- // / Print the recipe.
2222- void print (raw_ostream &O, const Twine &Indent,
2223- VPSlotTracker &SlotTracker) const override ;
2224- #endif
2225-
2226- VPValue *getStartValue () { return getOperand (0 ); }
2227- const VPValue *getStartValue () const { return getOperand (0 ); }
2228-
2229- VPValue *getStepValue () { return getOperand (1 ); }
2230- const VPValue *getStepValue () const { return getOperand (1 ); }
2231-
2232- // / Returns the scalar type of the induction.
2233- Type *getScalarType () const { return IV->getType (); }
2234-
2235- bool onlyFirstLaneUsed (const VPValue *Op) const override {
2236- assert (is_contained (operands (), Op) &&
2237- " Op must be an operand of the recipe" );
2238- return true ;
2257+ return getNumOperands () == 5 ? getOperand (4 ) : this ;
22392258 }
22402259};
22412260
@@ -2271,67 +2290,6 @@ class VPWidenIntOrFpInductionPHIRecipe : public VPHeaderPHIRecipe {
22712290#endif
22722291};
22732292
2274- // / A recipe to compute the backedge value for a widened IV, expanded from
2275- // / VPWidenIntOrFpInductionRecipe.
2276- class VPWidenIntOrFpInductionBackedgeRecipe : public VPSingleDefRecipe {
2277- Instruction *IV;
2278- const InductionDescriptor &ID;
2279-
2280- public:
2281- VPWidenIntOrFpInductionBackedgeRecipe (Instruction *IV, VPValue *Step,
2282- VPValue *VF, VPValue *Prev,
2283- VPValue *SplatVF,
2284- const InductionDescriptor &ID)
2285- : VPSingleDefRecipe(VPDef::VPWidenIntOrFpInductionSC, {Step, VF, Prev}),
2286- IV (IV), ID(ID) {
2287- assert ((isa<PHINode>(IV) || isa<TruncInst>(IV)) &&
2288- " Expected either an induction phi-node or a truncate of it!" );
2289- if (SplatVF)
2290- addOperand (SplatVF);
2291- }
2292-
2293- ~VPWidenIntOrFpInductionBackedgeRecipe () override = default ;
2294-
2295- VPWidenIntOrFpInductionBackedgeRecipe *clone () override {
2296- return new VPWidenIntOrFpInductionBackedgeRecipe (
2297- IV, getOperand (0 ), getOperand (1 ), getOperand (2 ), getOperand (3 ), ID);
2298- }
2299-
2300- VP_CLASSOF_IMPL (VPDef::VPWidenIntOrFpInductionIncSC)
2301-
2302- void execute (VPTransformState &State) override ;
2303-
2304- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2305- // / Print the recipe.
2306- void print (raw_ostream &O, const Twine &Indent,
2307- VPSlotTracker &SlotTracker) const override ;
2308- #endif
2309-
2310- VPValue *getStepValue () { return getOperand (0 ); }
2311- const VPValue *getStepValue () const { return getOperand (0 ); }
2312-
2313- VPValue *getVFValue () { return getOperand (1 ); }
2314- const VPValue *getVFValue () const { return getOperand (1 ); }
2315-
2316- VPValue *getPrevValue () { return getOperand (2 ); }
2317- const VPValue *getPrevValue () const { return getOperand (2 ); }
2318-
2319- VPValue *getSplatVFValue () {
2320- // If the recipe has been unrolled (4 operands), return the VPValue for the
2321- // induction increment.
2322- return getNumOperands () == 4 ? getOperand (3 ) : nullptr ;
2323- }
2324-
2325- // / Returns the scalar type of the induction.
2326- Type *getScalarType () const { return IV->getType (); }
2327-
2328- bool onlyFirstLaneUsed (const VPValue *Op) const override {
2329- assert (is_contained (operands (), Op) &&
2330- " Op must be an operand of the recipe" );
2331- return Op == getOperand (0 ) || Op == getOperand (1 );
2332- }
2333- };
2334-
23352293class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe ,
23362294 public VPUnrollPartAccessor<3 > {
23372295 const InductionDescriptor &IndDesc;
0 commit comments