[llvm] [VPlan] Dispatch to multiple exit blocks via middle blocks. (PR #112138)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 10 10:19:52 PST 2024
================
@@ -1838,3 +1838,61 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan) {
}
}
}
+
+void VPlanTransforms::handleUncountableEarlyExit(
+ VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop,
+ BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder) {
+ VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
+ auto *LatchVPBB = cast<VPBasicBlock>(LoopRegion->getExiting());
+ VPBuilder Builder(LatchVPBB->getTerminator());
+ auto *MiddleVPBB = Plan.getMiddleBlock();
+ VPValue *IsEarlyExitTaken = nullptr;
+
+ // Process the uncountable exiting block. Update IsEarlyExitTaken, which
+ // tracks if the uncountable early exit has been taken. Also split the middle
+ // block and have it conditionally branch to the early exit block if
+ // EarlyExitTaken.
+ auto *EarlyExitingBranch =
+ cast<BranchInst>(UncountableExitingBlock->getTerminator());
+ BasicBlock *TrueSucc = EarlyExitingBranch->getSuccessor(0);
+ BasicBlock *FalseSucc = EarlyExitingBranch->getSuccessor(1);
+
+ // The early exit block may or may not be the same as the "countable" exit
+ // block. Creates a new VPIRBB for the early exit block in case it is distinct
+ // from the countable exit block.
+ // TODO: Introduce both exit blocks during VPlan skeleton construction.
+ VPIRBasicBlock *VPEarlyExitBlock;
+ if (OrigLoop->getUniqueExitBlock()) {
+ VPEarlyExitBlock = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors()[0]);
+ } else {
+ VPEarlyExitBlock = VPIRBasicBlock::fromBasicBlock(
+ !OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
+ }
+
+ VPValue *EarlyExitNotTakenCond = RecipeBuilder.getBlockInMask(
+ OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
+ auto *EarlyExitTakenCond = Builder.createNot(EarlyExitNotTakenCond);
+ IsEarlyExitTaken =
+ Builder.createNaryOp(VPInstruction::AnyOf, {EarlyExitTakenCond});
+
+ VPBasicBlock *NewMiddle = new VPBasicBlock("middle.split");
+ VPBlockUtils::insertOnEdge(LoopRegion, MiddleVPBB, NewMiddle);
+ VPBlockUtils::connectBlocks(NewMiddle, VPEarlyExitBlock);
+ std::swap(NewMiddle->getSuccessors()[0], NewMiddle->getSuccessors()[1]);
+
+ VPBuilder MiddleBuilder(NewMiddle);
+ MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {IsEarlyExitTaken});
+
+ // Replace the condition controlling the non-early exit from the vector loop
+ // with one exiting if either the original condition of the vector latch is
+ // true or the early exit has been taken.
+ auto *LatchExitingBranch =
+ dyn_cast<VPInstruction>(LatchVPBB->getTerminator());
----------------
ayalz wrote:
```suggestion
cast<VPInstruction>(LatchVPBB->getTerminator());
```
https://github.com/llvm/llvm-project/pull/112138
More information about the llvm-commits
mailing list