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