@@ -336,12 +336,6 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
336336 return std::move (Plan);
337337}
338338
339- std::unique_ptr<VPlan> VPlanTransforms::buildPlainCFG (Loop *TheLoop,
340- LoopInfo &LI) {
341- PlainCFGBuilder Builder (TheLoop, &LI);
342- return Builder.buildPlainCFG ();
343- }
344-
345339// / Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
346340// / has exactly 2 predecessors (preheader and latch), where the block
347341// / dominates the latch and the preheader dominates the block. If it is a
@@ -457,10 +451,8 @@ static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB,
457451 LatchDL);
458452}
459453
460- void VPlanTransforms::prepareForVectorization (
461- VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE,
462- bool RequiresScalarEpilogueCheck, bool TailFolded, Loop *TheLoop,
463- DebugLoc IVDL, bool HasUncountableEarlyExit, VFRange &Range) {
454+ static void addInitialSkeleton (VPlan &Plan, Type *InductionTy, DebugLoc IVDL,
455+ PredicatedScalarEvolution &PSE, Loop *TheLoop) {
464456 VPDominatorTree VPDT;
465457 VPDT.recalculate (Plan);
466458
@@ -486,12 +478,54 @@ void VPlanTransforms::prepareForVectorization(
486478
487479 addCanonicalIVRecipes (Plan, HeaderVPBB, LatchVPBB, InductionTy, IVDL);
488480
489- [[maybe_unused]] bool HandledUncountableEarlyExit = false ;
481+ // Create SCEV and VPValue for the trip count.
482+ // We use the symbolic max backedge-taken-count, which works also when
483+ // vectorizing loops with uncountable early exits.
484+ const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount ();
485+ assert (!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
486+ " Invalid backedge-taken count" );
487+ ScalarEvolution &SE = *PSE.getSE ();
488+ const SCEV *TripCount = SE.getTripCountFromExitCount (BackedgeTakenCountSCEV,
489+ InductionTy, TheLoop);
490+ Plan.setTripCount (
491+ vputils::getOrCreateVPValueForSCEVExpr (Plan, TripCount, SE));
492+
493+ VPBasicBlock *ScalarPH = Plan.createVPBasicBlock (" scalar.ph" );
494+ VPBlockUtils::connectBlocks (ScalarPH, Plan.getScalarHeader ());
495+
496+ // The connection order corresponds to the operands of the conditional branch,
497+ // with the middle block already connected to the exit block.
498+ VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
499+ // Also connect the entry block to the scalar preheader.
500+ // TODO: Also introduce a branch recipe together with the minimum trip count
501+ // check.
502+ VPBlockUtils::connectBlocks (Plan.getEntry (), ScalarPH);
503+ Plan.getEntry ()->swapSuccessors ();
504+ }
505+
506+ std::unique_ptr<VPlan>
507+ VPlanTransforms::buildVPlan0 (Loop *TheLoop, LoopInfo &LI, Type *InductionTy,
508+ DebugLoc IVDL, PredicatedScalarEvolution &PSE) {
509+ PlainCFGBuilder Builder (TheLoop, &LI);
510+ std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG ();
511+ addInitialSkeleton (*VPlan0, InductionTy, IVDL, PSE, TheLoop);
512+ return VPlan0;
513+ }
514+
515+ void VPlanTransforms::handleEarlyExits (VPlan &Plan,
516+ bool HasUncountableEarlyExit,
517+ VFRange &Range) {
518+ auto *MiddleVPBB = cast<VPBasicBlock>(
519+ Plan.getScalarHeader ()->getSinglePredecessor ()->getPredecessors ()[0 ]);
520+ auto *LatchVPBB = cast<VPBasicBlock>(MiddleVPBB->getSinglePredecessor ());
521+ VPBlockBase *HeaderVPB = cast<VPBasicBlock>(LatchVPBB->getSuccessors ()[1 ]);
522+
490523 // Disconnect all early exits from the loop leaving it with a single exit from
491524 // the latch. Early exits that are countable are left for a scalar epilog. The
492525 // condition of uncountable early exits (currently at most one is supported)
493526 // is fused into the latch exit, and used to branch from middle block to the
494527 // early exit destination.
528+ [[maybe_unused]] bool HandledUncountableEarlyExit = false ;
495529 for (VPIRBasicBlock *EB : Plan.getExitBlocks ()) {
496530 for (VPBlockBase *Pred : to_vector (EB->getPredecessors ())) {
497531 if (Pred == MiddleVPBB)
@@ -500,7 +534,8 @@ void VPlanTransforms::prepareForVectorization(
500534 assert (!HandledUncountableEarlyExit &&
501535 " can handle exactly one uncountable early exit" );
502536 handleUncountableEarlyExit (cast<VPBasicBlock>(Pred), EB, Plan,
503- HeaderVPBB, LatchVPBB, Range);
537+ cast<VPBasicBlock>(HeaderVPB), LatchVPBB,
538+ Range);
504539 HandledUncountableEarlyExit = true ;
505540 } else {
506541 for (VPRecipeBase &R : EB->phis ())
@@ -513,36 +548,18 @@ void VPlanTransforms::prepareForVectorization(
513548
514549 assert ((!HasUncountableEarlyExit || HandledUncountableEarlyExit) &&
515550 " missed an uncountable exit that must be handled" );
551+ }
516552
517- // Create SCEV and VPValue for the trip count.
518- // We use the symbolic max backedge-taken-count, which works also when
519- // vectorizing loops with uncountable early exits.
520- const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount ();
521- assert (!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
522- " Invalid loop count" );
523- ScalarEvolution &SE = *PSE.getSE ();
524- const SCEV *TripCount = SE.getTripCountFromExitCount (BackedgeTakenCountSCEV,
525- InductionTy, TheLoop);
526- Plan.setTripCount (
527- vputils::getOrCreateVPValueForSCEVExpr (Plan, TripCount, SE));
528-
529- VPBasicBlock *ScalarPH = Plan.createVPBasicBlock (" scalar.ph" );
530- VPBlockUtils::connectBlocks (ScalarPH, Plan.getScalarHeader ());
531-
532- // The connection order corresponds to the operands of the conditional branch,
533- // with the middle block already connected to the exit block.
534- VPBlockUtils::connectBlocks (MiddleVPBB, ScalarPH);
535- // Also connect the entry block to the scalar preheader.
536- // TODO: Also introduce a branch recipe together with the minimum trip count
537- // check.
538- VPBlockUtils::connectBlocks (Plan.getEntry (), ScalarPH);
539- Plan.getEntry ()->swapSuccessors ();
540-
553+ void VPlanTransforms::addMiddleCheck (VPlan &Plan,
554+ bool RequiresScalarEpilogueCheck,
555+ bool TailFolded) {
556+ auto *MiddleVPBB = cast<VPBasicBlock>(
557+ Plan.getScalarHeader ()->getSinglePredecessor ()->getPredecessors ()[0 ]);
541558 // If MiddleVPBB has a single successor then the original loop does not exit
542559 // via the latch and the single successor must be the scalar preheader.
543560 // There's no need to add a runtime check to MiddleVPBB.
544561 if (MiddleVPBB->getNumSuccessors () == 1 ) {
545- assert (MiddleVPBB->getSingleSuccessor () == ScalarPH &&
562+ assert (MiddleVPBB->getSingleSuccessor () == Plan. getScalarPreheader () &&
546563 " must have ScalarPH as single successor" );
547564 return ;
548565 }
@@ -564,6 +581,7 @@ void VPlanTransforms::prepareForVectorization(
564581 // the corresponding compare because they may have ended up with different
565582 // line numbers and we want to avoid awkward line stepping while debugging.
566583 // E.g., if the compare has got a line number inside the loop.
584+ auto *LatchVPBB = cast<VPBasicBlock>(MiddleVPBB->getSinglePredecessor ());
567585 DebugLoc LatchDL = LatchVPBB->getTerminator ()->getDebugLoc ();
568586 VPBuilder Builder (MiddleVPBB);
569587 VPValue *Cmp;
0 commit comments