Skip to content

Commit 522b05a

Browse files
authored
[VPlan] Construct immutable VPIRBBs for exit blocks at construction(NFC) (#128374)
Constract immutable VPIRBasicBlocks for all exit blocks up front and keep a list of them. Same as the scalar header, they are leaf nodes of the VPlan and won't change. Some exit blocks may be unreachable, e.g. if the scalar epilogue always executes or depending on optimizations. This simplifies both the way we retrieve the exit blocks as well as hooking up the exit blocks. PR: #128374
1 parent d23da7d commit 522b05a

File tree

5 files changed

+33
-27
lines changed

5 files changed

+33
-27
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9132,6 +9132,10 @@ collectUsersInExitBlocks(Loop *OrigLoop, VPRecipeBuilder &Builder,
91329132
VPlan &Plan) {
91339133
SetVector<VPIRInstruction *> ExitUsersToFix;
91349134
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks()) {
9135+
// Nothing to do for unreachable exit blocks.
9136+
if (ExitVPBB->getNumPredecessors() == 0)
9137+
continue;
9138+
91359139
for (VPRecipeBase &R : *ExitVPBB) {
91369140
auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
91379141
if (!ExitIRI)

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,11 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
850850
VPlan::VPlan(Loop *L) {
851851
setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
852852
ScalarHeader = createVPIRBasicBlock(L->getHeader());
853+
854+
SmallVector<BasicBlock *> IRExitBlocks;
855+
L->getExitBlocks(IRExitBlocks);
856+
for (BasicBlock *EB : IRExitBlocks)
857+
ExitBlocks.push_back(createVPIRBasicBlock(EB));
853858
}
854859

855860
VPlan::~VPlan() {
@@ -931,7 +936,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
931936
// we unconditionally branch to the scalar preheader. Do nothing.
932937
// 3) Otherwise, construct a runtime check.
933938
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock();
934-
auto *VPExitBlock = Plan->createVPIRBasicBlock(IRExitBlock);
939+
VPIRBasicBlock *VPExitBlock = Plan->getExitBlock(IRExitBlock);
935940
// The connection order corresponds to the operands of the conditional branch.
936941
VPBlockUtils::insertBlockAfter(VPExitBlock, MiddleVPBB);
937942
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -983,6 +988,14 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
983988
}
984989
}
985990

991+
VPIRBasicBlock *VPlan::getExitBlock(BasicBlock *IRBB) const {
992+
auto Iter = find_if(getExitBlocks(), [IRBB](const VPIRBasicBlock *VPIRBB) {
993+
return VPIRBB->getIRBasicBlock() == IRBB;
994+
});
995+
assert(Iter != getExitBlocks().end() && "no exit block found");
996+
return *Iter;
997+
}
998+
986999
bool VPlan::isExitBlock(VPBlockBase *VPBB) {
9871000
return isa<VPIRBasicBlock>(VPBB) && VPBB->getNumSuccessors() == 0;
9881001
}

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,6 +3426,11 @@ class VPlan {
34263426
/// VPIRBasicBlock wrapping the header of the original scalar loop.
34273427
VPIRBasicBlock *ScalarHeader;
34283428

3429+
/// Immutable list of VPIRBasicBlocks wrapping the exit blocks of the original
3430+
/// scalar loop. Note that some exit blocks may be unreachable at the moment,
3431+
/// e.g. if the scalar epilogue always executes.
3432+
SmallVector<VPIRBasicBlock *, 2> ExitBlocks;
3433+
34293434
/// Holds the VFs applicable to this VPlan.
34303435
SmallSetVector<ElementCount, 2> VFs;
34313436

@@ -3559,11 +3564,13 @@ class VPlan {
35593564
/// Return the VPIRBasicBlock wrapping the header of the scalar loop.
35603565
VPIRBasicBlock *getScalarHeader() const { return ScalarHeader; }
35613566

3562-
/// Return an iterator range over the VPIRBasicBlock wrapping the exit blocks
3563-
/// of the VPlan, that is leaf nodes except the scalar header. Defined in
3564-
/// VPlanHCFG, as the definition of the type needs access to the definitions
3565-
/// of VPBlockShallowTraversalWrapper.
3566-
auto getExitBlocks();
3567+
/// Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of
3568+
/// the original scalar loop.
3569+
ArrayRef<VPIRBasicBlock *> getExitBlocks() const { return ExitBlocks; }
3570+
3571+
/// Return the VPIRBasicBlock corresponding to \p IRBB. \p IRBB must be an
3572+
/// exit block.
3573+
VPIRBasicBlock *getExitBlock(BasicBlock *IRBB) const;
35673574

35683575
/// Returns true if \p VPBB is an exit block.
35693576
bool isExitBlock(VPBlockBase *VPBB);

llvm/lib/Transforms/Vectorize/VPlanCFG.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,15 +307,6 @@ template <> struct GraphTraits<VPlan *> {
307307
}
308308
};
309309

310-
inline auto VPlan::getExitBlocks() {
311-
VPBlockBase *ScalarHeader = getScalarHeader();
312-
return make_filter_range(
313-
VPBlockUtils::blocksOnly<VPIRBasicBlock>(
314-
vp_depth_first_shallow(getVectorLoopRegion()->getSingleSuccessor())),
315-
[ScalarHeader](VPIRBasicBlock *VPIRBB) {
316-
return VPIRBB != ScalarHeader && VPIRBB->getNumSuccessors() == 0;
317-
});
318-
}
319310
} // namespace llvm
320311

321312
#endif // LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,18 +2049,9 @@ void VPlanTransforms::handleUncountableEarlyExit(
20492049
cast<BranchInst>(UncountableExitingBlock->getTerminator());
20502050
BasicBlock *TrueSucc = EarlyExitingBranch->getSuccessor(0);
20512051
BasicBlock *FalseSucc = EarlyExitingBranch->getSuccessor(1);
2052-
2053-
// The early exit block may or may not be the same as the "countable" exit
2054-
// block. Creates a new VPIRBB for the early exit block in case it is distinct
2055-
// from the countable exit block.
2056-
// TODO: Introduce both exit blocks during VPlan skeleton construction.
2057-
VPIRBasicBlock *VPEarlyExitBlock;
2058-
if (OrigLoop->getUniqueExitBlock()) {
2059-
VPEarlyExitBlock = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors()[0]);
2060-
} else {
2061-
VPEarlyExitBlock = Plan.createVPIRBasicBlock(
2062-
!OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
2063-
}
2052+
BasicBlock *EarlyExitIRBB =
2053+
!OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc;
2054+
VPIRBasicBlock *VPEarlyExitBlock = Plan.getExitBlock(EarlyExitIRBB);
20642055

20652056
VPValue *EarlyExitNotTakenCond = RecipeBuilder.getBlockInMask(
20662057
OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);

0 commit comments

Comments
 (0)