Skip to content

Commit 816dba4

Browse files
committed
[VPlan] Keep start value in VPWidenIntOrFpInductionRecipe (NFC).
This patch updates VPWidenIntOrFpInductionRecipe to hold the start value for the induction variable. This makes the start value explicit and allows for adjusting the start value for a VPlan. The flexibility will be used in further patches. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D92129
1 parent aa280c9 commit 816dba4

File tree

4 files changed

+43
-24
lines changed

4 files changed

+43
-24
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ class InnerLoopVectorizer {
526526
/// Widen an integer or floating-point induction variable \p IV. If \p Trunc
527527
/// is provided, the integer induction variable will first be truncated to
528528
/// the corresponding type.
529-
void widenIntOrFpInduction(PHINode *IV, TruncInst *Trunc = nullptr);
529+
void widenIntOrFpInduction(PHINode *IV, Value *Start,
530+
TruncInst *Trunc = nullptr);
530531

531532
/// getOrCreateVectorValue and getOrCreateScalarValue coordinate to generate a
532533
/// vector or scalar value on-demand if one is not yet available. When
@@ -666,7 +667,8 @@ class InnerLoopVectorizer {
666667
/// truncate instruction, instead of widening the original IV, we widen a
667668
/// version of the IV truncated to \p EntryVal's type.
668669
void createVectorIntOrFpInductionPHI(const InductionDescriptor &II,
669-
Value *Step, Instruction *EntryVal);
670+
Value *Step, Value *Start,
671+
Instruction *EntryVal);
670672

671673
/// Returns true if an instruction \p I should be scalarized instead of
672674
/// vectorized for the chosen vectorization factor.
@@ -2005,10 +2007,10 @@ Value *InnerLoopVectorizer::getBroadcastInstrs(Value *V) {
20052007
}
20062008

20072009
void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
2008-
const InductionDescriptor &II, Value *Step, Instruction *EntryVal) {
2010+
const InductionDescriptor &II, Value *Step, Value *Start,
2011+
Instruction *EntryVal) {
20092012
assert((isa<PHINode>(EntryVal) || isa<TruncInst>(EntryVal)) &&
20102013
"Expected either an induction phi-node or a truncate of it!");
2011-
Value *Start = II.getStartValue();
20122014

20132015
// Construct the initial value of the vector IV in the vector loop preheader
20142016
auto CurrIP = Builder.saveIP();
@@ -2126,7 +2128,8 @@ void InnerLoopVectorizer::recordVectorLoopValueForInductionCast(
21262128
VectorLoopValueMap.setVectorValue(CastInst, Part, VectorLoopVal);
21272129
}
21282130

2129-
void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, TruncInst *Trunc) {
2131+
void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, Value *Start,
2132+
TruncInst *Trunc) {
21302133
assert((IV->getType()->isIntegerTy() || IV != OldInduction) &&
21312134
"Primary induction variable must have an integer type");
21322135

@@ -2208,15 +2211,15 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, TruncInst *Trunc) {
22082211
// least one user in the loop that is not widened.
22092212
auto NeedsScalarIV = needsScalarInduction(EntryVal);
22102213
if (!NeedsScalarIV) {
2211-
createVectorIntOrFpInductionPHI(ID, Step, EntryVal);
2214+
createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
22122215
return;
22132216
}
22142217

22152218
// Try to create a new independent vector induction variable. If we can't
22162219
// create the phi node, we will splat the scalar induction variable in each
22172220
// loop iteration.
22182221
if (!shouldScalarizeInstruction(EntryVal)) {
2219-
createVectorIntOrFpInductionPHI(ID, Step, EntryVal);
2222+
createVectorIntOrFpInductionPHI(ID, Step, Start, EntryVal);
22202223
Value *ScalarIV = CreateScalarIV(Step);
22212224
// Create scalar steps that can be used by instructions we will later
22222225
// scalarize. Note that the addition of the scalar steps will not increase
@@ -8061,20 +8064,22 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, VFRange &Range,
80618064
}
80628065

80638066
VPWidenIntOrFpInductionRecipe *
8064-
VPRecipeBuilder::tryToOptimizeInductionPHI(PHINode *Phi) const {
8067+
VPRecipeBuilder::tryToOptimizeInductionPHI(PHINode *Phi, VPlan &Plan) const {
80658068
// Check if this is an integer or fp induction. If so, build the recipe that
80668069
// produces its scalar and vector values.
80678070
InductionDescriptor II = Legal->getInductionVars().lookup(Phi);
80688071
if (II.getKind() == InductionDescriptor::IK_IntInduction ||
8069-
II.getKind() == InductionDescriptor::IK_FpInduction)
8070-
return new VPWidenIntOrFpInductionRecipe(Phi);
8072+
II.getKind() == InductionDescriptor::IK_FpInduction) {
8073+
VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
8074+
return new VPWidenIntOrFpInductionRecipe(Phi, Start);
8075+
}
80718076

80728077
return nullptr;
80738078
}
80748079

80758080
VPWidenIntOrFpInductionRecipe *
8076-
VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I,
8077-
VFRange &Range) const {
8081+
VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
8082+
VPlan &Plan) const {
80788083
// Optimize the special case where the source is a constant integer
80798084
// induction variable. Notice that we can only optimize the 'trunc' case
80808085
// because (a) FP conversions lose precision, (b) sext/zext may wrap, and
@@ -8090,9 +8095,14 @@ VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I,
80908095
};
80918096

