@@ -2487,64 +2487,75 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan,
2487
2487
R->eraseFromParent ();
2488
2488
}
2489
2489
2490
- void VPlanTransforms::handleUncountableEarlyExit (
2491
- VPlan &Plan, Loop *OrigLoop, BasicBlock *UncountableExitingBlock,
2492
- VPRecipeBuilder &RecipeBuilder, VFRange &Range) {
2493
- VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion ();
2494
- auto *LatchVPBB = cast<VPBasicBlock>(LoopRegion->getExiting ());
2490
+ void VPlanTransforms::handleUncountableEarlyExit (VPlan &Plan,
2491
+ VPBasicBlock *HeaderVPBB,
2492
+ VPBasicBlock *LatchVPBB,
2493
+ VFRange &Range) {
2494
+ // First find the uncountable early exiting block by looking at the
2495
+ // predecessors of the exit blocks.
2496
+ VPBlockBase *MiddleVPBB = LatchVPBB->getSuccessors ()[0 ];
2497
+ VPBasicBlock *EarlyExitingVPBB = nullptr ;
2498
+ VPIRBasicBlock *EarlyExitVPBB = nullptr ;
2499
+ for (auto *EB : Plan.getExitBlocks ()) {
2500
+ for (VPBlockBase *Pred : EB->getPredecessors ()) {
2501
+ if (Pred != MiddleVPBB) {
2502
+ EarlyExitingVPBB = cast<VPBasicBlock>(Pred);
2503
+ EarlyExitVPBB = EB;
2504
+ break ;
2505
+ }
2506
+ }
2507
+ }
2508
+
2495
2509
VPBuilder Builder (LatchVPBB->getTerminator ());
2496
- auto *MiddleVPBB = Plan.getMiddleBlock ();
2497
- VPValue *IsEarlyExitTaken = nullptr ;
2498
-
2499
- // Process the uncountable exiting block. Update IsEarlyExitTaken, which
2500
- // tracks if the uncountable early exit has been taken. Also split the middle
2501
- // block and have it conditionally branch to the early exit block if
2502
- // EarlyExitTaken.
2503
- auto *EarlyExitingBranch =
2504
- cast<BranchInst>(UncountableExitingBlock->getTerminator ());
2505
- BasicBlock *TrueSucc = EarlyExitingBranch->getSuccessor (0 );
2506
- BasicBlock *FalseSucc = EarlyExitingBranch->getSuccessor (1 );
2507
- BasicBlock *EarlyExitIRBB =
2508
- !OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc;
2509
- VPIRBasicBlock *VPEarlyExitBlock = Plan.getExitBlock (EarlyExitIRBB);
2510
-
2511
- VPValue *EarlyExitNotTakenCond = RecipeBuilder.getBlockInMask (
2512
- OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc);
2513
- auto *EarlyExitTakenCond = Builder.createNot (EarlyExitNotTakenCond);
2514
- IsEarlyExitTaken =
2515
- Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
2510
+ VPBlockBase *TrueSucc = EarlyExitingVPBB->getSuccessors ()[0 ];
2511
+ VPValue *EarlyExitCond = EarlyExitingVPBB->getTerminator ()->getOperand (0 );
2512
+ auto *EarlyExitTakenCond = TrueSucc == EarlyExitVPBB
2513
+ ? EarlyExitCond
2514
+ : Builder.createNot (EarlyExitCond);
2515
+
2516
+ if (!EarlyExitVPBB->getSinglePredecessor () &&
2517
+ EarlyExitVPBB->getPredecessors ()[0 ] != MiddleVPBB) {
2518
+ for (VPRecipeBase &R : EarlyExitVPBB->phis ()) {
2519
+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
2520
+ // a single predecessor and 1 if it has two.
2521
+ // If EarlyExitVPBB has two predecessors, they are already ordered such
2522
+ // that early exit is second (and latch exit is first), by construction.
2523
+ // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2524
+ // ordered the other way around, and it is the order of the latter which
2525
+ // corresponds to the order of operands of EarlyExitVPBB's phi recipes.
2526
+ // Therefore, if early exit (UncountableExitingBlock) is the first
2527
+ // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2528
+ // thereby bringing them to match EarlyExitVPBB's predecessor order,
2529
+ // with early exit being last (second). Otherwise they already match.
2530
+ cast<VPIRPhi>(&R)->swapOperands ();
2531
+ }
2532
+ }
2516
2533
2534
+ EarlyExitingVPBB->getTerminator ()->eraseFromParent ();
2535
+ VPBlockUtils::disconnectBlocks (EarlyExitingVPBB, EarlyExitVPBB);
2536
+
2537
+ // Split the middle block and have it conditionally branch to the early exit
2538
+ // block if EarlyExitTaken.
2539
+ VPValue *IsEarlyExitTaken =
2540
+ Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
2517
2541
VPBasicBlock *NewMiddle = Plan.createVPBasicBlock (" middle.split" );
2518
2542
VPBasicBlock *VectorEarlyExitVPBB =
2519
2543
Plan.createVPBasicBlock (" vector.early.exit" );
2520
- VPBlockUtils::insertOnEdge (LoopRegion , MiddleVPBB, NewMiddle);
2544
+ VPBlockUtils::insertOnEdge (LatchVPBB , MiddleVPBB, NewMiddle);
2521
2545
VPBlockUtils::connectBlocks (NewMiddle, VectorEarlyExitVPBB);
2522
2546
NewMiddle->swapSuccessors ();
2523
2547
2524
- VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, VPEarlyExitBlock );
2548
+ VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, EarlyExitVPBB );
2525
2549
2526
2550
// Update the exit phis in the early exit block.
2527
2551
VPBuilder MiddleBuilder (NewMiddle);
2528
2552
VPBuilder EarlyExitB (VectorEarlyExitVPBB);
2529
- for (VPRecipeBase &R : VPEarlyExitBlock ->phis ()) {
2553
+ for (VPRecipeBase &R : EarlyExitVPBB ->phis ()) {
2530
2554
auto *ExitIRI = cast<VPIRPhi>(&R);
2531
- // Early exit operand should always be last, i.e., 0 if VPEarlyExitBlock has
2555
+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
2532
2556
// a single predecessor and 1 if it has two.
2533
2557
unsigned EarlyExitIdx = ExitIRI->getNumOperands () - 1 ;
2534
- if (!VPEarlyExitBlock->getSinglePredecessor ()) {
2535
- // If VPEarlyExitBlock has two predecessors, they are already ordered such
2536
- // that early exit is second (and latch exit is first), by construction.
2537
- // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2538
- // ordered the other way around, and it is the order of the latter which
2539
- // corresponds to the order of operands of VPEarlyExitBlock's phi recipes.
2540
- // Therefore, if early exit (UncountableExitingBlock) is the first
2541
- // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2542
- // thereby bringing them to match VPEarlyExitBlock's predecessor order,
2543
- // with early exit being last (second). Otherwise they already match.
2544
- if (*pred_begin (VPEarlyExitBlock->getIRBasicBlock ()) ==
2545
- UncountableExitingBlock)
2546
- ExitIRI->swapOperands ();
2547
-
2558
+ if (!EarlyExitVPBB->getSinglePredecessor ()) {
2548
2559
// The first of two operands corresponds to the latch exit, via MiddleVPBB
2549
2560
// predecessor. Extract its last lane.
2550
2561
ExitIRI->extractLastLaneOfFirstOperand (MiddleBuilder);
0 commit comments