@@ -123,6 +123,9 @@ VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
123
123
return VPBB;
124
124
}
125
125
126
+ if (!TheLoop->contains (BB))
127
+ return Plan.getExitBlock (BB);
128
+
126
129
// Create new VPBB.
127
130
StringRef Name = isHeaderBB (BB, TheLoop) ? " vector.body" : BB->getName ();
128
131
LLVM_DEBUG (dbgs () << " Creating VPBasicBlock for " << Name << " \n " );
@@ -156,14 +159,6 @@ bool PlainCFGBuilder::isExternalDef(Value *Val) {
156
159
// Instruction definition is in outermost loop PH.
157
160
return false ;
158
161
159
- // Check whether Instruction definition is in a loop exit.
160
- SmallVector<BasicBlock *> ExitBlocks;
161
- TheLoop->getExitBlocks (ExitBlocks);
162
- if (is_contained (ExitBlocks, InstParent)) {
163
- // Instruction definition is in outermost loop exit.
164
- return false ;
165
- }
166
-
167
162
// Check whether Instruction definition is in loop body.
168
163
return !TheLoop->contains (Inst);
169
164
}
@@ -212,11 +207,8 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
212
207
" Instruction shouldn't have been visited." );
213
208
214
209
if (auto *Br = dyn_cast<BranchInst>(Inst)) {
215
- if (TheLoop->getLoopLatch () == BB ||
216
- any_of (successors (BB),
217
- [this ](BasicBlock *Succ) { return !TheLoop->contains (Succ); }))
210
+ if (TheLoop->getLoopLatch () == BB)
218
211
continue ;
219
-
220
212
// Conditional branch instruction are represented using BranchOnCond
221
213
// recipes.
222
214
if (Br->isConditional ()) {
@@ -319,6 +311,13 @@ void PlainCFGBuilder::buildPlainCFG(
319
311
if (BB == TheLoop->getLoopLatch ()) {
320
312
VPBasicBlock *HeaderVPBB = getOrCreateVPBB (LoopForBB->getHeader ());
321
313
VPBlockUtils::connectBlocks (VPBB, HeaderVPBB);
314
+ assert (isa<BranchInst>(BB->getTerminator ()) && " latch must be terminated by branch"
315
+ );
316
+ for (BasicBlock *IRSucc : successors (BB)) {
317
+ VPBasicBlock *VPSucc = getOrCreateVPBB (IRSucc);
318
+ if (VPSucc != HeaderVPBB)
319
+ VPBB->getSuccessors ().push_back (VPSucc);
320
+ }
322
321
continue ;
323
322
}
324
323
@@ -349,24 +348,12 @@ void PlainCFGBuilder::buildPlainCFG(
349
348
BasicBlock *IRSucc1 = BI->getSuccessor (1 );
350
349
VPBasicBlock *Successor0 = getOrCreateVPBB (IRSucc0);
351
350
VPBasicBlock *Successor1 = getOrCreateVPBB (IRSucc1);
352
-
353
- // Don't connect any blocks outside the current loop except the latch, which
354
- // is handled below.
355
- if (LoopForBB &&
356
- (LoopForBB == TheLoop || BB != LoopForBB->getLoopLatch ())) {
357
- if (!LoopForBB->contains (IRSucc0)) {
358
- VPBB->setOneSuccessor (Successor1);
359
- continue ;
360
- }
361
- if (!LoopForBB->contains (IRSucc1)) {
362
- VPBB->setOneSuccessor (Successor0);
363
- continue ;
364
- }
365
- }
366
-
367
351
VPBB->setTwoSuccessors (Successor0, Successor1);
368
352
}
369
353
354
+ for (auto *EB : Plan.getExitBlocks ()) {
355
+ setVPBBPredsFromBB (EB, EB->getIRBasicBlock ());
356
+ }
370
357
// 2. The whole CFG has been built at this point so all the input Values must
371
358
// have a VPlan counterpart. Fix VPlan header phi by adding their
372
359
// corresponding VPlan operands.
@@ -448,6 +435,11 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
448
435
VPBasicBlock *OriginalLatch =
449
436
cast<VPBasicBlock>(HeaderVPBB->getSinglePredecessor ());
450
437
VPBlockUtils::disconnectBlocks (OriginalLatch, HeaderVPBB);
438
+ if (auto *RemainingSucc = OriginalLatch->getSingleSuccessor ())
439
+ VPBlockUtils::disconnectBlocks (OriginalLatch,
440
+ RemainingSucc);
441
+ else
442
+ assert (OriginalLatch->getSuccessors ().empty () && " Unsupported number of successors" );
451
443
VPBasicBlock *VecPreheader = Plan.createVPBasicBlock (" vector.ph" );
452
444
VPBlockUtils::connectBlocks (Plan.getEntry (), VecPreheader);
453
445
assert (OriginalLatch->getNumSuccessors () == 0 &&
@@ -473,8 +465,12 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
473
465
HeaderVPBB, LatchVPBB, " vector loop" , false /* isReplicator*/ );
474
466
// All VPBB's reachable shallowly from HeaderVPBB belong to top level loop,
475
467
// because VPlan is expected to end at top level latch.
476
- for (VPBlockBase *VPBB : vp_depth_first_shallow (HeaderVPBB))
477
- VPBB->setParent (TopRegion);
468
+ SmallPtrSet<VPBlockBase *, 2 > ExitBlocks (Plan.getExitBlocks ().begin (),
469
+ Plan.getExitBlocks ().end ());
470
+ for (VPBlockBase *VPBB : vp_depth_first_shallow (HeaderVPBB)) {
471
+ if (!ExitBlocks.contains (VPBB))
472
+ VPBB->setParent (TopRegion);
473
+ }
478
474
479
475
VPBlockUtils::insertBlockAfter (TopRegion, VecPreheader);
480
476
VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock (" middle.block" );
@@ -503,7 +499,7 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
503
499
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock ();
504
500
auto *VPExitBlock = Plan.getExitBlock (IRExitBlock);
505
501
// The connection order corresponds to the operands of the conditional branch.
506
- VPBlockUtils::insertBlockAfter (VPExitBlock, MiddleVPBB );
502
+ VPBlockUtils::connectBlocks (MiddleVPBB, VPExitBlock );
507
503
VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
508
504
509
505
auto *ScalarLatchTerm = TheLoop->getLoopLatch ()->getTerminator ();
@@ -522,5 +518,8 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
522
518
Builder.createNaryOp (VPInstruction::BranchOnCond, {Cmp},
523
519
ScalarLatchTerm->getDebugLoc ());
524
520
525
- introduceInnerLoopRegions (Plan);
521
+ if (all_of (Plan.getExitBlocks (), [MiddleVPBB](VPBlockBase *EB) {
522
+ return EB->getSinglePredecessor () == MiddleVPBB;
523
+ }))
524
+ introduceInnerLoopRegions (Plan);
526
525
}
0 commit comments