Skip to content

Commit 95e509a

Browse files
authored
[VPlan] Add VPWidenInduction recipe as common base class (NFC). (llvm#120008)
This helps to simplify some existing code and new code (llvm#112145) PR: llvm#120008
1 parent 978de2d commit 95e509a

File tree

5 files changed

+74
-68
lines changed

5 files changed

+74
-68
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7941,10 +7941,8 @@ BasicBlock *EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton(
79417941
SmallPtrSet<PHINode *, 4> WideIVs;
79427942
for (VPRecipeBase &H :
79437943
EPI.EpiloguePlan.getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
7944-
if (auto *WideIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&H))
7944+
if (auto *WideIV = dyn_cast<VPWidenInductionRecipe>(&H))
79457945
WideIVs.insert(WideIV->getPHINode());
7946-
else if (auto *PtrIV = dyn_cast<VPWidenPointerInductionRecipe>(&H))
7947-
WideIVs.insert(cast<PHINode>(PtrIV->getUnderlyingValue()));
79487946
}
79497947
createInductionResumeVPValues(ExpandedSCEVs, nullptr, &WideIVs);
79507948

@@ -10131,13 +10129,7 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1013110129
} else {
1013210130
// Retrieve the induction resume values for wide inductions from
1013310131
// their original phi nodes in the scalar loop.
10134-
PHINode *IndPhi = nullptr;
10135-
if (auto *Ind = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
10136-
IndPhi = cast<PHINode>(Ind->getUnderlyingValue());
10137-
} else {
10138-
auto *WidenInd = cast<VPWidenIntOrFpInductionRecipe>(&R);
10139-
IndPhi = WidenInd->getPHINode();
10140-
}
10132+
PHINode *IndPhi = cast<VPWidenInductionRecipe>(&R)->getPHINode();
1014110133
// Hook up to the PHINode generated by a ResumePhi recipe of main
1014210134
// loop VPlan, which feeds the scalar loop.
1014310135
ResumeV = IndPhi->getIncomingValueForBlock(L->getLoopPreheader());

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ void VPlan::execute(VPTransformState *State) {
10471047
if (isa<VPWidenPHIRecipe>(&R))
10481048
continue;
10491049

1050-
if (isa<VPWidenPointerInductionRecipe, VPWidenIntOrFpInductionRecipe>(&R)) {
1050+
if (isa<VPWidenInductionRecipe>(&R)) {
10511051
PHINode *Phi = nullptr;
10521052
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
10531053
Phi = cast<PHINode>(State->get(R.getVPSingleValue()));

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 61 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,38 +2099,81 @@ class VPHeaderPHIRecipe : public VPSingleDefRecipe {
20992099
}
21002100
};
21012101

2102+
/// Base class for widened induction (VPWidenIntOrFpInductionRecipe and
2103+
/// VPWidenPointerInductionRecipe), providing shared functionality, including
2104+
/// retrieving the step value, induction descriptor and original phi node.
2105+
class VPWidenInductionRecipe : public VPHeaderPHIRecipe {
2106+
const InductionDescriptor &IndDesc;
2107+
2108+
public:
2109+
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start,
2110+
VPValue *Step, const InductionDescriptor &IndDesc,
2111+
DebugLoc DL)
2112+
: VPHeaderPHIRecipe(Kind, IV, Start, DL), IndDesc(IndDesc) {
2113+
addOperand(Step);
2114+
}
2115+
2116+
static inline bool classof(const VPRecipeBase *R) {
2117+
return R->getVPDefID() == VPDef::VPWidenIntOrFpInductionSC ||
2118+
R->getVPDefID() == VPDef::VPWidenPointerInductionSC;
2119+
}
2120+
2121+
virtual void execute(VPTransformState &State) override = 0;
2122+
2123+
/// Returns the step value of the induction.
2124+
VPValue *getStepValue() { return getOperand(1); }
2125+
const VPValue *getStepValue() const { return getOperand(1); }
2126+
2127+
PHINode *getPHINode() const { return cast<PHINode>(getUnderlyingValue()); }
2128+
2129+
/// Returns the induction descriptor for the recipe.
2130+
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2131+
2132+
VPValue *getBackedgeValue() override {
2133+
// TODO: All operands of base recipe must exist and be at same index in
2134+
// derived recipe.
2135+
llvm_unreachable(
2136+
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2137+
}
2138+
2139+
VPRecipeBase &getBackedgeRecipe() override {
2140+
// TODO: All operands of base recipe must exist and be at same index in
2141+
// derived recipe.
2142+
llvm_unreachable(
2143+
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2144+
}
2145+
};
2146+
21022147
/// A recipe for handling phi nodes of integer and floating-point inductions,
21032148
/// producing their vector values.
2104-
class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
2105-
PHINode *IV;
2149+
class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {
21062150
TruncInst *Trunc;
2107-
const InductionDescriptor &IndDesc;
21082151

21092152
public:
21102153
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
21112154
VPValue *VF, const InductionDescriptor &IndDesc,
21122155
DebugLoc DL)
2113-
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start, DL),
2114-
IV(IV), Trunc(nullptr), IndDesc(IndDesc) {
2115-
addOperand(Step);
2156+
: VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2157+
Step, IndDesc, DL),
2158+
Trunc(nullptr) {
21162159
addOperand(VF);
21172160
}
21182161

21192162
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
21202163
VPValue *VF, const InductionDescriptor &IndDesc,
21212164
TruncInst *Trunc, DebugLoc DL)
2122-
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start, DL),
2123-
IV(IV), Trunc(Trunc), IndDesc(IndDesc) {
2124-
addOperand(Step);
2165+
: VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2166+
Step, IndDesc, DL),
2167+
Trunc(Trunc) {
21252168
addOperand(VF);
21262169
}
21272170

21282171
~VPWidenIntOrFpInductionRecipe() override = default;
21292172

21302173
VPWidenIntOrFpInductionRecipe *clone() override {
2131-
return new VPWidenIntOrFpInductionRecipe(IV, getStartValue(),
2132-
getStepValue(), getVFValue(),
2133-
IndDesc, Trunc, getDebugLoc());
2174+
return new VPWidenIntOrFpInductionRecipe(
2175+
getPHINode(), getStartValue(), getStepValue(), getVFValue(),
2176+
getInductionDescriptor(), Trunc, getDebugLoc());
21342177
}
21352178

21362179
VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)
@@ -2145,24 +2188,6 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
21452188
VPSlotTracker &SlotTracker) const override;
21462189
#endif
21472190

