Skip to content

Commit 1586cb9

Browse files
fhahnaadeshps-mcw
authored andcommitted
[VPlan] Create resume phis in scalar preheader early. (NFC) (llvm#166099)
Create phi recipes for scalar resume value up front in addInitialSkeleton during initial construction. This will allow moving the remaining code dealing with resume values to VPlan transforms/construction. PR: llvm#166099
1 parent 9176595 commit 1586cb9

File tree

7 files changed

+48
-52
lines changed

7 files changed

+48
-52
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8532,7 +8532,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
85328532
// failures.
85338533
VPlanTransforms::addExitUsersForFirstOrderRecurrences(*Plan, Range);
85348534
DenseMap<VPValue *, VPValue *> IVEndValues;
8535-
VPlanTransforms::addScalarResumePhis(*Plan, RecipeBuilder, IVEndValues);
8535+
VPlanTransforms::updateScalarResumePhis(*Plan, IVEndValues);
85368536

85378537
// ---------------------------------------------------------------------------
85388538
// Transform initial VPlan: Apply previously taken decisions, in order, to
@@ -8630,23 +8630,12 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VFRange &Range) {
86308630
*TLI))
86318631
return nullptr;
86328632

8633-
// Collect mapping of IR header phis to header phi recipes, to be used in
8634-
// addScalarResumePhis.
8635-
DenseMap<VPBasicBlock *, VPValue *> BlockMaskCache;
8636-
VPRecipeBuilder RecipeBuilder(*Plan, OrigLoop, TLI, &TTI, Legal, CM, PSE,
8637-
Builder, BlockMaskCache);
8638-
for (auto &R : Plan->getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
8639-
if (isa<VPCanonicalIVPHIRecipe>(&R))
8640-
continue;
8641-
auto *HeaderR = cast<VPHeaderPHIRecipe>(&R);
8642-
RecipeBuilder.setRecipe(HeaderR->getUnderlyingInstr(), HeaderR);
8643-
}
8644-
DenseMap<VPValue *, VPValue *> IVEndValues;
86458633
// TODO: IVEndValues are not used yet in the native path, to optimize exit
86468634
// values.
86478635
// TODO: We can't call runPass on the transform yet, due to verifier
86488636
// failures.
8649-
VPlanTransforms::addScalarResumePhis(*Plan, RecipeBuilder, IVEndValues);
8637+
DenseMap<VPValue *, VPValue *> IVEndValues;
8638+
VPlanTransforms::updateScalarResumePhis(*Plan, IVEndValues);
86508639

86518640
assert(verifyVPlanIsValid(*Plan) && "VPlan is invalid");
86528641
return Plan;

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
11341134
OpcodeTy Opcode;
11351135

11361136
/// An optional name that can be used for the generated IR instruction.
1137-
const std::string Name;
1137+
std::string Name;
11381138

11391139
/// Returns true if we can generate a scalar for the first lane only if
11401140
/// needed.
@@ -1225,6 +1225,9 @@ class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
12251225
/// Returns the symbolic name assigned to the VPInstruction.
12261226
StringRef getName() const { return Name; }
12271227

1228+
/// Set the symbolic name for the VPInstruction.
1229+
void setName(StringRef NewName) { Name = NewName.str(); }
1230+
12281231
protected:
12291232
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
12301233
/// Print the VPInstruction to \p O.

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,15 @@ static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, DebugLoc IVDL,
554554
Plan.getEntry()->swapSuccessors();
555555

556556
createExtractsForLiveOuts(Plan, MiddleVPBB);
557+
558+
VPBuilder ScalarPHBuilder(ScalarPH);
559+
for (const auto &[PhiR, ScalarPhiR] : zip_equal(
560+
drop_begin(HeaderVPBB->phis()), Plan.getScalarHeader()->phis())) {
561+
auto *VectorPhiR = cast<VPPhi>(&PhiR);
562+
auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
563+
{VectorPhiR, VectorPhiR->getOperand(0)}, VectorPhiR->getDebugLoc());
564+
cast<VPIRPhi>(&ScalarPhiR)->addOperand(ResumePhiR);
565+
}
557566
}
558567

559568
std::unique_ptr<VPlan>

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4526,12 +4526,13 @@ void VPlanTransforms::addBranchWeightToMiddleTerminator(
45264526
MiddleTerm->setMetadata(LLVMContext::MD_prof, BranchWeights);
45274527
}
45284528