80928097
if (LoopVectorizationPlanner::getDecisionAndClampRange(
8093-
isOptimizableIVTruncate(I), Range))
8098+
isOptimizableIVTruncate(I), Range)) {
8099+
8100+
InductionDescriptor II =
8101+
Legal->getInductionVars().lookup(cast<PHINode>(I->getOperand(0)));
8102+
VPValue *Start = Plan.getOrAddVPValue(II.getStartValue());
80948103
return new VPWidenIntOrFpInductionRecipe(cast<PHINode>(I->getOperand(0)),
8095-
I);
8104+
Start, I);
8105+
}
80968106
return nullptr;
80978107
}
80988108

@@ -8304,13 +8314,13 @@ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(Instruction *Instr,
83048314
if (auto Phi = dyn_cast<PHINode>(Instr)) {
83058315
if (Phi->getParent() != OrigLoop->getHeader())
83068316
return tryToBlend(Phi, Plan);
8307-
if ((Recipe = tryToOptimizeInductionPHI(Phi)))
8317+
if ((Recipe = tryToOptimizeInductionPHI(Phi, *Plan)))
83088318
return Recipe;
83098319
return new VPWidenPHIRecipe(Phi);
83108320
}
83118321

8312-
if (isa<TruncInst>(Instr) &&
8313-
(Recipe = tryToOptimizeInductionTruncate(cast<TruncInst>(Instr), Range)))
8322+
if (isa<TruncInst>(Instr) && (Recipe = tryToOptimizeInductionTruncate(
8323+
cast<TruncInst>(Instr), Range, *Plan)))
83148324
return Recipe;
83158325

83168326
if (!shouldWiden(Instr, Range))
@@ -8705,7 +8715,8 @@ void VPWidenGEPRecipe::execute(VPTransformState &State) {
87058715

87068716
void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
87078717
assert(!State.Instance && "Int or FP induction being replicated.");
8708-
State.ILV->widenIntOrFpInduction(IV, Trunc);
8718+
State.ILV->widenIntOrFpInduction(IV, getStartValue()->getLiveInIRValue(),
8719+
Trunc);
87098720
}
87108721

87118722
void VPWidenPHIRecipe::execute(VPTransformState &State) {

llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ class VPRecipeBuilder {
6666

6767
/// Check if an induction recipe should be constructed for \I. If so build and
6868
/// return it. If not, return null.
69-
VPWidenIntOrFpInductionRecipe *tryToOptimizeInductionPHI(PHINode *Phi) const;
69+
VPWidenIntOrFpInductionRecipe *tryToOptimizeInductionPHI(PHINode *Phi,
70+
VPlan &Plan) const;
7071

7172
/// Optimize the special case where the operand of \p I is a constant integer
7273
/// induction variable.
7374
VPWidenIntOrFpInductionRecipe *
74-
tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range) const;
75+
tryToOptimizeInductionTruncate(TruncInst *I, VFRange &Range,
76+
VPlan &Plan) const;
7577

7678
/// Handle non-loop phi nodes. Currently all such phi nodes are turned into
7779
/// a sequence of select instructions as the vectorizer currently performs

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -932,13 +932,15 @@ class VPWidenGEPRecipe : public VPRecipeBase,
932932

933933
/// A recipe for handling phi nodes of integer and floating-point inductions,
934934
/// producing their vector and scalar values.
935-
class VPWidenIntOrFpInductionRecipe : public VPRecipeBase {
935+
class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPUser {
936936
PHINode *IV;
937937
TruncInst *Trunc;
938938

939939
public:
940-
VPWidenIntOrFpInductionRecipe(PHINode *IV, TruncInst *Trunc = nullptr)
941-
: VPRecipeBase(VPWidenIntOrFpInductionSC), IV(IV), Trunc(Trunc) {
940+
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start,
941+
TruncInst *Trunc = nullptr)
942+
: VPRecipeBase(VPWidenIntOrFpInductionSC), VPUser({Start}), IV(IV),
943+
Trunc(Trunc) {
942944
if (Trunc)
943945
new VPValue(Trunc, this);
944946
else
@@ -958,6 +960,9 @@ class VPWidenIntOrFpInductionRecipe : public VPRecipeBase {
958960
/// Print the recipe.
959961
void print(raw_ostream &O, const Twine &Indent,
960962
VPSlotTracker &SlotTracker) const override;
963+
964+
/// Returns the start value of the induction.
965+
VPValue *getStartValue() { return getOperand(0); }
961966
};
962967

963968
/// A recipe for handling all phi nodes except for integer and FP inductions.

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
6868
InductionDescriptor II = Inductions.lookup(Phi);
6969
if (II.getKind() == InductionDescriptor::IK_IntInduction ||
7070
II.getKind() == InductionDescriptor::IK_FpInduction) {
71-
NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi);
71+
VPValue *Start = Plan->getOrAddVPValue(II.getStartValue());
72+
NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start);
7273
} else
7374
NewRecipe = new VPWidenPHIRecipe(Phi);
7475
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {

0 commit comments

Comments
 (0)