Skip to content

Commit 83f4c78

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 llvm#108378 and llvm#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 c5492e3 commit 83f4c78

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
}
@@ -8185,11 +8185,10 @@ EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck(
81858185

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

81948193
introduceCheckBlockInVPlan(Plan, Insert);
81958194
return Insert;
@@ -9335,7 +9334,7 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
93359334
VPBB->appendRecipe(Recipe);
93369335
}
93379336

9338-
VPBlockUtils::insertBlockAfter(new VPBasicBlock(), VPBB);
9337+
VPBlockUtils::insertBlockAfter(Plan->createVPBasicBlock(""), VPBB);
93399338
VPBB = cast<VPBasicBlock>(VPBB->getSingleSuccessor());
93409339
}
93419340

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.
@@ -1222,6 +1227,7 @@ static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
12221227
}
12231228

12241229
VPlan *VPlan::duplicate() {
1230+
unsigned CreatedBlockSize = CreatedBlocks.size();
12251231
// Clone blocks.
12261232
const auto &[NewEntry, __] = cloneFrom(Entry);
12271233

@@ -1262,9 +1268,23 @@ VPlan *VPlan::duplicate() {
12621268
assert(Old2NewVPValues.contains(TripCount) &&
12631269
"TripCount must have been added to Old2NewVPValues");
12641270
NewPlan->TripCount = Old2NewVPValues[TripCount];
1271+
1272+
for (unsigned I = CreatedBlockSize; I != CreatedBlocks.size(); ++I)
1273+
NewPlan->CreatedBlocks.push_back(CreatedBlocks[I]);
1274+
CreatedBlocks.truncate(CreatedBlockSize);
1275+
12651276
return NewPlan;
12661277
}
12671278

1279+
VPIRBasicBlock *VPlan::createVPIRBasicBlock(BasicBlock *IRBB) {
1280+
auto *VPIRBB = new VPIRBasicBlock(IRBB);
1281+
for (Instruction &I :
1282+
make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1283+
VPIRBB->appendRecipe(new VPIRInstruction(I));
1284+
CreatedBlocks.push_back(VPIRBB);
1285+
return VPIRBB;
1286+
}
1287+
12681288
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
12691289

12701290
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
@@ -3585,12 +3582,7 @@ class VPBasicBlock : public VPBlockBase {
35853582

35863583
/// Clone the current block and it's recipes, without updating the operands of
35873584
/// the cloned recipes.
3588-
VPBasicBlock *clone() override {
3589-
auto *NewBlock = new VPBasicBlock(getName());
3590-
for (VPRecipeBase &R : *this)
3591-
NewBlock->appendRecipe(R.clone());
3592-
return NewBlock;
3593-
}
3585+
VPBasicBlock *clone() override;
35943586

35953587
protected:
35963588
/// Execute the recipes in the IR basic block \p BB.
@@ -3626,20 +3618,11 @@ class VPIRBasicBlock : public VPBasicBlock {
36263618
return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
36273619
}
36283620

3629-
/// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
3630-
/// instructions in \p IRBB, except its terminator which is managed in VPlan.
3631-
static VPIRBasicBlock *fromBasicBlock(BasicBlock *IRBB);
3632-
36333621
/// The method which generates the output IR instructions that correspond to
36343622
/// this VPBasicBlock, thereby "executing" the VPlan.
36353623
void execute(VPTransformState *State) override;
36363624

3637-
VPIRBasicBlock *clone() override {
3638-
auto *NewBlock = new VPIRBasicBlock(IRBB);
3639-
for (VPRecipeBase &R : Recipes)
3640-
NewBlock->appendRecipe(R.clone());
3641-
return NewBlock;
3642-
}
3625+
VPIRBasicBlock *clone() override;
36433626

36443627
BasicBlock *getIRBasicBlock() const { return IRBB; }
36453628
};
@@ -3679,11 +3662,6 @@ class VPRegionBlock : public VPBlockBase {
36793662
IsReplicator(IsReplicator) {}
36803663

36813664
~VPRegionBlock() override {
3682-
if (Entry) {
3683-
VPValue DummyValue;
3684-
Entry->dropAllReferences(&DummyValue);
3685-
deleteCFG(Entry);
3686-
}
36873665
}
36883666

36893667
/// Method to support type inquiry through isa, cast, and dyn_cast.
@@ -3810,6 +3788,8 @@ class VPlan {
38103788
/// been modeled in VPlan directly.
38113789
DenseMap<const SCEV *, VPValue *> SCEVToExpansion;
38123790

3791+
SmallVector<VPBlockBase *> CreatedBlocks;
3792+
38133793
public:
38143794
/// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
38153795
/// wrapping the original header of the scalar loop.
@@ -4026,6 +4006,32 @@ class VPlan {
40264006
/// Clone the current VPlan, update all VPValues of the new VPlan and cloned
40274007
/// recipes to refer to the clones, and return it.
40284008
VPlan *duplicate();
4009+
4010+
VPBasicBlock *createVPBasicBlock(const Twine &Name,
4011+
VPRecipeBase *Recipe = nullptr) {
4012+
auto *VPB = new VPBasicBlock(Name, Recipe);
4013+
CreatedBlocks.push_back(VPB);
4014+
return VPB;
4015+
}
4016+
4017+
VPRegionBlock *createVPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting,
4018+
const std::string &Name = "",
4019+
bool IsReplicator = false) {
4020+
auto *VPB = new VPRegionBlock(Entry, Exiting, Name, IsReplicator);
4021+
CreatedBlocks.push_back(VPB);
4022+
return VPB;
4023+
}
4024+
4025+
VPRegionBlock *createVPRegionBlock(const std::string &Name = "",
4026+
bool IsReplicator = false) {
4027+
auto *VPB = new VPRegionBlock(Name, IsReplicator);
4028+
CreatedBlocks.push_back(VPB);
4029+
return VPB;
4030+
}
4031+
4032+
/// Create a VPIRBasicBlock from \p IRBB containing VPIRInstructions for all
4033+
/// instructions in \p IRBB, except its terminator which is managed in VPlan.
4034+
VPIRBasicBlock *createVPIRBasicBlock(BasicBlock *IRBB);
40294035
};
40304036

40314037
#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)