@@ -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