[llvm] [VPlan] Build initial VPlan 0 using HCFGBuilder for inner loops. (NFC) (PR #124432)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 8 13:05:07 PST 2025
================
@@ -9329,23 +9330,58 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
RecipeBuilder.collectScaledReductions(Range);
auto *MiddleVPBB = Plan->getMiddleBlock();
+
+ // Scan the body of the loop in a topological order to visit each basic block
+ // after having visited its predecessor basic blocks.
+ ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
+ HeaderVPBB);
+
VPBasicBlock::iterator MBIP = MiddleVPBB->getFirstNonPhi();
- for (BasicBlock *BB : make_range(DFS.beginRPO(), DFS.endRPO())) {
- // Relevant instructions from basic block BB will be grouped into VPRecipe
- // ingredients and fill a new VPBasicBlock.
- if (VPBB != HeaderVPBB)
- VPBB->setName(BB->getName());
- Builder.setInsertPoint(VPBB);
+ VPBlockBase *PrevVPBB = nullptr;
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
+ // Skip VPBBs not corresponding to any input IR basic blocks.
+ if (!HCFGBuilder.getIRBBForVPB(VPBB)) {
+ assert(VPBB == LoopRegion->getExiting() &&
+ "only the latch block shouldn't have a corresponding IRBB");
+ VPBlockUtils::connectBlocks(PrevVPBB, VPBB);
+ break;
+ }
- if (VPBB == HeaderVPBB)
+ // Create mask based on the IR BB corresponding to VPBB.
+ // TODO: Predicate directly based on VPlan.
+ Builder.setInsertPoint(VPBB, VPBB->begin());
+ if (VPBB == HeaderVPBB) {
+ Builder.setInsertPoint(VPBB, VPBB->getFirstNonPhi());
RecipeBuilder.createHeaderMask();
- else if (NeedsMasks)
- RecipeBuilder.createBlockInMask(BB);
+ } else if (NeedsMasks) {
+ RecipeBuilder.createBlockInMask(HCFGBuilder.getIRBBForVPB(VPBB));
+ }
+
+ // Convert input VPInstructions to widened recipes.
+ for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
+ auto *SingleDef = cast<VPSingleDefRecipe>(&R);
+ // Skip recipes that do not need transforming, including canonical IV,
+ // wide canonical IV and VPInstructions without underlying values. The
+ // latter is added by masking.
+ if (isa<VPCanonicalIVPHIRecipe>(SingleDef) ||
+ isa<VPWidenCanonicalIVRecipe>(SingleDef) ||
+ (isa<VPInstruction>(&R) && !SingleDef->getUnderlyingValue()))
+ continue;
+ assert(isa<VPWidenPHIRecipe>(&R) || (isa<VPInstruction>(SingleDef) &&
+ SingleDef->getUnderlyingValue()) &&
+ "unsupported recipe");
+
+ if (match(&R, m_BranchOnCond(m_VPValue())) ||
+ (isa<VPInstruction>(&R) &&
+ cast<VPInstruction>(&R)->getOpcode() == Instruction::Switch)) {
+ R.eraseFromParent();
+ break;
+ }
- // Introduce each ingredient into VPlan.
- // TODO: Model and preserve debug intrinsics in VPlan.
- for (Instruction &I : drop_end(BB->instructionsWithoutDebug(false))) {
- Instruction *Instr = &I;
+ // TODO: Gradually replace uses of underlying instruction by analyses on
+ // VPlan.
+ Instruction *Instr = SingleDef->getUnderlyingInstr();
+ Builder.setInsertPoint(SingleDef);
SmallVector<VPValue *, 4> Operands;
auto *Phi = dyn_cast<PHINode>(Instr);
if (Phi && Phi->getParent() == HeaderBB) {
----------------
fhahn wrote:
Done, thanks
https://github.com/llvm/llvm-project/pull/124432
More information about the llvm-commits
mailing list