@@ -240,7 +240,7 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
240
240
// Hook up the new basic block to its predecessors.
241
241
for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors ()) {
242
242
VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock ();
243
- auto &PredVPSuccessors = PredVPBB->getSuccessors ();
243
+ auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors ();
244
244
BasicBlock *PredBB = CFG.VPBB2IRBB [PredVPBB];
245
245
246
246
assert (PredBB && " Predecessor basic-block not found building successor." );
@@ -257,25 +257,13 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
257
257
Br->setDebugLoc (DL);
258
258
} else if (TermBr && !TermBr->isConditional ()) {
259
259
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.
261
263
unsigned idx = PredVPSuccessors.front () == this ? 0 : 1 ;
262
- assert (!PredBBTerminator ->getSuccessor (idx) &&
264
+ assert (!TermBr ->getSuccessor (idx) &&
263
265
" 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);
279
267
}
280
268
}
281
269
return NewBB;
@@ -297,6 +285,16 @@ void VPBasicBlock::execute(VPTransformState *State) {
297
285
// ExitBB can be re-used for the exit block of the Plan.
298
286
NewBB = State->CFG .ExitBB ;
299
287
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);
300
298
} else if (PrevVPBB && /* A */
301
299
!((SingleHPred = getSingleHierarchicalPredecessor ()) &&
302
300
SingleHPred->getExitingBasicBlock () == PrevVPBB &&
@@ -798,11 +796,15 @@ void VPInstruction::generateInstruction(VPTransformState &State,
798
796
auto *Plan = getParent ()->getPlan ();
799
797
VPRegionBlock *TopRegion = Plan->getVectorLoopRegion ();
800
798
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 ;
804
799
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 );
806
808
Builder.GetInsertBlock ()->getTerminator ()->eraseFromParent ();
807
809
break ;
808
810
}
0 commit comments