Skip to content

Commit 4247eaa

Browse files
committed
Remove initial and backedge recipes, expand out to regular VPInstructions + splat and step vector recipes
1 parent 3f1a181 commit 4247eaa

31 files changed

+444
-594
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,14 @@ class VPBuilder {
257257
FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags()));
258258
}
259259

260+
VPSplatRecipe *createSplat(VPValue *Val) {
261+
return tryInsertInstruction(new VPSplatRecipe(Val));
262+
}
263+
264+
VPStepVectorRecipe *createStepVector(Type *Ty) {
265+
return tryInsertInstruction(new VPStepVectorRecipe(Ty));
266+
}
267+
260268
//===--------------------------------------------------------------------===//
261269
// RAII helpers.
262270
//===--------------------------------------------------------------------===//

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 70 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
16361704
class 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-
23352293
class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
23362294
public VPUnrollPartAccessor<3> {
23372295
const InductionDescriptor &IndDesc;

llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,14 @@ Type *VPTypeAnalysis::inferScalarType(const VPValue *V) {
223223
return inferScalarType(R->getStartValue());
224224
})
225225
.Case<VPWidenIntOrFpInductionRecipe, VPDerivedIVRecipe,
226-
VPWidenIntOrFpInductionInitialRecipe,
227-
VPWidenIntOrFpInductionBackedgeRecipe>(
226+
VPStepVectorRecipe>(
228227
[](const auto *R) { return R->getScalarType(); })
229228
.Case<VPReductionRecipe, VPPredInstPHIRecipe, VPWidenPHIRecipe,
230229
VPScalarIVStepsRecipe, VPWidenGEPRecipe, VPVectorPointerRecipe,
231-
VPReverseVectorPointerRecipe, VPWidenCanonicalIVRecipe>(
232-
[this](const VPRecipeBase *R) {
233-
return inferScalarType(R->getOperand(0));
234-
})
230+
VPReverseVectorPointerRecipe, VPWidenCanonicalIVRecipe,
231+
VPSplatRecipe>([this](const VPRecipeBase *R) {
232+
return inferScalarType(R->getOperand(0));
233+
})
235234
.Case<VPBlendRecipe, VPInstruction, VPWidenRecipe, VPWidenEVLRecipe,
236235
VPReplicateRecipe, VPWidenCallRecipe, VPWidenMemoryRecipe,
237236
VPWidenSelectRecipe>(

0 commit comments

Comments
 (0)