Skip to content

Commit 389ab09

Browse files
committed
[NFC][LoopVectorize] Make replaceVPBBWithIRVPBB more efficient
In replaceVPBBWithIRVPBB we spend time erasing and appending predecessors and successors from a list, when all we really have to do is replace the old with the new. Not only is this more efficient, but it also preserves the ordering of successors and predecessors. This is something which may become important for vectorising early exit loops (see PR #88385), since a VPIRInstruction is the wrapper for a live-out phi with extra operands that map to the incoming block according to the block's predecessor.
1 parent 66b2820 commit 389ab09

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,12 +1005,14 @@ static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
10051005
R.moveBefore(*IRVPBB, IRVPBB->end());
10061006
}
10071007
VPBlockBase *PredVPBB = VPBB->getSinglePredecessor();
1008-
VPBlockUtils::disconnectBlocks(PredVPBB, VPBB);
1009-
VPBlockUtils::connectBlocks(PredVPBB, IRVPBB);
1010-
for (auto *Succ : to_vector(VPBB->getSuccessors())) {
1011-
VPBlockUtils::connectBlocks(IRVPBB, Succ);
1012-
VPBlockUtils::disconnectBlocks(VPBB, Succ);
1013-
}
1008+
PredVPBB->replaceSuccessor(VPBB, IRVPBB);
1009+
IRVPBB->setPredecessors({PredVPBB});
1010+
for (auto *Succ : to_vector(VPBB->getSuccessors()))
1011+
Succ->replacePredecessor(VPBB, IRVPBB);
1012+
IRVPBB->setSuccessors(VPBB->getSuccessors());
1013+
1014+
VPBB->clearSuccessors();
1015+
VPBB->clearPredecessors();
10141016
delete VPBB;
10151017
}
10161018

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,26 @@ class VPBlockBase {
556556
return getEnclosingBlockWithPredecessors()->getSinglePredecessor();
557557
}
558558

559+
/// This function replaces one predecessor with another, useful when
560+
/// trying to replace an old block in the CFG with a new one.
561+
void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
562+
auto I = find(Predecessors, Old);
563+
assert(I != Predecessors.end());
564+
assert(Old->getParent() == New->getParent() &&
565+
"replaced predecessor must have the same parent");
566+
*I = New;
567+
}
568+
569+
/// This function replaces one successor with another, useful when
570+
/// trying to replace an old block in the CFG with a new one.
571+
void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
572+
auto I = find(Successors, Old);
573+
assert(I != Successors.end());
574+
assert(Old->getParent() == New->getParent() &&
575+
"replaced successor must have the same parent");
576+
*I = New;
577+
}
578+
559579
/// Set a given VPBlockBase \p Successor as the single successor of this
560580
/// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor.
561581
/// This VPBlockBase must have no successors.

0 commit comments

Comments
 (0)