Skip to content

Commit ef1773a

Browse files
committed
[VPlan] Rewrite cloneSESE to use 2 depth-first passes (NFCI).
Rewrite cloneSESE to perform 2 depth-first passes with the first one cloning blocks and the second one updating the predecessors and successors. This is needed to preserve the correct predecessor/successor ordering with #92651 and has been split off as suggested.
1 parent 31a94bd commit ef1773a

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -655,22 +655,38 @@ static std::pair<VPBlockBase *, VPBlockBase *> cloneSESE(VPBlockBase *Entry);
655655
// cloned region.
656656
static std::pair<VPBlockBase *, VPBlockBase *> cloneSESE(VPBlockBase *Entry) {
657657
DenseMap<VPBlockBase *, VPBlockBase *> Old2NewVPBlocks;
658-
ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
659-
Entry);
660-
for (VPBlockBase *BB : RPOT) {
658+
VPBlockBase *Exiting = nullptr;
659+
// First, clone blocks reachable from Entry.
660+
for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
661661
VPBlockBase *NewBB = BB->clone();
662-
for (VPBlockBase *Pred : BB->getPredecessors())
663-
VPBlockUtils::connectBlocks(Old2NewVPBlocks[Pred], NewBB);
664-
665662
Old2NewVPBlocks[BB] = NewBB;
663+
if (BB->getNumSuccessors() == 0) {
664+
assert(!Exiting && "Multiple exiting blocks?");
665+
Exiting = BB;
666+
}
667+
}
668+
669+
// Second, update the predecessors & successors of the cloned blocks.
670+
for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
671+
VPBlockBase *NewBB = Old2NewVPBlocks[BB];
672+
SmallVector<VPBlockBase *> NewPreds;
673+
for (VPBlockBase *Pred : BB->getPredecessors()) {
674+
NewPreds.push_back(Old2NewVPBlocks[Pred]);
675+
}
676+
NewBB->setPredecessors(NewPreds);
677+
SmallVector<VPBlockBase *> NewSuccs;
678+
for (VPBlockBase *Succ : BB->successors()) {
679+
NewSuccs.push_back(Old2NewVPBlocks[Succ]);
680+
}
681+
NewBB->setSuccessors(NewSuccs);
666682
}
667683

668684
#if !defined(NDEBUG)
669685
// Verify that the order of predecessors and successors matches in the cloned
670686
// version.
671-
ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
672-
NewRPOT(Old2NewVPBlocks[Entry]);
673-
for (const auto &[OldBB, NewBB] : zip(RPOT, NewRPOT)) {
687+
for (const auto &[OldBB, NewBB] :
688+
zip(vp_depth_first_shallow(Entry),
689+
vp_depth_first_shallow(Old2NewVPBlocks[Entry]))) {
674690
for (const auto &[OldPred, NewPred] :
675691
zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
676692
assert(NewPred == Old2NewVPBlocks[OldPred] && "Different predecessors");
@@ -681,8 +697,7 @@ static std::pair<VPBlockBase *, VPBlockBase *> cloneSESE(VPBlockBase *Entry) {
681697
}
682698
#endif
683699

684-
return std::make_pair(Old2NewVPBlocks[Entry],
685-
Old2NewVPBlocks[*reverse(RPOT).begin()]);
700+
return std::make_pair(Old2NewVPBlocks[Entry], Old2NewVPBlocks[Exiting]);
686701
}
687702

688703
VPRegionBlock *VPRegionBlock::clone() {

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,15 @@ class VPBlockBase {
614614
appendPredecessor(Pred);
615615
}
616616

617+
/// Set each VPBasicBlock in \p NewSuccss as successor of this VPBlockBase.
618+
/// This VPBlockBase must have no successors. This VPBlockBase is not added
619+
/// as predecessor of any VPBasicBlock in \p NewSuccs.
620+
void setSuccessors(ArrayRef<VPBlockBase *> NewSuccs) {
621+
assert(Successors.empty() && "Block successors already set.");
622+
for (auto *Succ : NewSuccs)
623+
appendSuccessor(Succ);
624+
}
625+
617626
/// Remove all the predecessor of this block.
618627
void clearPredecessors() { Predecessors.clear(); }
619628

0 commit comments

Comments
 (0)