[llvm] [VPlan] Introduce scalar loop header in plan, remove VPLiveOut. (PR #109975)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 13:51:36 PDT 2024
================
@@ -8790,6 +8787,31 @@ static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, bool HasNUW,
{CanonicalIVIncrement, &Plan.getVectorTripCount()}, DL);
}
+/// Create resume phis in the scalar preheader for first-order recurrences and
+/// reductions and update the VPIRInstructions wrapping the original phis in the
+/// scalar header.
+static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan) {
+ for (VPRecipeBase &R : *Plan.getScalarHeader()) {
+ auto *IRI = cast<VPIRInstruction>(&R);
+ if (!isa<PHINode>(IRI->getInstruction()))
+ break;
+
+ VPBuilder ScalarPHBuilder(Plan.getScalarPreheader());
+ auto *VectorR =
+ dyn_cast<VPHeaderPHIRecipe>(Builder.getRecipe(&IRI->getInstruction()));
+ if (isa<VPFirstOrderRecurrencePHIRecipe, VPReductionPHIRecipe>(VectorR)) {
+ StringRef Name = isa<VPFirstOrderRecurrencePHIRecipe>(VectorR)
+ ? "scalar.recur.init"
+ : "bc.merge.rdx";
+ auto *ResumePhiRecipe = ScalarPHBuilder.createNaryOp(
+ VPInstruction::ResumePhi,
+ {VectorR->getBackedgeValue(), VectorR->getStartValue()}, {}, Name);
+
+ IRI->addOperand(ResumePhiRecipe);
+ }
+ }
----------------
ayalz wrote:
Various suggestions below, from using more consistent variable names, to introducing the extract in the middle block for FORs, so that this method takes full care of feeding scalar loop with values coming from vector loop. See what you think of any/all/none:
```suggestion
auto *ScalarPH = Plan.getScalarPreheader();
auto *MiddleVPBB = cast<VPBasicBlock>(ScalarPH->getSinglePredecessor());
VPBuilder ScalarPHBuilder(ScalarPH);
VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
VPValue *OneVPV = Plan.getOrAddLiveIn(
ConstantInt::get(Plan.getCanonicalIV()->getScalarType(), 1));
for (VPRecipeBase &ScalarPhiR : *Plan.getScalarHeader()) {
auto *ScalarPhiIRI = cast<VPIRInstruction>(&ScalarPhiR);
auto *ScalarPhiI = dyn_cast<PHINode>(ScalarPhiIRI->getInstruction());
if (!ScalarPhiI)
break;
auto *VectorPhiR =
cast<VPHeaderPHIRecipe>(Builder.getRecipe(ScalarPhiI));
if (!isa<VPFirstOrderRecurrencePHIRecipe, VPReductionPHIRecipe>(VectorPhiR))
continue;
// The backedge value provides the value to resume coming out of a loop, which
// for FORs is a vector whose last element needs to be extracted.
// The start value provides the value if the loop is bypassed.
bool IsFOR = isa<VPFirstOrderRecurrencePHIRecipe>(VectorPhiR);
auto *ResumeFromVectorLoop = VectorPhiR->getBackedgeValue();
if (IsFOR)
ResumeFromVectorLoop = MiddleBuilder.createNaryOp(VPInstruction::ExtractFromEnd {ResumeFromVectorLoop, OneVPV}, {}, "vector.recur.extract");
StringRef Name = isFOR ? "scalar.recur.init" : "bc.merge.rdx";
auto *ResumePhiR = ScalarPHBuilder.createNaryOp(
VPInstruction::ResumePhi,
{ResumeFromVectorLoop, VectorPhiR->getStartValue()}, {}, Name);
ScalarPhiIRI->addOperand(ResumePhiR);
}
```
https://github.com/llvm/llvm-project/pull/109975
More information about the llvm-commits
mailing list