Skip to content

Commit dd45cad

Browse files
committed
[VPlan] Manage created blocks directly in VPlan. (NFC)
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. Note that the original constructors taking VPBlockBase are retained at the moment for unit tests.
1 parent 9ab16d4 commit dd45cad

File tree

5 files changed

+97
-71
lines changed

5 files changed

+97
-71
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ static void introduceCheckBlockInVPlan(VPlan &Plan, BasicBlock *CheckIRBB) {
24772477
assert(PreVectorPH->getNumSuccessors() == 2 && "Expected 2 successors");
24782478
assert(PreVectorPH->getSuccessors()[0] == ScalarPH &&
24792479
"Unexpected successor");
2480-
VPIRBasicBlock *CheckVPIRBB = VPIRBasicBlock::fromBasicBlock(CheckIRBB);
2480+
VPIRBasicBlock *CheckVPIRBB = Plan.createVPIRBasicBlock(CheckIRBB);
24812481
VPBlockUtils::insertOnEdge(PreVectorPH, VectorPH, CheckVPIRBB);
24822482
PreVectorPH = CheckVPIRBB;
24832483
}
@@ -8189,11 +8189,10 @@ EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck(
81898189

81908190
// A new entry block has been created for the epilogue VPlan. Hook it in, as
81918191
// otherwise we would try to modify the entry to the main vector loop.
8192-
VPIRBasicBlock *NewEntry = VPIRBasicBlock::fromBasicBlock(Insert);
8192+
VPIRBasicBlock *NewEntry = Plan.createVPIRBasicBlock(Insert);
81938193
VPBasicBlock *OldEntry = Plan.getEntry();
81948194
VPBlockUtils::reassociateBlocks(OldEntry, NewEntry);
81958195
Plan.setEntry(NewEntry);
8196-
delete OldEntry;
81978196

81988197
introduceCheckBlockInVPlan(Plan, Insert);
81998198
return Insert;
@@ -9463,7 +9462,7 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
94639462
VPBB->appendRecipe(Recipe);
94649463
}
94659464

9466-
VPBlockUtils::insertBlockAfter(new VPBasicBlock(), VPBB);
9465+
VPBlockUtils::insertBlockAfter(Plan->createVPBasicBlock(""), VPBB);
94679466
VPBB = cast<VPBasicBlock>(VPBB->getSingleSuccessor());
94689467
}
94699468

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 52 additions & 32 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,16 @@ void VPIRBasicBlock::execute(VPTransformState *State) {
474469
connectToPredecessors(State->CFG);
475470
}
476471

472+
VPIRBasicBlock *VPIRBasicBlock::clone() {
473+
auto *NewBlock = getPlan()->createVPIRBasicBlock(IRBB);
474+
for (VPRecipeBase &R : make_early_inc_range(*NewBlock))
475+
R.eraseFromParent();
476+
477+
for (VPRecipeBase &R : Recipes)
478+
NewBlock->appendRecipe(R.clone());
479+
return NewBlock;
480+
}
481+
477482
void VPBasicBlock::execute(VPTransformState *State) {
478483
bool Replica = bool(State->Lane);
479484
BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
@@ -523,6 +528,13 @@ void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
523528
}
524529
}
525530

531+
VPBasicBlock *VPBasicBlock::clone() {
532+
auto *NewBlock = getPlan()->createVPBasicBlock(getName());
533+
for (VPRecipeBase &R : *this)
534+
NewBlock->appendRecipe(R.clone());
535+
return NewBlock;
536+
}
537+
526538
void VPBasicBlock::executeRecipes(VPTransformState *State, BasicBlock *BB) {
527539
LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB:" << getName()
528540
<< " in BB:" << BB->getName() << '\n');
@@ -541,7 +553,7 @@ VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
541553

542554
SmallVector<VPBlockBase *, 2> Succs(successors());
543555
// Create new empty block after the block to split.
544-
auto *SplitBlock = new VPBasicBlock(getName() + ".split");
556+
auto *SplitBlock = getPlan()->createVPBasicBlock(getName() + ".split");
545557
VPBlockUtils::insertBlockAfter(SplitBlock, this);
546558

