Skip to content

Commit e8d78a9

Browse files
committed
!fixup address latest comments, thanks!
1 parent 56e82ef commit e8d78a9

File tree

2 files changed

+65
-49
lines changed

2 files changed

+65
-49
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -513,16 +513,17 @@ class InnerLoopVectorizer {
513513
void fixNonInductionPHIs(VPTransformState &State);
514514

515515
/// Create a ResumePHI VPInstruction for the induction variable \p OrigPhi to
516-
/// resume iteration count in the scalar epilogue, from where the vectorized
517-
/// loop left off and add it the scalar preheader of the VPlan. \p Step is the
516+
/// resume iteration count in the scalar epilogue from where the vectorized
517+
/// loop left off, and add it to the scalar preheader of VPlan. \p Step is the
518518
/// SCEV-expanded induction step to use. In cases where the loop skeleton is
519519
/// more complicated (i.e., epilogue vectorization) and the resume values can
520520
/// come from an additional bypass block, the \p AdditionalBypass pair
521-
/// provides information about the bypass block and the end value on the edge
522-
/// from bypass to this loop.
521+
/// provides this additional bypass block along with the resume value coming
522+
/// from it.
523523
void createInductionResumeValue(
524-
PHINode *OrigPhi, const InductionDescriptor &ID, Value *Step,
525-
ArrayRef<BasicBlock *> BypassBlocks, VPBuilder &ScalarPHBuilder,
524+
VPIRInstruction *PhiIRI, PHINode *OrigPhi, const InductionDescriptor &ID,
525+
Value *Step, ArrayRef<BasicBlock *> BypassBlocks,
526+
VPBuilder &ScalarPHBuilder,
526527
std::pair<BasicBlock *, Value *> AdditionalBypass = {nullptr, nullptr});
527528

528529
/// Returns the original loop trip count.
@@ -535,7 +536,7 @@ class InnerLoopVectorizer {
535536

536537
std::pair<BasicBlock *, Value *>
537538
getInductionBypassValue(PHINode *OrigPhi) const {
538-
return InductionBypassValues.find(OrigPhi)->second;
539+
return InductionBypassValues.at(OrigPhi);
539540
}
540541

541542
protected:
@@ -669,7 +670,9 @@ class InnerLoopVectorizer {
669670
/// for cleaning the checks, if vectorization turns out unprofitable.
670671
GeneratedRTChecks &RTChecks;
671672

672-
/// Mapping of induction phis to their bypass values and bypass blocks.
673+
/// Mapping of induction phis to their bypass values and bypass blocks. They
674+
/// need to be added to their phi nodes after the epilogue skeleton has been
675+
/// created.
673676
DenseMap<PHINode *, std::pair<BasicBlock *, Value *>> InductionBypassValues;
674677

675678
VPlan &Plan;
@@ -2586,8 +2589,9 @@ void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
25862589
}
25872590

25882591
void InnerLoopVectorizer::createInductionResumeValue(
2589-
PHINode *OrigPhi, const InductionDescriptor &II, Value *Step,
2590-
ArrayRef<BasicBlock *> BypassBlocks, VPBuilder &ScalarPHBuilder,
2592+
VPIRInstruction *PhiR, PHINode *OrigPhi, const InductionDescriptor &II,
2593+
Value *Step, ArrayRef<BasicBlock *> BypassBlocks,
2594+
VPBuilder &ScalarPHBuilder,
25912595
std::pair<BasicBlock *, Value *> AdditionalBypass) {
25922596
Value *VectorTripCount = getOrCreateVectorTripCount(LoopVectorPreHeader);
25932597
assert(VectorTripCount && "Expected valid arguments");
@@ -2624,18 +2628,17 @@ void InnerLoopVectorizer::createInductionResumeValue(
26242628
VPInstruction::ResumePhi,
26252629
{Plan.getOrAddLiveIn(EndValue), Plan.getOrAddLiveIn(II.getStartValue())},
26262630
OrigPhi->getDebugLoc(), "bc.resume.val");
2627-
auto *ScalarLoopHeader = Plan.getScalarHeader();
2628-
for (VPRecipeBase &R : *ScalarLoopHeader) {
2629-
auto *IRI = cast<VPIRInstruction>(&R);
2630-
if (&IRI->getInstruction() == OrigPhi) {
2631-
IRI->addOperand(ResumePhiRecipe);
2632-
break;
2633-
}
2634-
}
2635-
2636-
if (AdditionalBypass.first)
2631+
assert(PhiR->getNumOperands() == 0 && "PhiR should not have any operands");
2632+
PhiR->addOperand(ResumePhiRecipe);
2633+
2634+
if (AdditionalBypass.first) {
2635+
// Store the bypass values here, as they need to be added to their phi nodes
2636+
// after the epilogue skeleton has been created.
2637+
assert(!InductionBypassValues.contains(OrigPhi) &&
2638+
"entry for OrigPhi already exits");
26372639
InductionBypassValues[OrigPhi] = {AdditionalBypass.first,
26382640
EndValueFromAdditionalBypass};
2641+
}
26392642
}
26402643

26412644
/// Return the expanded step for \p ID using \p ExpandedSCEVs to look up SCEV
@@ -2659,20 +2662,24 @@ void InnerLoopVectorizer::createInductionResumeValues(
26592662
(!AdditionalBypass.first && !AdditionalBypass.second)) &&
26602663
"Inconsistent information about additional bypass.");
26612664
// We are going to resume the execution of the scalar loop.
2662-
// Go over all of the induction variables that we found and fix the
2663-
// PHIs that are left in the scalar version of the loop.
2664-
// The starting values of PHI nodes depend on the counter of the last
2665-
// iteration in the vectorized loop.
2666-
// If we come from a bypass edge then we need to start from the original
2665+
// Go over all of the induction variables in the scalar header and fix the
2666+
// PHIs that are left in the scalar version of the loop. The starting values
2667+
// of PHI nodes depend on the counter of the last iteration in the vectorized
2668+
// loop. If we come from a bypass edge then we need to start from the original
26672669
// start value.
26682670
VPBasicBlock *ScalarPHVPBB = Plan.getScalarPreheader();
26692671
VPBuilder ScalarPHBuilder(ScalarPHVPBB, ScalarPHVPBB->begin());
2670-
for (const auto &InductionEntry : Legal->getInductionVars()) {
2671-
PHINode *OrigPhi = InductionEntry.first;
2672-
const InductionDescriptor &II = InductionEntry.second;
2673-
createInductionResumeValue(OrigPhi, II, getExpandedStep(II, ExpandedSCEVs),
2674-
LoopBypassBlocks, ScalarPHBuilder,
2675-
AdditionalBypass);
2672+
for (VPRecipeBase &R : *Plan.getScalarHeader()) {
2673+
auto *PhiR = cast<VPIRInstruction>(&R);
2674+
auto *Phi = dyn_cast<PHINode>(&PhiR->getInstruction());
2675+
if (!Phi)
2676+
break;
2677+
if (!Legal->getInductionVars().contains(Phi))
2678+
continue;
2679+
const InductionDescriptor &II = Legal->getInductionVars().find(Phi)->second;
2680+
createInductionResumeValue(
2681+
PhiR, Phi, II, getExpandedStep(II, ExpandedSCEVs), LoopBypassBlocks,
2682+
ScalarPHBuilder, AdditionalBypass);
26762683
}
26772684
}
26782685

@@ -7713,13 +7720,21 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
77137720

77147721
BestVPlan.execute(&State);
77157722

7716-
// 2.5 Collect reduction resume values.
77177723
auto *ExitVPBB = BestVPlan.getMiddleBlock();
7718-
if (VectorizingEpilogue)
7724+
// 2.5 When vectorizing the epilogue, fix reduction resume values and
7725+
// induction resume values from the bypass blocks.
7726+
if (VectorizingEpilogue) {
77197727
for (VPRecipeBase &R : *ExitVPBB) {
77207728
fixReductionScalarResumeWhenVectorizingEpilog(
77217729
&R, State, State.CFG.VPBB2IRBB[ExitVPBB]);
77227730
}
7731+
BasicBlock *PH = OrigLoop->getLoopPreheader();
7732+
for (const auto &[IVPhi, _] : Legal->getInductionVars()) {
7733+
auto *Inc = cast<PHINode>(IVPhi->getIncomingValueForBlock(PH));
7734+
const auto &[BB, V] = ILV.getInductionBypassValue(IVPhi);
7735+
Inc->setIncomingValueForBlock(BB, V);
7736+
}
7737+
}
77237738

77247739
// 2.6. Maintain Loop Hints
77257740
// Keep all loop hints from the original loop on the vector loop (we'll
@@ -7808,10 +7823,8 @@ EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton(
78087823
// Generate the induction variable.
78097824
EPI.VectorTripCount = getOrCreateVectorTripCount(LoopVectorPreHeader);
78107825

7811-
// Skip induction resume value creation here because they will be created in
7812-
// the second pass for the scalar loop. The induction resume values for the
7813-
// inductions in the epilogue loop are created before executing the plan for
7814-
// the epilogue loop.
7826+
// Create induction resume values and ResumePhis for the inductions in the
7827+
// epilogue loop in the VPlan for the epilogue vector loop.
78157828
VPBasicBlock *ScalarPHVPBB = Plan.getScalarPreheader();
78167829
VPBuilder ScalarPHBuilder(ScalarPHVPBB, ScalarPHVPBB->begin());
78177830
for (VPRecipeBase &R :
@@ -7827,11 +7840,19 @@ EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton(
78277840
} else if (auto *WidenInd = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) {
78287841
IndPhi = WidenInd->getPHINode();
78297842
ID = &WidenInd->getInductionDescriptor();
7830-
} else
7843+
} else {
78317844
continue;
7845+
}
78327846

7833-
createInductionResumeValue(IndPhi, *ID, getExpandedStep(*ID, ExpandedSCEVs),
7834-
LoopBypassBlocks, ScalarPHBuilder);
7847+
auto *ScalarLoopHeader = Plan.getScalarHeader();
7848+
for (VPRecipeBase &R : *ScalarLoopHeader) {
7849+
auto *PhiR = cast<VPIRInstruction>(&R);
7850+
if (&PhiR->getInstruction() != IndPhi)
7851+
continue;
7852+
createInductionResumeValue(PhiR, IndPhi, *ID,
7853+
getExpandedStep(*ID, ExpandedSCEVs),
7854+
LoopBypassBlocks, ScalarPHBuilder);
7855+
}
78357856
}
78367857

78377858
return {LoopVectorPreHeader, nullptr};
@@ -10321,8 +10342,8 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1032110342
RdxDesc.getRecurrenceStartValue());
1032210343
}
1032310344
} else {
10324-
// Retrive the induction resume values for wide inductions from
10325-
// their original phi nodes in the scalar loop
10345+
// Retrieve the induction resume values for wide inductions from
10346+
// their original phi nodes in the scalar loop.
1032610347
PHINode *IndPhi = nullptr;
1032710348
if (auto *Ind = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
1032810349
IndPhi = cast<PHINode>(Ind->getUnderlyingValue());
@@ -10342,13 +10363,6 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1034210363
LVP.executePlan(EPI.EpilogueVF, EPI.EpilogueUF, BestEpiPlan, EpilogILV,
1034310364
DT, true, &ExpandedSCEVs);
1034410365
++LoopsEpilogueVectorized;
10345-
BasicBlock *PH = L->getLoopPreheader();
10346-
10347-
for (const auto &[IVPhi, _] : LVL.getInductionVars()) {
10348-
auto *Inc = cast<PHINode>(IVPhi->getIncomingValueForBlock(PH));
10349-
const auto &[BB, V] = EpilogILV.getInductionBypassValue(IVPhi);
10350-
Inc->setIncomingValueForBlock(BB, V);
10351-
}
1035210366
if (!MainILV.areSafetyChecksAdded())
1035310367
DisableRuntimeUnroll = true;
1035410368
} else {

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
629629
State.CFG
630630
.VPBB2IRBB[cast<VPBasicBlock>(getParent()->getSinglePredecessor())];
631631
NewPhi->addIncoming(IncomingFromVPlanPred, VPlanPred);
632+
// TODO: Predecessors are temporarily reversed to reduce test changes.
633+
// Remove it and update remaining tests after functional change landed.
632634
for (auto *OtherPred :
633635
reverse(to_vector(predecessors(Builder.GetInsertBlock())))) {
634636
assert(OtherPred != VPlanPred &&

0 commit comments

Comments
 (0)