@@ -182,11 +182,6 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
182
182
" Instruction shouldn't have been visited." );
183
183
184
184
if (auto *Br = dyn_cast<BranchInst>(Inst)) {
185
- if (TheLoop->getLoopLatch () == BB ||
186
- any_of (successors (BB),
187
- [this ](BasicBlock *Succ) { return !TheLoop->contains (Succ); }))
188
- continue ;
189
-
190
185
// Conditional branch instruction are represented using BranchOnCond
191
186
// recipes.
192
187
if (Br->isConditional ()) {
@@ -251,6 +246,8 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG(
251
246
DenseMap<VPBlockBase *, BasicBlock *> &VPB2IRBB) {
252
247
VPIRBasicBlock *Entry = cast<VPIRBasicBlock>(Plan->getEntry ());
253
248
BB2VPBB[Entry->getIRBasicBlock ()] = Entry;
249
+ for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks ())
250
+ BB2VPBB[ExitVPBB->getIRBasicBlock ()] = ExitVPBB;
254
251
255
252
// 1. Scan the body of the loop in a topological order to visit each basic
256
253
// block after having visited its predecessor basic blocks. Create a VPBB for
@@ -276,7 +273,6 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG(
276
273
for (BasicBlock *BB : RPO) {
277
274
// Create or retrieve the VPBasicBlock for this BB.
278
275
VPBasicBlock *VPBB = getOrCreateVPBB (BB);
279
- Loop *LoopForBB = LI->getLoopFor (BB);
280
276
// Set VPBB predecessors in the same order as they are in the incoming BB.
281
277
setVPBBPredsFromBB (VPBB, BB);
282
278
@@ -307,24 +303,12 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG(
307
303
BasicBlock *IRSucc1 = BI->getSuccessor (1 );
308
304
VPBasicBlock *Successor0 = getOrCreateVPBB (IRSucc0);
309
305
VPBasicBlock *Successor1 = getOrCreateVPBB (IRSucc1);
310
-
311
- // Don't connect any blocks outside the current loop except the latches for
312
- // inner loops.
313
- // TODO: Also connect exit blocks during initial VPlan construction.
314
- if (LoopForBB == TheLoop || BB != LoopForBB->getLoopLatch ()) {
315
- if (!LoopForBB->contains (IRSucc0)) {
316
- VPBB->setOneSuccessor (Successor1);
317
- continue ;
318
- }
319
- if (!LoopForBB->contains (IRSucc1)) {
320
- VPBB->setOneSuccessor (Successor0);
321
- continue ;
322
- }
323
- }
324
-
325
306
VPBB->setTwoSuccessors (Successor0, Successor1);
326
307
}
327
308
309
+ for (auto *EB : Plan->getExitBlocks ())
310
+ setVPBBPredsFromBB (EB, EB->getIRBasicBlock ());
311
+
328
312
// 2. The whole CFG has been built at this point so all the input Values must
329
313
// have a VPlan counterpart. Fix VPlan header phi by adding their
330
314
// corresponding VPlan operands.
@@ -424,22 +408,23 @@ static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB) {
424
408
425
409
VPBlockUtils::disconnectBlocks (PreheaderVPBB, HeaderVPB);
426
410
VPBlockUtils::disconnectBlocks (LatchVPBB, HeaderVPB);
427
- VPBlockBase *Succ = LatchVPBB->getSingleSuccessor ();
428
- assert (LatchVPBB->getNumSuccessors () <= 1 &&
429
- " Latch has more than one successor" );
430
- if (Succ)
431
- VPBlockUtils::disconnectBlocks (LatchVPBB, Succ);
432
-
433
- auto *R = Plan.createVPRegionBlock (HeaderVPB, LatchVPBB, " " ,
434
- false /* isReplicator*/ );
435
- // All VPBB's reachable shallowly from HeaderVPB belong to top level loop,
436
- // because VPlan is expected to end at top level latch disconnected above.
411
+ VPBlockBase *LatchExitVPB = LatchVPBB->getSingleSuccessor ();
412
+ assert (LatchExitVPB && " Latch expected to be left with a single successor" );
413
+
414
+ // Create an empty region first and insert it between PreheaderVPBB and
415
+ // LatchExitVPB, taking care to preserve the original predecessor & successor
416
+ // order of blocks. Set region entry and exiting after both HeaderVPB and
417
+ // LatchVPBB have been disconnected from their predecessors/successors.
418
+ auto *R = Plan.createVPRegionBlock (" " , false /* isReplicator*/ );
419
+ VPBlockUtils::insertOnEdge (LatchVPBB, LatchExitVPB, R);
420
+ VPBlockUtils::disconnectBlocks (LatchVPBB, R);
421
+ VPBlockUtils::connectBlocks (PreheaderVPBB, R);
422
+ R->setEntry (HeaderVPB);
423
+ R->setExiting (LatchVPBB);
424
+
425
+ // All VPBB's reachable shallowly from HeaderVPB belong to the current region.
437
426
for (VPBlockBase *VPBB : vp_depth_first_shallow (HeaderVPB))
438
427
VPBB->setParent (R);
439
-
440
- VPBlockUtils::insertBlockAfter (R, PreheaderVPBB);
441
- if (Succ)
442
- VPBlockUtils::connectBlocks (R, Succ);
443
428
}
444
429
445
430
// Add the necessary canonical IV and branch recipes required to control the
@@ -491,12 +476,34 @@ void VPlanTransforms::prepareForVectorization(VPlan &Plan, Type *InductionTy,
491
476
VPBlockUtils::insertBlockAfter (VecPreheader, Plan.getEntry ());
492
477
493
478
VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock (" middle.block" );
494
- VPBlockUtils::connectBlocks (LatchVPB, MiddleVPBB);
495
- LatchVPB->swapSuccessors ();
479
+ // The canonical LatchVPB has the header block as last successor. If it has
480
+ // another successor, this successor is an exit block - insert middle block on
481
+ // its edge. Otherwise, add middle block as another successor retaining header
482
+ // as last.
483
+ if (LatchVPB->getNumSuccessors () == 2 ) {
484
+ VPBlockBase *LatchExitVPB = LatchVPB->getSuccessors ()[0 ];
485
+ VPBlockUtils::insertOnEdge (LatchVPB, LatchExitVPB, MiddleVPBB);
486
+ } else {
487
+ VPBlockUtils::connectBlocks (LatchVPB, MiddleVPBB);
488
+ LatchVPB->swapSuccessors ();
489
+ }
496
490
497
491
addCanonicalIVRecipes (Plan, cast<VPBasicBlock>(HeaderVPB),
498
492
cast<VPBasicBlock>(LatchVPB), InductionTy, IVDL);
499
493
494
+ // Disconnect all edges to exit blocks other than from the middle block.
495
+ // TODO: VPlans with early exits should be explicitly converted to a form
496
+ // exiting only via the latch here, including adjusting the exit condition,
497
+ // instead of simply disconnecting the edges and adjusting the VPlan later.
498
+ for (VPBlockBase *EB : Plan.getExitBlocks ()) {
499
+ for (VPBlockBase *Pred : to_vector (EB->getPredecessors ())) {
500
+ if (Pred == MiddleVPBB)
501
+ continue ;
502
+ cast<VPBasicBlock>(Pred)->getTerminator ()->eraseFromParent ();
503
+ VPBlockUtils::disconnectBlocks (Pred, EB);
504
+ }
505
+ }
506
+
500
507
// Create SCEV and VPValue for the trip count.
501
508
// We use the symbolic max backedge-taken-count, which works also when
502
509
// vectorizing loops with uncountable early exits.
@@ -523,6 +530,8 @@ void VPlanTransforms::prepareForVectorization(VPlan &Plan, Type *InductionTy,
523
530
// 3) Otherwise, construct a runtime check.
524
531
525
532
if (!RequiresScalarEpilogueCheck) {
533
+ if (auto *LatchExitVPB = MiddleVPBB->getSingleSuccessor ())
534
+ VPBlockUtils::disconnectBlocks (MiddleVPBB, LatchExitVPB);
526
535
VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
527
536
// The exit blocks are unreachable, remove their recipes to make sure no
528
537
// users remain that may pessimize transforms.
@@ -533,10 +542,8 @@ void VPlanTransforms::prepareForVectorization(VPlan &Plan, Type *InductionTy,
533
542
return ;
534
543
}
535
544
536
- // The connection order corresponds to the operands of the conditional branch.
537
- BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock ();
538
- auto *VPExitBlock = Plan.getExitBlock (IRExitBlock);
539
- VPBlockUtils::connectBlocks (MiddleVPBB, VPExitBlock);
545
+ // The connection order corresponds to the operands of the conditional branch,
546
+ // with the middle block already connected to the exit block.
540
547
VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
541
548
542
549
auto *ScalarLatchTerm = TheLoop->getLoopLatch ()->getTerminator ();
0 commit comments