@@ -123,6 +123,9 @@ VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
123123 return VPBB;
124124 }
125125
126+ if (!TheLoop->contains (BB))
127+ return Plan.getExitBlock (BB);
128+
126129 // Create new VPBB.
127130 StringRef Name = isHeaderBB (BB, TheLoop) ? " vector.body" : BB->getName ();
128131 LLVM_DEBUG (dbgs () << " Creating VPBasicBlock for " << Name << " \n " );
@@ -156,14 +159,6 @@ bool PlainCFGBuilder::isExternalDef(Value *Val) {
156159 // Instruction definition is in outermost loop PH.
157160 return false ;
158161
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-
167162 // Check whether Instruction definition is in loop body.
168163 return !TheLoop->contains (Inst);
169164}
@@ -212,11 +207,8 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
212207 " Instruction shouldn't have been visited." );
213208
214209 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)
218211 continue ;
219-
220212 // Conditional branch instruction are represented using BranchOnCond
221213 // recipes.
222214 if (Br->isConditional ()) {
@@ -319,6 +311,13 @@ void PlainCFGBuilder::buildPlainCFG(
319311 if (BB == TheLoop->getLoopLatch ()) {
320312 VPBasicBlock *HeaderVPBB = getOrCreateVPBB (LoopForBB->getHeader ());
321313 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+ }
322321 continue ;
323322 }
324323
@@ -349,24 +348,12 @@ void PlainCFGBuilder::buildPlainCFG(
349348 BasicBlock *IRSucc1 = BI->getSuccessor (1 );
350349 VPBasicBlock *Successor0 = getOrCreateVPBB (IRSucc0);
351350 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-
367351 VPBB->setTwoSuccessors (Successor0, Successor1);
368352 }
369353
354+ for (auto *EB : Plan.getExitBlocks ()) {
355+ setVPBBPredsFromBB (EB, EB->getIRBasicBlock ());
356+ }
370357 // 2. The whole CFG has been built at this point so all the input Values must
371358 // have a VPlan counterpart. Fix VPlan header phi by adding their
372359 // corresponding VPlan operands.
@@ -448,6 +435,11 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
448435 VPBasicBlock *OriginalLatch =
449436 cast<VPBasicBlock>(HeaderVPBB->getSinglePredecessor ());
450437 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" );
451443 VPBasicBlock *VecPreheader = Plan.createVPBasicBlock (" vector.ph" );
452444 VPBlockUtils::connectBlocks (Plan.getEntry (), VecPreheader);
453445 assert (OriginalLatch->getNumSuccessors () == 0 &&
@@ -473,8 +465,12 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
473465 HeaderVPBB, LatchVPBB, " vector loop" , false /* isReplicator*/ );
474466 // All VPBB's reachable shallowly from HeaderVPBB belong to top level loop,
475467 // 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+ }
478474
479475 VPBlockUtils::insertBlockAfter (TopRegion, VecPreheader);
480476 VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock (" middle.block" );
@@ -503,7 +499,7 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
503499 BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock ();
504500 auto *VPExitBlock = Plan.getExitBlock (IRExitBlock);
505501 // The connection order corresponds to the operands of the conditional branch.
506- VPBlockUtils::insertBlockAfter (VPExitBlock, MiddleVPBB );
502+ VPBlockUtils::connectBlocks (MiddleVPBB, VPExitBlock );
507503 VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
508504
509505 auto *ScalarLatchTerm = TheLoop->getLoopLatch ()->getTerminator ();
@@ -522,5 +518,8 @@ void VPlanTransforms::introduceTopLevelVectorLoopRegion(
522518 Builder.createNaryOp (VPInstruction::BranchOnCond, {Cmp},
523519 ScalarLatchTerm->getDebugLoc ());
524520
525- introduceInnerLoopRegions (Plan);
521+ if (all_of (Plan.getExitBlocks (), [MiddleVPBB](VPBlockBase *EB) {
522+ return EB->getSinglePredecessor () == MiddleVPBB;
523+ }))
524+ introduceInnerLoopRegions (Plan);
526525}
0 commit comments