From 4fc190351e5af901b6107d162d07e1fbca90934f Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 17 Apr 2023 13:38:00 +0100 Subject: [PATCH] [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. --- .../Transforms/Vectorize/LoopVectorize.cpp | 33 ++++++------------- llvm/lib/Transforms/Vectorize/VPlan.h | 13 +++----- .../Transforms/Vectorize/VPlanTransforms.cpp | 8 +++-- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 3633cd903e22..fb36daeacfe1 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8277,22 +8277,11 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, /// Creates a VPWidenIntOrFpInductionRecpipe for \p Phi. If needed, it will also /// insert a recipe to expand the step for the induction recipe. -static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes( - PHINode *Phi, Instruction *PhiOrTrunc, VPValue *Start, - const InductionDescriptor &IndDesc, LoopVectorizationCostModel &CM, - VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, VFRange &Range) { - // Returns true if an instruction \p I should be scalarized instead of - // 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); +static VPWidenIntOrFpInductionRecipe * +createWidenInductionRecipes(PHINode *Phi, Instruction *PhiOrTrunc, + VPValue *Start, const InductionDescriptor &IndDesc, + VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, + VFRange &Range) { assert(IndDesc.getStartValue() == Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader())); assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) && @@ -8301,12 +8290,10 @@ static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes( VPValue *Step = vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep(), SE); if (auto *TruncI = dyn_cast(PhiOrTrunc)) { - return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI, - !NeedsScalarIVOnly); + return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI); } assert(isa(PhiOrTrunc) && "must be a phi node here"); - return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, - !NeedsScalarIVOnly); + return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc); } 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 // produces its scalar and vector values. 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); // Check if this is pointer induction. If so, build the recipe for it. @@ -8355,8 +8342,8 @@ VPWidenIntOrFpInductionRecipe *VPRecipeBuilder::tryToOptimizeInductionTruncate( auto *Phi = cast(I->getOperand(0)); const InductionDescriptor &II = *Legal->getIntOrFpInductionDescriptor(Phi); VPValue *Start = Plan.getVPValueOrAddLiveIn(II.getStartValue()); - return createWidenInductionRecipes(Phi, I, Start, II, CM, Plan, - *PSE.getSE(), *OrigLoop, Range); + return createWidenInductionRecipes(Phi, I, Start, II, Plan, *PSE.getSE(), + *OrigLoop, Range); } return nullptr; } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 0e74a0b91aba..3d031e6740d5 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1140,22 +1140,20 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe { PHINode *IV; TruncInst *Trunc; const InductionDescriptor &IndDesc; - bool NeedsVectorIV; public: VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, - const InductionDescriptor &IndDesc, - bool NeedsVectorIV) + const InductionDescriptor &IndDesc) : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start), IV(IV), - Trunc(nullptr), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { + Trunc(nullptr), IndDesc(IndDesc) { addOperand(Step); } VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, - TruncInst *Trunc, bool NeedsVectorIV) + TruncInst *Trunc) : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start), - IV(IV), Trunc(Trunc), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { + IV(IV), Trunc(Trunc), IndDesc(IndDesc) { addOperand(Step); } @@ -1209,9 +1207,6 @@ public: const Type *getScalarType() const { 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 { diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 41c7c79c0e92..ec1a1a8307e9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -55,8 +55,7 @@ void VPlanTransforms::VPInstructionsToVPRecipes( VPValue *Start = Plan->getVPValueOrAddLiveIn(II->getStartValue()); VPValue *Step = vputils::getOrCreateVPValueForSCEVExpr(*Plan, II->getStep(), SE); - NewRecipe = - new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II, true); + NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II); } else { Plan->addVPValue(Phi, VPPhi); continue; @@ -474,7 +473,10 @@ void VPlanTransforms::removeRedundantCanonicalIVs(VPlan &Plan) { // everything WidenNewIV's users need. That is, WidenOriginalIV will // generate a vector phi or all users of WidenNewIV demand the first lane // only. - if (WidenOriginalIV->needsVectorIV() || + if (any_of(WidenOriginalIV->users(), + [WidenOriginalIV](VPUser *U) { + return !U->usesScalars(WidenOriginalIV); + }) || vputils::onlyFirstLaneUsed(WidenNewIV)) { WidenNewIV->replaceAllUsesWith(WidenOriginalIV); WidenNewIV->eraseFromParent();