Skip to content

Commit 16d19aa

Browse files
authored
[VPlan] Manage created blocks directly in VPlan. (NFC) (#120918)
This patch changes the way blocks are managed by VPlan. Previously all blocks reachable from entry would be cleaned up when a VPlan is destroyed. With this patch, each VPlan keeps track of blocks created for it in a list and this list is then used to delete all blocks in the list when the VPlan is destroyed. To do so, block creation is funneled through helpers in directly in VPlan. The main advantage of doing so is it simplifies CFG transformations, as those do not have to take care of deleting any blocks, just adjusting the CFG. This helps to simplify #108378 and #106748. This also simplifies handling of 'immutable' blocks a VPlan holds references to, which at the moment only include the scalar header block. PR: #120918
1 parent 60d2060 commit 16d19aa

File tree

8 files changed

+228
-196
lines changed

8 files changed

+228
-196
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,7 @@ static void introduceCheckBlockInVPlan(VPlan &Plan, BasicBlock *CheckIRBB) {
24542454
assert(PreVectorPH->getNumSuccessors() == 2 && "Expected 2 successors");
24552455
assert(PreVectorPH->getSuccessors()[0] == ScalarPH &&
24562456
"Unexpected successor");
2457-
VPIRBasicBlock *CheckVPIRBB = VPIRBasicBlock::fromBasicBlock(CheckIRBB);
2457+
VPIRBasicBlock *CheckVPIRBB = Plan.createVPIRBasicBlock(CheckIRBB);
24582458
VPBlockUtils::insertOnEdge(PreVectorPH, VectorPH, CheckVPIRBB);
24592459
PreVectorPH = CheckVPIRBB;
24602460
}
@@ -8084,11 +8084,11 @@ EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck(
80848084

80858085
// A new entry block has been created for the epilogue VPlan. Hook it in, as
80868086
// otherwise we would try to modify the entry to the main vector loop.
8087-
VPIRBasicBlock *NewEntry = VPIRBasicBlock::fromBasicBlock(Insert);
8087+
VPIRBasicBlock *NewEntry = Plan.createVPIRBasicBlock(Insert);
80888088
VPBasicBlock *OldEntry = Plan.getEntry();
80898089
VPBlockUtils::reassociateBlocks(OldEntry, NewEntry);
80908090
Plan.setEntry(NewEntry);
8091-
delete OldEntry;
8091+
// OldEntry is now dead and will be cleaned up when the plan gets destroyed.
80928092

80938093
introduceCheckBlockInVPlan(Plan, Insert);
80948094
return Insert;
@@ -9289,7 +9289,7 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
92899289
VPBB->appendRecipe(Recipe);
92909290
}
92919291

9292-
VPBlockUtils::insertBlockAfter(new VPBasicBlock(), VPBB);
9292+
VPBlockUtils::insertBlockAfter(Plan->createVPBasicBlock(""), VPBB);
92939293
VPBB = cast<VPBasicBlock>(VPBB->getSingleSuccessor());
92949294
}
92959295

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,6 @@ VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
205205
return Parent->getEnclosingBlockWithPredecessors();
206206
}
207207

208-
void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
209-
for (VPBlockBase *Block : to_vector(vp_depth_first_shallow(Entry)))
210-
delete Block;
211-
}
212-
213208
VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
214209
iterator It = begin();
215210
while (It != end() && It->isPhi())
@@ -474,6 +469,13 @@ void VPIRBasicBlock::execute(VPTransformState *State) {
474469
connectToPredecessors(State->CFG);
475470
}
476471