4529-
/// Create and return a ResumePhi for \p WideIV, unless it is truncated. If the
4530-
/// induction recipe is not canonical, creates a VPDerivedIVRecipe to compute
4531-
/// the end value of the induction.
4532-
static VPInstruction *addResumePhiRecipeForInduction(
4533-
VPWidenInductionRecipe *WideIV, VPBuilder &VectorPHBuilder,
4534-
VPBuilder &ScalarPHBuilder, VPTypeAnalysis &TypeInfo, VPValue *VectorTC) {
4529+
/// Compute and return the end value for \p WideIV, unless it is truncated. If
4530+
/// the induction recipe is not canonical, creates a VPDerivedIVRecipe to
4531+
/// compute the end value of the induction.
4532+
static VPValue *tryToComputeEndValueForInduction(VPWidenInductionRecipe *WideIV,
4533+
VPBuilder &VectorPHBuilder,
4534+
VPTypeAnalysis &TypeInfo,
4535+
VPValue *VectorTC) {
45354536
auto *WideIntOrFp = dyn_cast<VPWidenIntOrFpInductionRecipe>(WideIV);
45364537
// Truncated wide inductions resume from the last lane of their vector value
45374538
// in the last vector iteration which is handled elsewhere.
@@ -4557,36 +4558,30 @@ static VPInstruction *addResumePhiRecipeForInduction(
45574558
WideIV->getDebugLoc());
45584559
}
45594560

4560-
auto *ResumePhiRecipe = ScalarPHBuilder.createScalarPhi(
4561-
{EndValue, Start}, WideIV->getDebugLoc(), "bc.resume.val");
4562-
return ResumePhiRecipe;
4561+
return EndValue;
45634562
}
45644563

