Skip to content

Commit 416a508

Browse files
committed
[VPlan] Update vector latch terminator edge to exit block after execution.
Instead of setting the successor to the exit using CFG.ExitBB, set it to nullptr initially. The successor to the exit block is later set either through createEmptyBasicBlock or after VPlan execution (because at the moment, no block is created by VPlan for the exit block, the existing one is reused). This also enables BranchOnCond to be used as terminator for the exiting block of the topmost vector region. Depends on D126618. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D126679
1 parent 29794ab commit 416a508

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
240240
// Hook up the new basic block to its predecessors.
241241
for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors()) {
242242
VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
243-
auto &PredVPSuccessors = PredVPBB->getSuccessors();
243+
auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors();
244244
BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
245245

246246
assert(PredBB && "Predecessor basic-block not found building successor.");
@@ -257,25 +257,13 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
257257
Br->setDebugLoc(DL);
258258
} else if (TermBr && !TermBr->isConditional()) {
259259
TermBr->setSuccessor(0, NewBB);
260-
} else if (PredVPSuccessors.size() == 2) {
260+
} else {
261+
// Set each forward successor here when it is created, excluding
262+
// backedges. A backward successor is set when the branch is created.
261263
unsigned idx = PredVPSuccessors.front() == this ? 0 : 1;
262-
assert(!PredBBTerminator->getSuccessor(idx) &&
264+
assert(!TermBr->getSuccessor(idx) &&
263265
"Trying to reset an existing successor block.");
264-
PredBBTerminator->setSuccessor(idx, NewBB);
265-
} else {
266-
// PredVPBB is the exiting block of a loop region. Connect its successor
267-
// outside the region.
268-
auto *LoopRegion = cast<VPRegionBlock>(PredVPBB->getParent());
269-
assert(!LoopRegion->isReplicator() &&
270-
"predecessor must be in a loop region");
271-
assert(PredVPSuccessors.empty() &&
272-
LoopRegion->getExitingBasicBlock() == PredVPBB &&
273-
"PredVPBB must be the exiting block of its parent region");
274-
assert(this == LoopRegion->getSingleSuccessor() &&
275-
"the current block must be the single successor of the region");
276-
PredBBTerminator->setSuccessor(0, NewBB);
277-
PredBBTerminator->setSuccessor(
278-
1, CFG.VPBB2IRBB[LoopRegion->getEntryBasicBlock()]);
266+
TermBr->setSuccessor(idx, NewBB);
279267
}
280268
}
281269
return NewBB;
@@ -297,6 +285,16 @@ void VPBasicBlock::execute(VPTransformState *State) {
297285
// ExitBB can be re-used for the exit block of the Plan.
298286
NewBB = State->CFG.ExitBB;
299287
State->CFG.PrevBB = NewBB;
288+
289+
// Update the branch instruction in the predecessor to branch to ExitBB.
290+
VPBlockBase *PredVPB = getSingleHierarchicalPredecessor();
291+
VPBasicBlock *ExitingVPBB = PredVPB->getExitingBasicBlock();
292+
assert(PredVPB->getSingleSuccessor() == this &&
293+
"predecessor must have the current block as only successor");
294+
BasicBlock *ExitingBB = State->CFG.VPBB2IRBB[ExitingVPBB];
295+
// The Exit block of a loop is always set to be successor 0 of the Exiting
296+
// block.
297+
cast<BranchInst>(ExitingBB->getTerminator())->setSuccessor(0, NewBB);
300298
} else if (PrevVPBB && /* A */
301299
!((SingleHPred = getSingleHierarchicalPredecessor()) &&
302300
SingleHPred->getExitingBasicBlock() == PrevVPBB &&
@@ -798,11 +796,15 @@ void VPInstruction::generateInstruction(VPTransformState &State,
798796
auto *Plan = getParent()->getPlan();
799797
VPRegionBlock *TopRegion = Plan->getVectorLoopRegion();
800798
VPBasicBlock *Header = TopRegion->getEntry()->getEntryBasicBlock();
801-
// TODO: Once the exit block is modeled in VPlan, use it instead of going
802-
// through State.CFG.ExitBB.
803-
BasicBlock *Exit = State.CFG.ExitBB;
804799

805-
Builder.CreateCondBr(Cond, Exit, State.CFG.VPBB2IRBB[Header]);
800+
// Replace the temporary unreachable terminator with a new conditional
801+
// branch, hooking it up to backward destination (the header) now and to the
802+
// forward destination (the exit/middle block) later when it is created.
803+
// Note that CreateCondBr expects a valid BB as first argument, so we need
804+
// to set it to nullptr later.
805+
BranchInst *CondBr = Builder.CreateCondBr(Cond, Builder.GetInsertBlock(),
806+
State.CFG.VPBB2IRBB[Header]);
807+
CondBr->setSuccessor(0, nullptr);
806808
Builder.GetInsertBlock()->getTerminator()->eraseFromParent();
807809
break;
808810
}

0 commit comments

Comments
 (0)