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