4565-
void VPlanTransforms::addScalarResumePhis(
4566-
VPlan &Plan, VPRecipeBuilder &Builder,
4567-
DenseMap<VPValue *, VPValue *> &IVEndValues) {
4564+
void VPlanTransforms::updateScalarResumePhis(
4565+
VPlan &Plan, DenseMap<VPValue *, VPValue *> &IVEndValues) {
45684566
VPTypeAnalysis TypeInfo(Plan);
45694567
auto *ScalarPH = Plan.getScalarPreheader();
45704568
auto *MiddleVPBB = cast<VPBasicBlock>(ScalarPH->getPredecessors()[0]);
45714569
VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion();
45724570
VPBuilder VectorPHBuilder(
45734571
cast<VPBasicBlock>(VectorRegion->getSinglePredecessor()));
45744572
VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
4575-
VPBuilder ScalarPHBuilder(ScalarPH);
4576-
for (VPRecipeBase &ScalarPhiR : Plan.getScalarHeader()->phis()) {
4577-
auto *ScalarPhiIRI = cast<VPIRPhi>(&ScalarPhiR);
4573+
for (VPRecipeBase &PhiR : Plan.getScalarPreheader()->phis()) {
4574+
auto *ResumePhiR = cast<VPPhi>(&PhiR);
45784575

45794576
// TODO: Extract final value from induction recipe initially, optimize to
45804577
// pre-computed end value together in optimizeInductionExitUsers.
4581-
auto *VectorPhiR =
4582-
cast<VPHeaderPHIRecipe>(Builder.getRecipe(&ScalarPhiIRI->getIRPhi()));
4578+
auto *VectorPhiR = cast<VPHeaderPHIRecipe>(ResumePhiR->getOperand(0));
45834579
if (auto *WideIVR = dyn_cast<VPWidenInductionRecipe>(VectorPhiR)) {
4584-
if (VPInstruction *ResumePhi = addResumePhiRecipeForInduction(
4585-
WideIVR, VectorPHBuilder, ScalarPHBuilder, TypeInfo,
4586-
&Plan.getVectorTripCount())) {
4587-
assert(isa<VPPhi>(ResumePhi) && "Expected a phi");
4588-
IVEndValues[WideIVR] = ResumePhi->getOperand(0);
4589-
ScalarPhiIRI->addOperand(ResumePhi);
4580+
if (VPValue *EndValue = tryToComputeEndValueForInduction(
4581+
WideIVR, VectorPHBuilder, TypeInfo, &Plan.getVectorTripCount())) {
4582+
IVEndValues[WideIVR] = EndValue;
4583+
ResumePhiR->setOperand(0, EndValue);
4584+
ResumePhiR->setName("bc.resume.val");
45904585
continue;
45914586
}
45924587
// TODO: Also handle truncated inductions here. Computing end-values
@@ -4608,10 +4603,8 @@ void VPlanTransforms::addScalarResumePhis(
46084603
ResumeFromVectorLoop = MiddleBuilder.createNaryOp(
46094604
VPInstruction::ExtractLastElement, {ResumeFromVectorLoop}, {},
46104605
"vector.recur.extract");
4611-
StringRef Name = IsFOR ? "scalar.recur.init" : "bc.merge.rdx";
4612-
auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
4613-
{ResumeFromVectorLoop, VectorPhiR->getStartValue()}, {}, Name);
4614-
ScalarPhiIRI->addOperand(ResumePhiR);
4606+
ResumePhiR->setName(IsFOR ? "scalar.recur.init" : "bc.merge.rdx");
4607+
ResumePhiR->setOperand(0, ResumeFromVectorLoop);
46154608
}
46164609
}
46174610

llvm/lib/Transforms/Vectorize/VPlanTransforms.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,12 @@ struct VPlanTransforms {
372372
addBranchWeightToMiddleTerminator(VPlan &Plan, ElementCount VF,
373373
std::optional<unsigned> VScaleForTuning);
374374

375-
/// Create resume phis in the scalar preheader for first-order recurrences,
376-
/// reductions and inductions, and update the VPIRInstructions wrapping the
377-
/// original phis in the scalar header. End values for inductions are added to
378-
/// \p IVEndValues.
379-
static void addScalarResumePhis(VPlan &Plan, VPRecipeBuilder &Builder,
380-
DenseMap<VPValue *, VPValue *> &IVEndValues);
375+
/// Update the resume phis in the scalar preheader after creating wide recipes
376+
/// for first-order recurrences, reductions and inductions. End values for
377+
/// inductions are added to \p IVEndValues.
378+
static void
379+
updateScalarResumePhis(VPlan &Plan,
380+
DenseMap<VPValue *, VPValue *> &IVEndValues);
381381

382382
/// Handle users in the exit block for first order reductions in the original
383383
/// exit block. The penultimate value of recurrences is fed to their LCSSA phi

llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ compound=true
113113
N0 -> N2 [ label="F"]
114114
N1 [label =
115115
"scalar.ph:\l" +
116+
" EMIT-SCALAR vp\<%6\> = phi [ ir\<%indvars.iv\>, middle.block ], [ ir\<0\>, ir-bb\<entry\> ]\l" +
116117
"Successor(s): ir-bb\<for.body\>\l"
117118
]
118119
N1 -> N3 [ label=""]
119120
N3 [label =
120121
"ir-bb\<for.body\>:\l" +
121-
" IR %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]\l" +
122+
" IR %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] (extra operand: vp\<%6\> from scalar.ph)\l" +
122123
" IR %arr.idx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv\l" +
123124
" IR %l1 = load i32, ptr %arr.idx, align 4\l" +
124125
" IR %res = add i32 %l1, 10\l" +
@@ -282,12 +283,13 @@ compound=true
282283
N0 -> N2 [ label="F"]
283284
N1 [label =
284285
"scalar.ph:\l" +
286+
" EMIT-SCALAR vp\<%6\> = phi [ ir\<%iv\>, middle.block ], [ ir\<0\>, ir-bb\<entry\> ]\l" +
285287
"Successor(s): ir-bb\<loop.header\>\l"
286288
]
287289
N1 -> N3 [ label=""]
288290
N3 [label =
289291
"ir-bb\<loop.header\>:\l" +
290-
" IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]\l" +
292+
" IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] (extra operand: vp\<%6\> from scalar.ph)\l" +
291293
" IR %arr.idx = getelementptr inbounds i32, ptr %A, i64 %iv\l" +
292294
" IR %l1 = load i32, ptr %arr.idx, align 4\l" +
293295
" IR %c = icmp eq i32 %l1, 0\l" +

llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ TEST_F(VPIRVerifierTest, testVerifyIRPhiInScalarHeaderVPIRBB) {
346346
Function *F = M.getFunction("f");
347347
BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
348348
auto Plan = buildVPlan(LoopHeader);
349+
VPValue *Zero = Plan->getConstantInt(32, 0);
350+
Plan->getScalarHeader()->front().addOperand(Zero);
349351

350352
#if GTEST_HAS_STREAM_REDIRECTION
351353
::testing::internal::CaptureStderr();
@@ -387,8 +389,6 @@ TEST_F(VPIRVerifierTest, testVerifyIRPhiInExitVPIRBB) {
387389
{HeaderBlock->front().getVPSingleValue()});
388390
DefI->insertBefore(Plan->getMiddleBlock()->getTerminator());
389391
Plan->getExitBlocks()[0]->front().addOperand(DefI);
390-
VPValue *Zero = Plan->getConstantInt(32, 0);
391-
Plan->getScalarHeader()->front().addOperand(Zero);
392392

393393
#if GTEST_HAS_STREAM_REDIRECTION
394394
::testing::internal::CaptureStderr();

0 commit comments

Comments
 (0)