Skip to content

Commit 852ad20

Browse files
committed
[VPlan] Generalize collectUsersInExitBlocks for multiple exit bbs.
Generalize collectUsersInExitBlock to collecting exit users in multiple exit blocks. Exit blocks are leaf nodes in the VPlan (without successors) except the scalar header. Split off from #112138
1 parent 0c18def commit 852ad20

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8819,55 +8819,59 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan) {
88198819
}
88208820
}
88218821

8822-
// Collect VPIRInstructions for phis in the original exit block that are modeled
8822+
// Collect VPIRInstructions for phis in the exit blocks that are modeled
88238823
// in VPlan and add the exiting VPValue as operand. Some exiting values are not
88248824
// modeled explicitly yet and won't be included. Those are un-truncated
88258825
// VPWidenIntOrFpInductionRecipe, VPWidenPointerInductionRecipe and induction
88268826
// increments.
8827-
static SetVector<VPIRInstruction *> collectUsersInExitBlock(
8827+
static SetVector<VPIRInstruction *> collectUsersInExitBlocks(
88288828
Loop *OrigLoop, VPRecipeBuilder &Builder, VPlan &Plan,
88298829
const MapVector<PHINode *, InductionDescriptor> &Inductions) {
8830-
auto *MiddleVPBB = Plan.getMiddleBlock();
8831-
// No edge from the middle block to the unique exit block has been inserted
8832-
// and there is nothing to fix from vector loop; phis should have incoming
8833-
// from scalar loop only.
8834-
if (MiddleVPBB->getNumSuccessors() != 2)
8835-
return {};
88368830
SetVector<VPIRInstruction *> ExitUsersToFix;
8837-
VPBasicBlock *ExitVPBB = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors()[0]);
8838-
BasicBlock *ExitingBB = OrigLoop->getExitingBlock();
8839-
for (VPRecipeBase &R : *ExitVPBB) {
8840-
auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
8841-
if (!ExitIRI)
8842-
continue;
8843-
auto *ExitPhi = dyn_cast<PHINode>(&ExitIRI->getInstruction());
8844-
if (!ExitPhi)
8845-
break;
8846-
Value *IncomingValue = ExitPhi->getIncomingValueForBlock(ExitingBB);
8847-
VPValue *V = Builder.getVPValueOrAddLiveIn(IncomingValue);
8848-
// Exit values for inductions are computed and updated outside of VPlan and
8849-
// independent of induction recipes.
8850-
// TODO: Compute induction exit values in VPlan.
8851-
if ((isa<VPWidenIntOrFpInductionRecipe>(V) &&
8852-
!cast<VPWidenIntOrFpInductionRecipe>(V)->getTruncInst()) ||
8853-
isa<VPWidenPointerInductionRecipe>(V) ||
8854-
(isa<Instruction>(IncomingValue) &&
8855-
OrigLoop->contains(cast<Instruction>(IncomingValue)) &&
8856-
any_of(IncomingValue->users(), [&Inductions](User *U) {
8857-
auto *P = dyn_cast<PHINode>(U);
8858-
return P && Inductions.contains(P);
8859-
})))
8831+
for (VPBlockBase *VPB : vp_depth_first_shallow(
8832+
Plan.getVectorLoopRegion()->getSingleSuccessor())) {
8833+
if (VPB->getNumSuccessors() != 0 || VPB == Plan.getScalarHeader())
88608834
continue;
8861-
ExitUsersToFix.insert(ExitIRI);
8862-
ExitIRI->addOperand(V);
8835+
auto *ExitVPBB = cast<VPIRBasicBlock>(VPB);
8836+
BasicBlock *ExitBB = ExitVPBB->getIRBasicBlock();
8837+
BasicBlock *ExitingBB = find_singleton<BasicBlock>(
8838+
to_vector(predecessors(ExitBB)),
8839+
[OrigLoop](BasicBlock *Pred, bool AllowRepeats) {
8840+
return OrigLoop->contains(Pred) ? Pred : nullptr;
8841+
});
8842+
for (VPRecipeBase &R : *ExitVPBB) {
8843+
auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
8844+
if (!ExitIRI)
8845+
continue;
8846+
auto *ExitPhi = dyn_cast<PHINode>(&ExitIRI->getInstruction());
8847+
if (!ExitPhi)
8848+
break;
8849+
Value *IncomingValue = ExitPhi->getIncomingValueForBlock(ExitingBB);
8850+
VPValue *V = Builder.getVPValueOrAddLiveIn(IncomingValue);
8851+
// Exit values for inductions are computed and updated outside of VPlan
8852+
// and independent of induction recipes.
8853+
// TODO: Compute induction exit values in VPlan.
8854+
if ((isa<VPWidenIntOrFpInductionRecipe>(V) &&
8855+
!cast<VPWidenIntOrFpInductionRecipe>(V)->getTruncInst()) ||
8856+
isa<VPWidenPointerInductionRecipe>(V) ||
8857+
(isa<Instruction>(IncomingValue) &&
8858+
OrigLoop->contains(cast<Instruction>(IncomingValue)) &&
8859+
any_of(IncomingValue->users(), [&Inductions](User *U) {
8860+
auto *P = dyn_cast<PHINode>(U);
8861+
return P && Inductions.contains(P);
8862+
})))
8863+
continue;
8864+
ExitUsersToFix.insert(ExitIRI);
8865+
ExitIRI->addOperand(V);
8866+
}
88638867
}
88648868
return ExitUsersToFix;
88658869
}
88668870

88678871
// Add exit values to \p Plan. Extracts are added for each entry in \p
88688872
// ExitUsersToFix if needed and their operands are updated.
88698873
static void
8870-
addUsersInExitBlock(VPlan &Plan,
8874+
addUsersInExitBlocks(VPlan &Plan,
88718875
const SetVector<VPIRInstruction *> &ExitUsersToFix) {
88728876
if (ExitUsersToFix.empty())
88738877
return;
@@ -9161,10 +9165,10 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
91619165
RecipeBuilder.fixHeaderPhis();
91629166

91639167
addScalarResumePhis(RecipeBuilder, *Plan);
9164-
SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlock(
9168+
SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlocks(
91659169
OrigLoop, RecipeBuilder, *Plan, Legal->getInductionVars());
91669170
addExitUsersForFirstOrderRecurrences(*Plan, ExitUsersToFix);
9167-
addUsersInExitBlock(*Plan, ExitUsersToFix);
9171+
addUsersInExitBlocks(*Plan, ExitUsersToFix);
91689172
// ---------------------------------------------------------------------------
91699173
// Transform initial VPlan: Apply previously taken decisions, in order, to
91709174
// bring the VPlan to its final state.

0 commit comments

Comments
 (0)