2148-
VPValue *getBackedgeValue() override {
2149-
// TODO: All operands of base recipe must exist and be at same index in
2150-
// derived recipe.
2151-
llvm_unreachable(
2152-
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2153-
}
2154-
2155-
VPRecipeBase &getBackedgeRecipe() override {
2156-
// TODO: All operands of base recipe must exist and be at same index in
2157-
// derived recipe.
2158-
llvm_unreachable(
2159-
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2160-
}
2161-
2162-
/// Returns the step value of the induction.
2163-
VPValue *getStepValue() { return getOperand(1); }
2164-
const VPValue *getStepValue() const { return getOperand(1); }
2165-
21662191
VPValue *getVFValue() { return getOperand(2); }
21672192
const VPValue *getVFValue() const { return getOperand(2); }
21682193

@@ -2177,19 +2202,14 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
21772202
TruncInst *getTruncInst() { return Trunc; }
21782203
const TruncInst *getTruncInst() const { return Trunc; }
21792204

2180-
PHINode *getPHINode() { return IV; }
2181-
2182-
/// Returns the induction descriptor for the recipe.
2183-
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2184-
21852205
/// Returns true if the induction is canonical, i.e. starting at 0 and
21862206
/// incremented by UF * VF (= the original IV is incremented by 1) and has the
21872207
/// same type as the canonical induction.
21882208
bool isCanonical() const;
21892209

21902210
/// Returns the scalar type of the induction.
21912211
Type *getScalarType() const {
2192-
return Trunc ? Trunc->getType() : IV->getType();
2212+
return Trunc ? Trunc->getType() : getPHINode()->getType();
21932213
}
21942214

21952215
/// Returns the VPValue representing the value of this induction at
@@ -2200,10 +2220,8 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
22002220
}
22012221
};
22022222

2203-
class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
2223+
class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe,
22042224
public VPUnrollPartAccessor<3> {
2205-
const InductionDescriptor &IndDesc;
2206-
22072225
bool IsScalarAfterVectorization;
22082226

22092227
public:
@@ -2212,19 +2230,16 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
22122230
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step,
22132231
const InductionDescriptor &IndDesc,
22142232
bool IsScalarAfterVectorization, DebugLoc DL)
2215-
: VPHeaderPHIRecipe(VPDef::VPWidenPointerInductionSC, Phi, nullptr, DL),
2216-
IndDesc(IndDesc),
2217-
IsScalarAfterVectorization(IsScalarAfterVectorization) {
2218-
addOperand(Start);
2219-
addOperand(Step);
2220-
}
2233+
: VPWidenInductionRecipe(VPDef::VPWidenPointerInductionSC, Phi, Start,
2234+
Step, IndDesc, DL),
2235+
IsScalarAfterVectorization(IsScalarAfterVectorization) {}
22212236

22222237
~VPWidenPointerInductionRecipe() override = default;
22232238

