Skip to content

Commit c7ebe4f

Browse files
committed
[VPlan] Replace VPBBs with VPIRBBs during skeleton creation (NFC).
Move replacement of VPBBs for vector preheader, middle block and scalar preheader from VPlan::execute to skeleton creation, which actually creates the IR basic blocks. For now, the vector preheader can only be replaced after prepareToExecute as it may create new instructions in the vector preheader.
1 parent 418dedc commit c7ebe4f

File tree

2 files changed

+21
-28
lines changed

2 files changed

+21
-28
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,21 @@ BasicBlock *InnerLoopVectorizer::emitMemRuntimeChecks(BasicBlock *Bypass) {
26032603
return MemCheckBlock;
26042604
}
26052605

2606+
/// Replace \p VPBB with a VPIRBasicBlock wrapping \p IRBB. All recipes from \p
2607+
/// VPBB are moved to the end of the newly created VPIRBasicBlock. VPBB must
2608+
/// have a single predecessor, which is rewired to the new VPIRBasicBlock. All
2609+
/// successors of VPBB, if any, are rewired to the new VPIRBasicBlock.
2610+
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
2611+
VPIRBasicBlock *IRVPBB = VPBB->getPlan()->createVPIRBasicBlock(IRBB);
2612+
for (auto &R : make_early_inc_range(*VPBB)) {
2613+
assert(!R.isPhi() && "Tried to move phi recipe to end of block");
2614+
R.moveBefore(*IRVPBB, IRVPBB->end());
2615+
}
2616+
2617+
VPBlockUtils::reassociateBlocks(VPBB, IRVPBB);
2618+
// VPBB is now dead and will be cleaned up when the plan gets destroyed.
2619+
}
2620+
26062621
void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
26072622
LoopVectorPreHeader = OrigLoop->getLoopPreheader();
26082623
assert(LoopVectorPreHeader && "Invalid loop structure");
@@ -2613,9 +2628,11 @@ void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
26132628
LoopMiddleBlock =
26142629
SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
26152630
LI, nullptr, Twine(Prefix) + "middle.block");
2631+
replaceVPBBWithIRVPBB(Plan.getMiddleBlock(), LoopMiddleBlock);
26162632
LoopScalarPreHeader =
26172633
SplitBlock(LoopMiddleBlock, LoopMiddleBlock->getTerminator(), DT, LI,
26182634
nullptr, Twine(Prefix) + "scalar.ph");
2635+
replaceVPBBWithIRVPBB(Plan.getScalarPreheader(), LoopScalarPreHeader);
26192636
}
26202637

26212638
/// Return the expanded step for \p ID using \p ExpandedSCEVs to look up SCEV
@@ -7757,6 +7774,7 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
77577774
BestVPlan.prepareToExecute(
77587775
ILV.getTripCount(),
77597776
ILV.getOrCreateVectorTripCount(ILV.LoopVectorPreHeader), State);
7777+
replaceVPBBWithIRVPBB(BestVPlan.getVectorPreheader(), State.CFG.PrevBB);
77607778

77617779
BestVPlan.execute(&State);
77627780

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -949,47 +949,20 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
949949
}
950950
}
951951

952-
/// Replace \p VPBB with a VPIRBasicBlock wrapping \p IRBB. All recipes from \p
953-
/// VPBB are moved to the end of the newly created VPIRBasicBlock. VPBB must
954-
/// have a single predecessor, which is rewired to the new VPIRBasicBlock. All
955-
/// successors of VPBB, if any, are rewired to the new VPIRBasicBlock.
956-
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
957-
VPIRBasicBlock *IRVPBB = VPBB->getPlan()->createVPIRBasicBlock(IRBB);
958-
for (auto &R : make_early_inc_range(*VPBB)) {
959-
assert(!R.isPhi() && "Tried to move phi recipe to end of block");
960-
R.moveBefore(*IRVPBB, IRVPBB->end());
961-
}
962-
963-
VPBlockUtils::reassociateBlocks(VPBB, IRVPBB);
964-
// VPBB is now dead and will be cleaned up when the plan gets destroyed.
965-
}
966-
967952
/// Generate the code inside the preheader and body of the vectorized loop.
968953
/// Assumes a single pre-header basic-block was created for this. Introduce
969954
/// additional basic-blocks as needed, and fill them all.
970955
void VPlan::execute(VPTransformState *State) {
971956
// Initialize CFG state.
972957
State->CFG.PrevVPBB = nullptr;
973958
State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
974-
BasicBlock *VectorPreHeader = State->CFG.PrevBB;
975-
State->Builder.SetInsertPoint(VectorPreHeader->getTerminator());
976959

977960
// Disconnect VectorPreHeader from ExitBB in both the CFG and DT.
961+
BasicBlock *VectorPreHeader = State->CFG.PrevBB;
978962
cast<BranchInst>(VectorPreHeader->getTerminator())->setSuccessor(0, nullptr);
979963
State->CFG.DTU.applyUpdates(
980964
{{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}});
981965

982-
// Replace regular VPBB's for the vector preheader, middle and scalar
983-
// preheader blocks with VPIRBasicBlocks wrapping their IR blocks. The IR
984-
// blocks are created during skeleton creation, so we can only create the
985-
// VPIRBasicBlocks now during VPlan execution rather than earlier during VPlan
986-
// construction.
987-
BasicBlock *MiddleBB = State->CFG.ExitBB;
988-
BasicBlock *ScalarPh = MiddleBB->getSingleSuccessor();
989-
replaceVPBBWithIRVPBB(getVectorPreheader(), VectorPreHeader);
990-
replaceVPBBWithIRVPBB(getMiddleBlock(), MiddleBB);
991-
replaceVPBBWithIRVPBB(getScalarPreheader(), ScalarPh);
992-
993966
LLVM_DEBUG(dbgs() << "Executing best plan with VF=" << State->VF
994967
<< ", UF=" << getUF() << '\n');
995968
setName("Final VPlan");
@@ -998,6 +971,8 @@ void VPlan::execute(VPTransformState *State) {
998971
// Disconnect the middle block from its single successor (the scalar loop
999972
// header) in both the CFG and DT. The branch will be recreated during VPlan
1000973
// execution.
974+
BasicBlock *MiddleBB = State->CFG.ExitBB;
975+
BasicBlock *ScalarPh = MiddleBB->getSingleSuccessor();
1001976
auto *BrInst = new UnreachableInst(MiddleBB->getContext());
1002977
BrInst->insertBefore(MiddleBB->getTerminator());
1003978
MiddleBB->getTerminator()->eraseFromParent();

0 commit comments

Comments
 (0)