472+
VPIRBasicBlock *VPIRBasicBlock::clone() {
473+
auto *NewBlock = getPlan()->createEmptyVPIRBasicBlock(IRBB);
474+
for (VPRecipeBase &R : Recipes)
475+
NewBlock->appendRecipe(R.clone());
476+
return NewBlock;
477+
}
478+
477479
void VPBasicBlock::execute(VPTransformState *State) {
478480
bool Replica = bool(State->Lane);
479481
BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
@@ -513,14 +515,11 @@ void VPBasicBlock::execute(VPTransformState *State) {
513515
executeRecipes(State, NewBB);
514516
}
515517

516-
void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
517-
for (VPRecipeBase &R : Recipes) {
518-
for (auto *Def : R.definedValues())
519-
Def->replaceAllUsesWith(NewValue);
520-
521-
for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
522-
R.setOperand(I, NewValue);
523-
}
518+
VPBasicBlock *VPBasicBlock::clone() {
519+
auto *NewBlock = getPlan()->createVPBasicBlock(getName());
520+
for (VPRecipeBase &R : *this)
521+
NewBlock->appendRecipe(R.clone());
522+
return NewBlock;
524523
}
525524

526525
void VPBasicBlock::executeRecipes(VPTransformState *State, BasicBlock *BB) {
@@ -541,7 +540,7 @@ VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
541540

542541
SmallVector<VPBlockBase *, 2> Succs(successors());
543542
// Create new empty block after the block to split.
544-
auto *SplitBlock = new VPBasicBlock(getName() + ".split");
543+
auto *SplitBlock = getPlan()->createVPBasicBlock(getName() + ".split");
545544
VPBlockUtils::insertBlockAfter(SplitBlock, this);
546545

547546
// Finally, move the recipes starting at SplitAt to new block.
@@ -701,20 +700,13 @@ static std::pair<VPBlockBase *, VPBlockBase *> cloneFrom(VPBlockBase *Entry) {
701700

702701
VPRegionBlock *VPRegionBlock::clone() {
703702
const auto &[NewEntry, NewExiting] = cloneFrom(getEntry());
704-
auto *NewRegion =
705-
new VPRegionBlock(NewEntry, NewExiting, getName(), isReplicator());
703+
auto *NewRegion = getPlan()->createVPRegionBlock(NewEntry, NewExiting,
704+
getName(), isReplicator());
706705
for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
707706
Block->setParent(NewRegion);
708707
return NewRegion;
709708
}
710709

711-
void VPRegionBlock::dropAllReferences(VPValue *NewValue) {
712-
for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
713-
// Drop all references in VPBasicBlocks and replace all uses with
714-
// DummyValue.
715-
Block->dropAllReferences(NewValue);
716-
}
717-
718710
void VPRegionBlock::execute(VPTransformState *State) {
719711
ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
720712
RPOT(Entry);
@@ -822,32 +814,33 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
822814
#endif
823815

824816
VPlan::VPlan(Loop *L) {
825-
setEntry(VPIRBasicBlock::fromBasicBlock(L->getLoopPreheader()));
826-
ScalarHeader = VPIRBasicBlock::fromBasicBlock(L->getHeader());
817+
setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
818+
ScalarHeader = createVPIRBasicBlock(L->getHeader());
827819
}
828820

829821
VPlan::~VPlan() {
830-
if (Entry) {
831-
VPValue DummyValue;
832-
for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
833-
Block->dropAllReferences(&DummyValue);
834-
835-
VPBlockBase::deleteCFG(Entry);
822+
VPValue DummyValue;
823+
824+
for (auto *VPB : CreatedBlocks) {
825+
if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB)) {
826+
// Replace all operands of recipes and all VPValues defined in VPBB with
827+
// DummyValue so the block can be deleted.
828+
for (VPRecipeBase &R : *VPBB) {
829+
for (auto *Def : R.definedValues())
830+
Def->replaceAllUsesWith(&DummyValue);
831+
832+
for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
833+
R.setOperand(I, &DummyValue);
834+
}
835+
}
836+
delete VPB;
836837
}
837838
for (VPValue *VPV : VPLiveInsToFree)
838839
delete VPV;
839840
if (BackedgeTakenCount)
840841
delete BackedgeTakenCount;
841842
}
842843

843-
VPIRBasicBlock *VPIRBasicBlock::fromBasicBlock(BasicBlock *IRBB) {
844-
auto *VPIRBB = new VPIRBasicBlock(IRBB);
845-
for (Instruction &I :
846-
make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
847-
VPIRBB->appendRecipe(new VPIRInstruction(I));
848-
return VPIRBB;
849-
}
850-
851844
VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
852845
PredicatedScalarEvolution &PSE,
853846
bool RequiresScalarEpilogueCheck,
@@ -861,7 +854,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
861854
// an epilogue vector loop, the original entry block here will be replaced by
862855
// a new VPIRBasicBlock wrapping the entry to the epilogue vector loop after
863856
// generating code for the main vector loop.
864-
VPBasicBlock *VecPreheader = new VPBasicBlock("vector.ph");
857+
VPBasicBlock *VecPreheader = Plan->createVPBasicBlock("vector.ph");
865858
VPBlockUtils::connectBlocks(Plan->getEntry(), VecPreheader);
866859

867860
// Create SCEV and VPValue for the trip count.
@@ -878,17 +871,17 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
878871

879872
// Create VPRegionBlock, with empty header and latch blocks, to be filled
880873
// during processing later.
881-
VPBasicBlock *HeaderVPBB = new VPBasicBlock("vector.body");
882-
VPBasicBlock *LatchVPBB = new VPBasicBlock("vector.latch");
874+
VPBasicBlock *HeaderVPBB = Plan->createVPBasicBlock("vector.body");
875+
VPBasicBlock *LatchVPBB = Plan->createVPBasicBlock("vector.latch");
883876
VPBlockUtils::insertBlockAfter(LatchVPBB, HeaderVPBB);
884-
auto *TopRegion = new VPRegionBlock(HeaderVPBB, LatchVPBB, "vector loop",
885-
false /*isReplicator*/);
877+
auto *TopRegion = Plan->createVPRegionBlock(
878+
HeaderVPBB, LatchVPBB, "vector loop", false /*isReplicator*/);
886879

887880
VPBlockUtils::insertBlockAfter(TopRegion, VecPreheader);
888-
VPBasicBlock *MiddleVPBB = new VPBasicBlock("middle.block");
881+
VPBasicBlock *MiddleVPBB = Plan->createVPBasicBlock("middle.block");
889882
VPBlockUtils::insertBlockAfter(MiddleVPBB, TopRegion);
890883

891-
VPBasicBlock *ScalarPH = new VPBasicBlock("scalar.ph");
884+
VPBasicBlock *ScalarPH = Plan->createVPBasicBlock("scalar.ph");
892885
VPBlockUtils::connectBlocks(ScalarPH, ScalarHeader);
893886
if (!RequiresScalarEpilogueCheck) {
894887
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -904,7 +897,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
904897
// we unconditionally branch to the scalar preheader. Do nothing.
905898
// 3) Otherwise, construct a runtime check.
906899
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock();
907-
auto *VPExitBlock = VPIRBasicBlock::fromBasicBlock(IRExitBlock);
900+
auto *VPExitBlock = Plan->createVPIRBasicBlock(IRExitBlock);
908901
// The connection order corresponds to the operands of the conditional branch.
909902
VPBlockUtils::insertBlockAfter(VPExitBlock, MiddleVPBB);
910903
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -960,15 +953,14 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
960953
/// have a single predecessor, which is rewired to the new VPIRBasicBlock. All
961954
/// successors of VPBB, if any, are rewired to the new VPIRBasicBlock.
962955
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
963-
VPIRBasicBlock *IRVPBB = VPIRBasicBlock::fromBasicBlock(IRBB);
956+
VPIRBasicBlock *IRVPBB = VPBB->getPlan()->createVPIRBasicBlock(IRBB);
964957
for (auto &R : make_early_inc_range(*VPBB)) {
965958
assert(!R.isPhi() && "Tried to move phi recipe to end of block");
966959
R.moveBefore(*IRVPBB, IRVPBB->end());
967960
}
968961

969962
VPBlockUtils::reassociateBlocks(VPBB, IRVPBB);
970-
971-
delete VPBB;
963+
// VPBB is now dead and will be cleaned up when the plan gets destroyed.
972964
}
973965

974966
/// Generate the code inside the preheader and body of the vectorized loop.
@@ -1217,6 +1209,7 @@ static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
12171209
}
12181210

12191211
VPlan *VPlan::duplicate() {
1212+
unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
12201213
// Clone blocks.
12211214
const auto &[NewEntry, __] = cloneFrom(Entry);
12221215

@@ -1257,9 +1250,32 @@ VPlan *VPlan::duplicate() {
12571250
assert(Old2NewVPValues.contains(TripCount) &&
12581251
"TripCount must have been added to Old2NewVPValues");
12591252
NewPlan->TripCount = Old2NewVPValues[TripCount];
1253+
1254+
// Transfer all cloned blocks (the second half of all current blocks) from
1255+
// current to new VPlan.
1256+
unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1257+
for (unsigned I :
1258+
seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning))
1259+
NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[I]);
1260+
CreatedBlocks.truncate(NumBlocksBeforeCloning);
1261+
12601262
return NewPlan;
12611263
}
12621264

1265+
VPIRBasicBlock *VPlan::createEmptyVPIRBasicBlock(BasicBlock *IRBB) {
1266+
auto *VPIRBB = new VPIRBasicBlock(IRBB);
1267+
CreatedBlocks.push_back(VPIRBB);
1268+
return VPIRBB;
1269+
}
1270+
1271+
VPIRBasicBlock *VPlan::createVPIRBasicBlock(BasicBlock *IRBB) {
1272+
auto *VPIRBB = createEmptyVPIRBasicBlock(IRBB);
1273+
for (Instruction &I :
1274+
make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1275+
VPIRBB->appendRecipe(new VPIRInstruction(I));
1276+
return VPIRBB;
1277+
}
1278+
12631279
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
12641280

12651281
Twine VPlanPrinter::getUID(const VPBlockBase *Block) {

0 commit comments

Comments
 (0)