[VPlan] Remove uneeded NeedsVectorIV from VPWidenIntOrFpInduction.

After recent improvements, all instances of
VPWidenIntOrFpInductionRecipe should needs a vector IV and there's no
need for a separate field.
This commit is contained in:
Florian Hahn 2023-04-17 13:38:00 +01:00
parent 9d9046f06d
commit 4fc190351e
No known key found for this signature in database
GPG Key ID: 9E54DEA47A8F4434
3 changed files with 19 additions and 35 deletions

View File

@ -8277,22 +8277,11 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I,
/// Creates a VPWidenIntOrFpInductionRecpipe for \p Phi. If needed, it will also /// Creates a VPWidenIntOrFpInductionRecpipe for \p Phi. If needed, it will also
/// insert a recipe to expand the step for the induction recipe. /// insert a recipe to expand the step for the induction recipe.
static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes( static VPWidenIntOrFpInductionRecipe *
PHINode *Phi, Instruction *PhiOrTrunc, VPValue *Start, createWidenInductionRecipes(PHINode *Phi, Instruction *PhiOrTrunc,
const InductionDescriptor &IndDesc, LoopVectorizationCostModel &CM, VPValue *Start, const InductionDescriptor &IndDesc,
VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, VFRange &Range) { VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop,
// Returns true if an instruction \p I should be scalarized instead of VFRange &Range) {
// vectorized for the chosen vectorization factor.
auto ShouldScalarizeInstruction = [&CM](Instruction *I, ElementCount VF) {
return CM.isScalarAfterVectorization(I, VF) ||
CM.isProfitableToScalarize(I, VF);
};
bool NeedsScalarIVOnly = LoopVectorizationPlanner::getDecisionAndClampRange(
[&](ElementCount VF) {
return ShouldScalarizeInstruction(PhiOrTrunc, VF);
},
Range);
assert(IndDesc.getStartValue() == assert(IndDesc.getStartValue() ==
Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader())); Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader()));
assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) && assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
@ -8301,12 +8290,10 @@ static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes(
VPValue *Step = VPValue *Step =
vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep(), SE); vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep(), SE);
if (auto *TruncI = dyn_cast<TruncInst>(PhiOrTrunc)) { if (auto *TruncI = dyn_cast<TruncInst>(PhiOrTrunc)) {
return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI, return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI);
!NeedsScalarIVOnly);
} }
assert(isa<PHINode>(PhiOrTrunc) && "must be a phi node here"); assert(isa<PHINode>(PhiOrTrunc) && "must be a phi node here");
return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc);
!NeedsScalarIVOnly);
} }
VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI(
@ -8315,7 +8302,7 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI(
// Check if this is an integer or fp induction. If so, build the recipe that // Check if this is an integer or fp induction. If so, build the recipe that
// produces its scalar and vector values. // produces its scalar and vector values.
if (auto *II = Legal->getIntOrFpInductionDescriptor(Phi)) if (auto *II = Legal->getIntOrFpInductionDescriptor(Phi))
return createWidenInductionRecipes(Phi, Phi, Operands[0], *II, CM, Plan, return createWidenInductionRecipes(Phi, Phi, Operands[0], *II, Plan,
*PSE.getSE(), *OrigLoop, Range); *PSE.getSE(), *OrigLoop, Range);
// Check if this is pointer induction. If so, build the recipe for it. // Check if this is pointer induction. If so, build the recipe for it.
@ -8355,8 +8342,8 @@ VPWidenIntOrFpInductionRecipe *VPRecipeBuilder::tryToOptimizeInductionTruncate(
auto *Phi = cast<PHINode>(I->getOperand(0)); auto *Phi = cast<PHINode>(I->getOperand(0));
const InductionDescriptor &II = *Legal->getIntOrFpInductionDescriptor(Phi); const InductionDescriptor &II = *Legal->getIntOrFpInductionDescriptor(Phi);
VPValue *Start = Plan.getVPValueOrAddLiveIn(II.getStartValue()); VPValue *Start = Plan.getVPValueOrAddLiveIn(II.getStartValue());
return createWidenInductionRecipes(Phi, I, Start, II, CM, Plan, return createWidenInductionRecipes(Phi, I, Start, II, Plan, *PSE.getSE(),
*PSE.getSE(), *OrigLoop, Range); *OrigLoop, Range);
} }
return nullptr; return nullptr;
} }

View File

@ -1140,22 +1140,20 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
PHINode *IV; PHINode *IV;
TruncInst *Trunc; TruncInst *Trunc;
const InductionDescriptor &IndDesc; const InductionDescriptor &IndDesc;
bool NeedsVectorIV;
public: public:
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc, const InductionDescriptor &IndDesc)
bool NeedsVectorIV)
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start), IV(IV), : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start), IV(IV),
Trunc(nullptr), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { Trunc(nullptr), IndDesc(IndDesc) {
addOperand(Step); addOperand(Step);
} }
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc, const InductionDescriptor &IndDesc,
TruncInst *Trunc, bool NeedsVectorIV) TruncInst *Trunc)
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start), : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start),
IV(IV), Trunc(Trunc), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { IV(IV), Trunc(Trunc), IndDesc(IndDesc) {
addOperand(Step); addOperand(Step);
} }
@ -1209,9 +1207,6 @@ public:
const Type *getScalarType() const { const Type *getScalarType() const {
return Trunc ? Trunc->getType() : IV->getType(); return Trunc ? Trunc->getType() : IV->getType();
} }
/// Returns true if a vector phi needs to be created for the induction.
bool needsVectorIV() const { return NeedsVectorIV; }
}; };
class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe {

View File

@ -55,8 +55,7 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
VPValue *Start = Plan->getVPValueOrAddLiveIn(II->getStartValue()); VPValue *Start = Plan->getVPValueOrAddLiveIn(II->getStartValue());
VPValue *Step = VPValue *Step =
vputils::getOrCreateVPValueForSCEVExpr(*Plan, II->getStep(), SE); vputils::getOrCreateVPValueForSCEVExpr(*Plan, II->getStep(), SE);
NewRecipe = NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II);
new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II, true);
} else { } else {
Plan->addVPValue(Phi, VPPhi); Plan->addVPValue(Phi, VPPhi);
continue; continue;
@ -474,7 +473,10 @@ void VPlanTransforms::removeRedundantCanonicalIVs(VPlan &Plan) {
// everything WidenNewIV's users need. That is, WidenOriginalIV will // everything WidenNewIV's users need. That is, WidenOriginalIV will
// generate a vector phi or all users of WidenNewIV demand the first lane // generate a vector phi or all users of WidenNewIV demand the first lane
// only. // only.
if (WidenOriginalIV->needsVectorIV() || if (any_of(WidenOriginalIV->users(),
[WidenOriginalIV](VPUser *U) {
return !U->usesScalars(WidenOriginalIV);
}) ||
vputils::onlyFirstLaneUsed(WidenNewIV)) { vputils::onlyFirstLaneUsed(WidenNewIV)) {
WidenNewIV->replaceAllUsesWith(WidenOriginalIV); WidenNewIV->replaceAllUsesWith(WidenOriginalIV);
WidenNewIV->eraseFromParent(); WidenNewIV->eraseFromParent();