Skip to content

Commit e950e32

Browse files
committed
[VPlan] Construct immutable VPIRBBs for exit blocks at construction(NFC)
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.
1 parent 0859df4 commit e950e32

File tree

5 files changed

+31
-27
lines changed

5 files changed

+31
-27
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9140,6 +9140,10 @@ collectUsersInExitBlocks(Loop *OrigLoop, VPRecipeBuilder &Builder,
91409140
VPlan &Plan) {
91419141
SetVector<VPIRInstruction *> ExitUsersToFix;
91429142
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks()) {
9143+
// Nothing to do for unreachable exit blocks.
9144+
if (ExitVPBB->getNumPredecessors() == 0)
9145+
continue;
9146+
91439147
for (VPRecipeBase &R : *ExitVPBB) {
91449148
auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
91459149
if (!ExitIRI)

llvm/lib/Transforms/Vectorize/VPlan.cpp

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

856861
VPlan::~VPlan() {
@@ -932,7 +937,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
932937
// we unconditionally branch to the scalar preheader. Do nothing.
933938
// 3) Otherwise, construct a runtime check.
934939
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock();
935-
auto *VPExitBlock = Plan->createVPIRBasicBlock(IRExitBlock);
940+
VPIRBasicBlock *VPExitBlock = Plan->getExitBlock(IRExitBlock);
936941
// The connection order corresponds to the operands of the conditional branch.
937942
VPBlockUtils::insertBlockAfter(VPExitBlock, MiddleVPBB);
938943
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -984,6 +989,12 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
984989
}
985990
}
986991

992+
VPIRBasicBlock *VPlan::getExitBlock(BasicBlock *IRBB) const {
993+
return *find_if(getExitBlocks(), [IRBB](const VPIRBasicBlock *VPIRBB) {
994+
return VPIRBB->getIRBasicBlock() == IRBB;
995+
});
996+
}
997+
987998
bool VPlan::isExitBlock(VPBlockBase *VPBB) {
988999
return isa<VPIRBasicBlock>(VPBB) && VPBB->getNumSuccessors() == 0;
9891000
}

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, e.g. if the
3431+
/// 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)