22242239
VPWidenPointerInductionRecipe *clone() override {
22252240
return new VPWidenPointerInductionRecipe(
22262241
cast<PHINode>(getUnderlyingInstr()), getOperand(0), getOperand(1),
2227-
IndDesc, IsScalarAfterVectorization, getDebugLoc());
2242+
getInductionDescriptor(), IsScalarAfterVectorization, getDebugLoc());
22282243
}
22292244

22302245
VP_CLASSOF_IMPL(VPDef::VPWidenPointerInductionSC)
@@ -2235,9 +2250,6 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
22352250
/// Returns true if only scalar values will be generated.
22362251
bool onlyScalarsGenerated(bool IsScalable);
22372252

2238-
/// Returns the induction descriptor for the recipe.
2239-
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2240-
22412253
/// Returns the VPValue representing the value of this induction at
22422254
/// the first unrolled part, if it exists. Returns itself if unrolling did not
22432255
/// take place.

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,12 +1655,13 @@ void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
16551655
const InductionDescriptor &ID = getInductionDescriptor();
16561656
TruncInst *Trunc = getTruncInst();
16571657
IRBuilderBase &Builder = State.Builder;
1658-
assert(IV->getType() == ID.getStartValue()->getType() && "Types must match");
1658+
assert(getPHINode()->getType() == ID.getStartValue()->getType() &&
1659+
"Types must match");
16591660
assert(State.VF.isVector() && "must have vector VF");
16601661

16611662
// The value from the original loop to which we are mapping the new induction
16621663
// variable.
1663-
Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : IV;
1664+
Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : getPHINode();
16641665

16651666
// Fast-math-flags propagate from the original induction instruction.
16661667
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
@@ -3144,7 +3145,8 @@ bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(bool IsScalable) {
31443145
}
31453146

31463147
void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
3147-
assert(IndDesc.getKind() == InductionDescriptor::IK_PtrInduction &&
3148+
assert(getInductionDescriptor().getKind() ==
3149+
InductionDescriptor::IK_PtrInduction &&
31483150
"Not a pointer induction according to InductionDescriptor!");
31493151
assert(cast<PHINode>(getUnderlyingInstr())->getType()->isPointerTy() &&
31503152
"Unexpected type.");
@@ -3180,8 +3182,8 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
31803182

31813183
// A pointer induction, performed by using a gep
31823184
BasicBlock::iterator InductionLoc = State.Builder.GetInsertPoint();
3183-
Value *ScalarStepValue = State.get(getOperand(1), VPLane(0));
3184-
Type *PhiType = State.TypeAnalysis.inferScalarType(getOperand(1));
3185+
Value *ScalarStepValue = State.get(getStepValue(), VPLane(0));
3186+
Type *PhiType = State.TypeAnalysis.inferScalarType(getStepValue());
31853187
Value *RuntimeVF = getRuntimeVF(State.Builder, PhiType, State.VF);
31863188
// Add induction update using an incorrect block temporarily. The phi node
31873189
// will be fixed after VPlan execution. Note that at this point the latch
@@ -3234,7 +3236,7 @@ void VPWidenPointerInductionRecipe::print(raw_ostream &O, const Twine &Indent,
32343236
O << " = WIDEN-POINTER-INDUCTION ";
32353237
getStartValue()->printAsOperand(O, SlotTracker);
32363238
O << ", ";
3237-
getOperand(1)->printAsOperand(O, SlotTracker);
3239+
getStepValue()->printAsOperand(O, SlotTracker);
32383240
if (getNumOperands() == 4) {
32393241
O << ", ";
32403242
getOperand(2)->printAsOperand(O, SlotTracker);

llvm/test/Transforms/LoopVectorize/vplan-printing.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,10 +653,10 @@ define void @print_expand_scev(i64 %y, ptr %ptr) {
653653
; CHECK-NEXT: <x1> vector loop: {
654654
; CHECK-NEXT: vector.body:
655655
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
656-
; CHECK-NEXT: ir<%v2> = WIDEN-INDUCTION ir<0>, vp<[[EXP_SCEV]]>, vp<[[VF]]> (truncated to i8)
656+
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, vp<[[EXP_SCEV]]>, vp<[[VF]]> (truncated to i8)
657657
; CHECK-NEXT: vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * vp<[[EXP_SCEV]]>
658658
; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, vp<[[EXP_SCEV]]>
659-
; CHECK-NEXT: WIDEN ir<%v3> = add nuw ir<%v2>, ir<1>
659+
; CHECK-NEXT: WIDEN ir<%v3> = add nuw ir<%iv>, ir<1>
660660
; CHECK-NEXT: REPLICATE ir<%gep> = getelementptr inbounds ir<%ptr>, vp<[[STEPS]]>
661661
; CHECK-NEXT: REPLICATE store ir<%v3>, ir<%gep>
662662
; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>

0 commit comments

Comments
 (0)