@@ -336,12 +336,6 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
336
336
return std::move (Plan);
337
337
}
338
338
339
- std::unique_ptr<VPlan> VPlanTransforms::buildPlainCFG (Loop *TheLoop,
340
- LoopInfo &LI) {
341
- PlainCFGBuilder Builder (TheLoop, &LI);
342
- return Builder.buildPlainCFG ();
343
- }
344
-
345
339
// / Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
346
340
// / has exactly 2 predecessors (preheader and latch), where the block
347
341
// / dominates the latch and the preheader dominates the block. If it is a
@@ -457,10 +451,8 @@ static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB,
457
451
LatchDL);
458
452
}
459
453
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) {
464
456
VPDominatorTree VPDT;
465
457
VPDT.recalculate (Plan);
466
458
@@ -486,12 +478,54 @@ void VPlanTransforms::prepareForVectorization(
486
478
487
479
addCanonicalIVRecipes (Plan, HeaderVPBB, LatchVPBB, InductionTy, IVDL);
488
480
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
+
490
523
// Disconnect all early exits from the loop leaving it with a single exit from
491
524
// the latch. Early exits that are countable are left for a scalar epilog. The
492
525
// condition of uncountable early exits (currently at most one is supported)
493
526
// is fused into the latch exit, and used to branch from middle block to the
494
527
// early exit destination.
528
+ [[maybe_unused]] bool HandledUncountableEarlyExit = false ;
495
529
for (VPIRBasicBlock *EB : Plan.getExitBlocks ()) {
496
530
for (VPBlockBase *Pred : to_vector (EB->getPredecessors ())) {
497
531
if (Pred == MiddleVPBB)
@@ -500,7 +534,8 @@ void VPlanTransforms::prepareForVectorization(
500
534
assert (!HandledUncountableEarlyExit &&
501
535
" can handle exactly one uncountable early exit" );
502
536
handleUncountableEarlyExit (cast<VPBasicBlock>(Pred), EB, Plan,
503
- HeaderVPBB, LatchVPBB, Range);
537
+ cast<VPBasicBlock>(HeaderVPB), LatchVPBB,
538
+ Range);
504
539
HandledUncountableEarlyExit = true ;
505
540
} else {
506
541
for (VPRecipeBase &R : EB->phis ())
@@ -513,36 +548,18 @@ void VPlanTransforms::prepareForVectorization(
513
548
514
549
assert ((!HasUncountableEarlyExit || HandledUncountableEarlyExit) &&
515
550
" missed an uncountable exit that must be handled" );
551
+ }
516
552
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 ]);
541
558
// If MiddleVPBB has a single successor then the original loop does not exit
542
559
// via the latch and the single successor must be the scalar preheader.
543
560
// There's no need to add a runtime check to MiddleVPBB.
544
561
if (MiddleVPBB->getNumSuccessors () == 1 ) {
545
- assert (MiddleVPBB->getSingleSuccessor () == ScalarPH &&
562
+ assert (MiddleVPBB->getSingleSuccessor () == Plan. getScalarPreheader () &&
546
563
" must have ScalarPH as single successor" );
547
564
return ;
548
565
}
@@ -564,6 +581,7 @@ void VPlanTransforms::prepareForVectorization(
564
581
// the corresponding compare because they may have ended up with different
565
582
// line numbers and we want to avoid awkward line stepping while debugging.
566
583
// E.g., if the compare has got a line number inside the loop.
584
+ auto *LatchVPBB = cast<VPBasicBlock>(MiddleVPBB->getSinglePredecessor ());
567
585
DebugLoc LatchDL = LatchVPBB->getTerminator ()->getDebugLoc ();
568
586
VPBuilder Builder (MiddleVPBB);
569
587
VPValue *Cmp;
0 commit comments