547559
// Finally, move the recipes starting at SplitAt to new block.
@@ -701,8 +713,8 @@ static std::pair<VPBlockBase *, VPBlockBase *> cloneFrom(VPBlockBase *Entry) {
701713

702714
VPRegionBlock *VPRegionBlock::clone() {
703715
const auto &[NewEntry, NewExiting] = cloneFrom(getEntry());
704-
auto *NewRegion =
705-
new VPRegionBlock(NewEntry, NewExiting, getName(), isReplicator());
716+
auto *NewRegion = getPlan()->createVPRegionBlock(NewEntry, NewExiting,
717+
getName(), isReplicator());
706718
for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
707719
Block->setParent(NewRegion);
708720
return NewRegion;
@@ -822,32 +834,27 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
822834
#endif
823835

824836
VPlan::VPlan(Loop *L) {
825-
setEntry(VPIRBasicBlock::fromBasicBlock(L->getLoopPreheader()));
826-
ScalarHeader = VPIRBasicBlock::fromBasicBlock(L->getHeader());
837+
setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
838+
ScalarHeader = createVPIRBasicBlock(L->getHeader());
827839
}
828840

829841
VPlan::~VPlan() {
830842
if (Entry) {
831843
VPValue DummyValue;
832-
for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
833-
Block->dropAllReferences(&DummyValue);
834844

835-
VPBlockBase::deleteCFG(Entry);
845+
for (auto *VPB : reverse(CreatedBlocks))
846+
VPB->dropAllReferences(&DummyValue);
847+
848+
for (auto *VPB : reverse(CreatedBlocks)) {
849+
delete VPB;
850+
}
836851
}
837852
for (VPValue *VPV : VPLiveInsToFree)
838853
delete VPV;
839854
if (BackedgeTakenCount)
840855
delete BackedgeTakenCount;
841856
}
842857

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-
851858
VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
852859
PredicatedScalarEvolution &PSE,
853860
bool RequiresScalarEpilogueCheck,
@@ -861,7 +868,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
861868
// an epilogue vector loop, the original entry block here will be replaced by
862869
// a new VPIRBasicBlock wrapping the entry to the epilogue vector loop after
863870
// generating code for the main vector loop.
864-
VPBasicBlock *VecPreheader = new VPBasicBlock("vector.ph");
871+
VPBasicBlock *VecPreheader = Plan->createVPBasicBlock("vector.ph");
865872
VPBlockUtils::connectBlocks(Plan->getEntry(), VecPreheader);
866873

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

879886
// Create VPRegionBlock, with empty header and latch blocks, to be filled
880887
// during processing later.
881-
VPBasicBlock *HeaderVPBB = new VPBasicBlock("vector.body");
882-
VPBasicBlock *LatchVPBB = new VPBasicBlock("vector.latch");
888+
VPBasicBlock *HeaderVPBB = Plan->createVPBasicBlock("vector.body");
889+
VPBasicBlock *LatchVPBB = Plan->createVPBasicBlock("vector.latch");
883890
VPBlockUtils::insertBlockAfter(LatchVPBB, HeaderVPBB);
884-
auto *TopRegion = new VPRegionBlock(HeaderVPBB, LatchVPBB, "vector loop",
885-
false /*isReplicator*/);
891+
auto *TopRegion = Plan->createVPRegionBlock(
892+
HeaderVPBB, LatchVPBB, "vector loop", false /*isReplicator*/);
886893

887894
VPBlockUtils::insertBlockAfter(TopRegion, VecPreheader);
888-
VPBasicBlock *MiddleVPBB = new VPBasicBlock("middle.block");
895+
VPBasicBlock *MiddleVPBB = Plan->createVPBasicBlock("middle.block");
889896
VPBlockUtils::insertBlockAfter(MiddleVPBB, TopRegion);
890897

891-
VPBasicBlock *ScalarPH = new VPBasicBlock("scalar.ph");
898+
VPBasicBlock *ScalarPH = Plan->createVPBasicBlock("scalar.ph");
892899
VPBlockUtils::connectBlocks(ScalarPH, ScalarHeader);
893900
if (!RequiresScalarEpilogueCheck) {
894901
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -904,7 +911,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
904911
// we unconditionally branch to the scalar preheader. Do nothing.
905912
// 3) Otherwise, construct a runtime check.
906913
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock();
907-
auto *VPExitBlock = VPIRBasicBlock::fromBasicBlock(IRExitBlock);
914+
auto *VPExitBlock = Plan->createVPIRBasicBlock(IRExitBlock);
908915
// The connection order corresponds to the operands of the conditional branch.
909916
VPBlockUtils::insertBlockAfter(VPExitBlock, MiddleVPBB);
910917
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
@@ -960,15 +967,13 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
960967
/// have a single predecessor, which is rewired to the new VPIRBasicBlock. All
961968
/// successors of VPBB, if any, are rewired to the new VPIRBasicBlock.
962969
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) {
963-
VPIRBasicBlock *IRVPBB = VPIRBasicBlock::fromBasicBlock(IRBB);
970+
VPIRBasicBlock *IRVPBB = VPBB->getPlan()->createVPIRBasicBlock(IRBB);
964971
for (auto &R : make_early_inc_range(*VPBB)) {
965972
assert(!R.isPhi() && "Tried to move phi recipe to end of block");
966973
R.moveBefore(*IRVPBB, IRVPBB->end());
967974
}
968975

969976
VPBlockUtils::reassociateBlocks(VPBB, IRVPBB);
970-
971-
delete VPBB;
972977
}
973978

974979
/// Generate the code inside the preheader and body of the vectorized loop.
@@ -1217,6 +1222,7 @@ static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
12171222
}
12181223

12191224
VPlan *VPlan::duplicate() {
1225+
unsigned CreatedBlockSize = CreatedBlocks.size();
12201226
// Clone blocks.
12211227
const auto &[NewEntry, __] = cloneFrom(Entry);
12221228

@@ -1257,9 +1263,23 @@ VPlan *VPlan::duplicate() {
12571263
assert(Old2NewVPValues.contains(TripCount) &&
12581264
"TripCount must have been added to Old2NewVPValues");
12591265
NewPlan->TripCount = Old2NewVPValues[TripCount];
1266+
1267+
for (unsigned I = CreatedBlockSize; I != CreatedBlocks.size(); ++I)
1268+
NewPlan->CreatedBlocks.push_back(CreatedBlocks[I]);
1269+
CreatedBlocks.truncate(CreatedBlockSize);
1270+
12601271
return NewPlan;
12611272
}
12621273

1274+
VPIRBasicBlock *VPlan::createVPIRBasicBlock(BasicBlock *IRBB) {
1275+
auto *VPIRBB = new VPIRBasicBlock(IRBB);
1276+
for (Instruction &I :
1277+
make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1278+
VPIRBB->appendRecipe(new VPIRInstruction(I));
1279+
CreatedBlocks.push_back(VPIRBB);
1280+
return VPIRBB;
1281+
}
1282+
12631283
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
12641284

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

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -636,9 +636,6 @@ class VPBlockBase {
636636
/// Return the cost of the block.
637637
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx) = 0;
638638

639-
/// Delete all blocks reachable from a given VPBlockBase, inclusive.
640-
static void deleteCFG(VPBlockBase *Entry);
641-
642639
/// Return true if it is legal to hoist instructions into this block.
643640
bool isLegalToHoistInto() {
644641
// There are currently no constraints that prevent an instruction to be
@@ -3638,12 +3635,7 @@ class VPBasicBlock : public VPBlockBase {
36383635

36393636
/// Clone the current block and it's recipes, without updating the operands of
36403637
/// the cloned recipes.
3641-
VPBasicBlock *clone() override {
3642-
auto *NewBlock = new VPBasicBlock(getName());
3643-
for (VPRecipeBase &R : *this)
3644-
NewBlock->appendRecipe(R.clone());
3645-
return NewBlock;
3646-
}
3638+
VPBasicBlock *clone() override;
36473639

36483640
protected:
36493641
/// Execute the recipes in the IR basic block \p BB.
@@ -3679,20 +3671,11 @@ class VPIRBasicBlock : public VPBasicBlock {
36793671
return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
36803672
}
36813673

3682-
/// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
3683-
/// instructions in \p IRBB, except its terminator which is managed in VPlan.
3684-
static VPIRBasicBlock *fromBasicBlock(BasicBlock *IRBB);
3685-
36863674
/// The method which generates the output IR instructions that correspond to
36873675
/// this VPBasicBlock, thereby "executing" the VPlan.
36883676
void execute(VPTransformState *State) override;
36893677

3690-
VPIRBasicBlock *clone() override {
3691-
auto *NewBlock = new VPIRBasicBlock(IRBB);
3692-
for (VPRecipeBase &R : Recipes)
3693-
NewBlock->appendRecipe(R.clone());
3694-
return NewBlock;
3695-
}
3678+
VPIRBasicBlock *clone() override;
36963679

36973680
BasicBlock *getIRBasicBlock() const { return IRBB; }
36983681
};
@@ -3732,11 +3715,6 @@ class VPRegionBlock : public VPBlockBase {
37323715
IsReplicator(IsReplicator) {}
37333716

37343717
~VPRegionBlock() override {
3735-
if (Entry) {
3736-
VPValue DummyValue;
3737-
Entry->dropAllReferences(&DummyValue);
3738-
deleteCFG(Entry);
3739-
}
37403718
}
37413719

37423720
/// Method to support type inquiry through isa, cast, and dyn_cast.
@@ -3863,6 +3841,8 @@ class VPlan {
38633841
/// been modeled in VPlan directly.
38643842
DenseMap<const SCEV *, VPValue *> SCEVToExpansion;
38653843

3844+
SmallVector<VPBlockBase *> CreatedBlocks;
3845+
38663846
public:
38673847
/// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
38683848
/// wrapping the original header of the scalar loop.
@@ -4079,6 +4059,32 @@ class VPlan {
40794059
/// Clone the current VPlan, update all VPValues of the new VPlan and cloned
40804060
/// recipes to refer to the clones, and return it.
40814061
VPlan *duplicate();
4062+
4063+
VPBasicBlock *createVPBasicBlock(const Twine &Name,
4064+
VPRecipeBase *Recipe = nullptr) {
4065+
auto *VPB = new VPBasicBlock(Name, Recipe);
4066+
CreatedBlocks.push_back(VPB);
4067+
return VPB;
4068+
}
4069+
4070+
VPRegionBlock *createVPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting,
4071+
const std::string &Name = "",
4072+
bool IsReplicator = false) {
4073+
auto *VPB = new VPRegionBlock(Entry, Exiting, Name, IsReplicator);
4074+
CreatedBlocks.push_back(VPB);
4075+
return VPB;
4076+
}
4077+
4078+
VPRegionBlock *createVPRegionBlock(const std::string &Name = "",
4079+
bool IsReplicator = false) {
4080+
auto *VPB = new VPRegionBlock(Name, IsReplicator);
4081+
CreatedBlocks.push_back(VPB);
4082+
return VPB;
4083+
}
4084+
4085+
/// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
4086+
/// instructions in \p IRBB, except its terminator which is managed in VPlan.
4087+
VPIRBasicBlock *createVPIRBasicBlock(BasicBlock *IRBB);
40824088
};
40834089

40844090
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
182182
// Create new VPBB.
183183
StringRef Name = isHeaderBB(BB, TheLoop) ? "vector.body" : BB->getName();
184184
LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << Name << "\n");
185-
VPBasicBlock *VPBB = new VPBasicBlock(Name);
185+
VPBasicBlock *VPBB = Plan.createVPBasicBlock(Name);
186186
BB2VPBB[BB] = VPBB;
187187

188188
// Get or create a region for the loop containing BB.
@@ -204,7 +204,7 @@ VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
204204
if (LoopOfBB == TheLoop) {
205205
RegionOfVPBB = Plan.getVectorLoopRegion();
206206
} else {
207-
RegionOfVPBB = new VPRegionBlock(Name.str(), false /*isReplicator*/);
207+
RegionOfVPBB = Plan.createVPRegionBlock(Name.str(), false /*isReplicator*/);
208208
RegionOfVPBB->setParent(Loop2Region[LoopOfBB->getParentLoop()]);
209209
}
210210
RegionOfVPBB->setEntry(VPBB);

0 commit comments

Comments
 (0)