Skip to content

Commit 541e88d

Browse files
committed
[VPlan] Simplify HCFG construction of region blocks (NFC).
Update the logic to update the successors and predecessors of region blocks directly. This adds special handling for header and latch blocks in place, and removes the separate loop to fix up the region blocks. Helps to simplify D158333. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D159136
1 parent 6169e45 commit 541e88d

File tree

2 files changed

+99
-82
lines changed

2 files changed

+99
-82
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ class VPBlockBase {
585585
/// This VPBlockBase must have no successors.
586586
void setOneSuccessor(VPBlockBase *Successor) {
587587
assert(Successors.empty() && "Setting one successor when others exist.");
588+
assert(Successor->getParent() == getParent() &&
589+
"connected blocks must have the same parent");
588590
appendSuccessor(Successor);
589591
}
590592

llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp

Lines changed: 97 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class PlainCFGBuilder {
6161

6262
// Utility functions.
6363
void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB);
64+
void setRegionPredsFromBB(VPRegionBlock *VPBB, BasicBlock *BB);
6465
void fixPhiNodes();
6566
VPBasicBlock *getOrCreateVPBB(BasicBlock *BB);
6667
#ifndef NDEBUG
@@ -81,18 +82,43 @@ class PlainCFGBuilder {
8182
// Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB
8283
// must have no predecessors.
8384
void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) {
84-
SmallVector<VPBlockBase *, 8> VPBBPreds;
85+
auto GetLatchOfExit = [this](BasicBlock *BB) -> BasicBlock * {
86+
auto *SinglePred = BB->getSinglePredecessor();
87+
Loop *LoopForBB = LI->getLoopFor(BB);
88+
if (!SinglePred || LI->getLoopFor(SinglePred) == LoopForBB)
89+
return nullptr;
90+
// The input IR must be in loop-simplify form, ensuring a single predecessor
91+
// for exit blocks.
92+
assert(SinglePred == LI->getLoopFor(SinglePred)->getLoopLatch() &&
93+
"SinglePred must be the only loop latch");
94+
return SinglePred;
95+
};
96+
if (auto *LatchBB = GetLatchOfExit(BB)) {
97+
auto *PredRegion = getOrCreateVPBB(LatchBB)->getParent();
98+
assert(VPBB == cast<VPBasicBlock>(PredRegion->getSingleSuccessor()) &&
99+
"successor must already be set for PredRegion; it must have VPBB "
100+
"as single successor");
101+
VPBB->setPredecessors({PredRegion});
102+
return;
103+
}
85104
// Collect VPBB predecessors.
105+
SmallVector<VPBlockBase *, 2> VPBBPreds;
86106
for (BasicBlock *Pred : predecessors(BB))
87107
VPBBPreds.push_back(getOrCreateVPBB(Pred));
88-
89108
VPBB->setPredecessors(VPBBPreds);
90109
}
91110

92111
static bool isHeaderBB(BasicBlock *BB, Loop *L) {
93112
return L && BB == L->getHeader();
94113
}
95114

115+
void PlainCFGBuilder::setRegionPredsFromBB(VPRegionBlock *Region,
116+
BasicBlock *BB) {
117+
// BB is a loop header block. Connect the region to the loop preheader.
118+
Loop *LoopOfBB = LI->getLoopFor(BB);
119+
Region->setPredecessors({getOrCreateVPBB(LoopOfBB->getLoopPredecessor())});
120+
}
121+
96122
// Add operands to VPInstructions representing phi nodes from the input IR.
97123
void PlainCFGBuilder::fixPhiNodes() {
98124
for (auto *Phi : PhisToFix) {
@@ -126,32 +152,46 @@ void PlainCFGBuilder::fixPhiNodes() {
126152
}
127153
}
128154

155+
static bool isHeaderVPBB(VPBasicBlock *VPBB) {
156+
return VPBB->getParent() && VPBB->getParent()->getEntry() == VPBB;
157+
}
158+
129159
// Create a new empty VPBasicBlock for an incoming BasicBlock in the region
130160
// corresponding to the containing loop or retrieve an existing one if it was
131161
// already created. If no region exists yet for the loop containing \p BB, a new
132162
// one is created.
133163
VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
134-
auto BlockIt = BB2VPBB.find(BB);
135-
if (BlockIt != BB2VPBB.end())
164+
if (auto *VPBB = BB2VPBB.lookup(BB)) {
136165
// Retrieve existing VPBB.
137-
return BlockIt->second;
138-
139-
// Get or create a region for the loop containing BB.
140-
Loop *CurrentLoop = LI->getLoopFor(BB);
141-
VPRegionBlock *ParentR = nullptr;
142-
if (CurrentLoop) {
143-
auto Iter = Loop2Region.insert({CurrentLoop, nullptr});
144-
if (Iter.second)
145-
Iter.first->second = new VPRegionBlock(
146-
CurrentLoop->getHeader()->getName().str(), false /*isReplicator*/);
147-
ParentR = Iter.first->second;
166+
return VPBB;
148167
}
149168

150169
// Create new VPBB.
151170
LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << BB->getName() << "\n");
152171
VPBasicBlock *VPBB = new VPBasicBlock(BB->getName());
153172
BB2VPBB[BB] = VPBB;
154-
VPBB->setParent(ParentR);
173+
174+
// Get or create a region for the loop containing BB.
175+
Loop *LoopOfBB = LI->getLoopFor(BB);
176+
if (!LoopOfBB)
177+
return VPBB;
178+
179+
VPRegionBlock *RegionOfBB = Loop2Region.lookup(LoopOfBB);
180+
assert((RegionOfBB != nullptr) ^ isHeaderBB(BB, LoopOfBB) &&
181+
"region must exist or BB must be a loop header");
182+
if (RegionOfBB) {
183+
VPBB->setParent(RegionOfBB);
184+
} else {
185+
// If BB's loop is nested inside another loop within VPlan's scope, the
186+
// header of that enclosing loop was already visited and its region
187+
// constructed and recorded in Loop2Region. That region is now set as the
188+
// parent of VPBB's region. Otherwise it is set to null.
189+
auto *RegionOfVPBB = new VPRegionBlock(
190+
LoopOfBB->getHeader()->getName().str(), false /*isReplicator*/);
191+
RegionOfVPBB->setParent(Loop2Region[LoopOfBB->getParentLoop()]);
192+
RegionOfVPBB->setEntry(VPBB);
193+
Loop2Region[LoopOfBB] = RegionOfVPBB;
194+
}
155195
return VPBB;
156196
}
157197

@@ -286,6 +326,9 @@ void PlainCFGBuilder::buildPlainCFG() {
286326
BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();
287327
assert((ThePreheaderBB->getTerminator()->getNumSuccessors() == 1) &&
288328
"Unexpected loop preheader");
329+
// buildPlainCFG needs to be called after createInitialVPlan, which creates
330+
// the initial skeleton (including the preheader VPBB). buildPlainCFG builds
331+
// the CFG for the loop nest and hooks it up to the initial skeleton.
289332
VPBasicBlock *ThePreheaderVPBB = Plan.getEntry();
290333
BB2VPBB[ThePreheaderBB] = ThePreheaderVPBB;
291334
ThePreheaderVPBB->setName("vector.ph");
@@ -294,10 +337,11 @@ void PlainCFGBuilder::buildPlainCFG() {
294337
continue;
295338
IRDef2VPValue[&I] = Plan.getVPValueOrAddLiveIn(&I);
296339
}
297-
// Create empty VPBB for Loop H so that we can link PH->H.
340+
// Create region (and header block) for the outer loop, so that we can link
341+
// PH->Region.
298342
VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader());
299343
HeaderVPBB->setName("vector.body");
300-
ThePreheaderVPBB->setOneSuccessor(HeaderVPBB);
344+
ThePreheaderVPBB->setOneSuccessor(HeaderVPBB->getParent());
301345

302346
LoopBlocksRPO RPO(TheLoop);
303347
RPO.perform(LI);
@@ -306,39 +350,46 @@ void PlainCFGBuilder::buildPlainCFG() {
306350
// Create or retrieve the VPBasicBlock for this BB and create its
307351
// VPInstructions.
308352
VPBasicBlock *VPBB = getOrCreateVPBB(BB);
353+
VPRegionBlock *Region = VPBB->getParent();
309354
createVPInstructionsForVPBB(VPBB, BB);
355+
Loop *LoopForBB = LI->getLoopFor(BB);
356+
// Set VPBB predecessors in the same order as they are in the incoming BB.
357+
if (!isHeaderBB(BB, LoopForBB))
358+
setVPBBPredsFromBB(VPBB, BB);
359+
else {
360+
// BB is a loop header, set the predecessor for the region.
361+
assert(isHeaderVPBB(VPBB) && "isHeaderBB and isHeaderVPBB disagree");
362+
setRegionPredsFromBB(Region, BB);
363+
}
310364

311365
// Set VPBB successors. We create empty VPBBs for successors if they don't
312366
// exist already. Recipes will be created when the successor is visited
313367
// during the RPO traversal.
314-
Instruction *TI = BB->getTerminator();
315-
assert(TI && "Terminator expected.");
316-
unsigned NumSuccs = TI->getNumSuccessors();
317-
368+
auto *BI = cast<BranchInst>(BB->getTerminator());
369+
unsigned NumSuccs = succ_size(BB);
318370
if (NumSuccs == 1) {
319-
VPBasicBlock *SuccVPBB = getOrCreateVPBB(TI->getSuccessor(0));
320-
assert(SuccVPBB && "VPBB Successor not found.");
321-
VPBB->setOneSuccessor(SuccVPBB);
322-
} else if (NumSuccs == 2) {
323-
VPBasicBlock *SuccVPBB0 = getOrCreateVPBB(TI->getSuccessor(0));
324-
assert(SuccVPBB0 && "Successor 0 not found.");
325-
VPBasicBlock *SuccVPBB1 = getOrCreateVPBB(TI->getSuccessor(1));
326-
assert(SuccVPBB1 && "Successor 1 not found.");
327-
328-
// Get VPBB's condition bit.
329-
assert(isa<BranchInst>(TI) && "Unsupported terminator!");
330-
// Look up the branch condition to get the corresponding VPValue
331-
// representing the condition bit in VPlan (which may be in another VPBB).
332-
assert(IRDef2VPValue.count(cast<BranchInst>(TI)->getCondition()) &&
333-
"Missing condition bit in IRDef2VPValue!");
334-
335-
// Link successors.
336-
VPBB->setTwoSuccessors(SuccVPBB0, SuccVPBB1);
337-
} else
338-
llvm_unreachable("Number of successors not supported.");
339-
340-
// Set VPBB predecessors in the same order as they are in the incoming BB.
341-
setVPBBPredsFromBB(VPBB, BB);
371+
auto *Successor = getOrCreateVPBB(BB->getSingleSuccessor());
372+
VPBB->setOneSuccessor(isHeaderVPBB(Successor)
373+
? Successor->getParent()
374+
: static_cast<VPBlockBase *>(Successor));
375+
continue;
376+
}
377+
assert(BI->isConditional() && NumSuccs == 2 && BI->isConditional() &&
378+
"block must have conditional branch with 2 successors");
379+
// Look up the branch condition to get the corresponding VPValue
380+
// representing the condition bit in VPlan (which may be in another VPBB).
381+
assert(IRDef2VPValue.contains(BI->getCondition()) &&
382+
"Missing condition bit in IRDef2VPValue!");
383+
VPBasicBlock *Successor0 = getOrCreateVPBB(BI->getSuccessor(0));
384+
VPBasicBlock *Successor1 = getOrCreateVPBB(BI->getSuccessor(1));
385+
if (!LoopForBB || BB != LoopForBB->getLoopLatch()) {
386+
VPBB->setTwoSuccessors(Successor0, Successor1);
387+
continue;
388+
}
389+
// For a latch we need to set the successor of the region rather than that
390+
// of VPBB and it should be set to the exit, i.e., non-header successor.
391+
Region->setOneSuccessor(isHeaderVPBB(Successor0) ? Successor1 : Successor0);
392+
Region->setExiting(VPBB);
342393
}
343394

344395
// 2. Process outermost loop exit. We created an empty VPBB for the loop
@@ -351,43 +402,7 @@ void PlainCFGBuilder::buildPlainCFG() {
351402
// We only set its predecessor VPBB now.
352403
setVPBBPredsFromBB(LoopExitVPBB, LoopExitBB);
353404

354-
// 3. Fix up region blocks for loops. For each loop,
355-
// * use the header block as entry to the corresponding region,
356-
// * use the latch block as exit of the corresponding region,
357-
// * set the region as successor of the loop pre-header, and
358-
// * set the exit block as successor to the region.
359-
SmallVector<Loop *> LoopWorkList;
360-
LoopWorkList.push_back(TheLoop);
361-
while (!LoopWorkList.empty()) {
362-
Loop *L = LoopWorkList.pop_back_val();
363-
BasicBlock *Header = L->getHeader();
364-
BasicBlock *Exiting = L->getLoopLatch();
365-
assert(Exiting == L->getExitingBlock() &&
366-
"Latch must be the only exiting block");
367-
VPRegionBlock *Region = Loop2Region[L];
368-
VPBasicBlock *HeaderVPBB = getOrCreateVPBB(Header);
369-
VPBasicBlock *ExitingVPBB = getOrCreateVPBB(Exiting);
370-
371-
// Disconnect backedge and pre-header from header.
372-
VPBasicBlock *PreheaderVPBB = getOrCreateVPBB(L->getLoopPreheader());
373-
VPBlockUtils::disconnectBlocks(PreheaderVPBB, HeaderVPBB);
374-
VPBlockUtils::disconnectBlocks(ExitingVPBB, HeaderVPBB);
375-
376-
Region->setParent(PreheaderVPBB->getParent());
377-
Region->setEntry(HeaderVPBB);
378-
VPBlockUtils::connectBlocks(PreheaderVPBB, Region);
379-
380-
// Disconnect exit block from exiting (=latch) block, set exiting block and
381-
// connect region to exit block.
382-
VPBasicBlock *ExitVPBB = getOrCreateVPBB(L->getExitBlock());
383-
VPBlockUtils::disconnectBlocks(ExitingVPBB, ExitVPBB);
384-
Region->setExiting(ExitingVPBB);
385-
VPBlockUtils::connectBlocks(Region, ExitVPBB);
386-
387-
// Queue sub-loops for processing.
388-
LoopWorkList.append(L->begin(), L->end());
389-
}
390-
// 4. The whole CFG has been built at this point so all the input Values must
405+
// 3. The whole CFG has been built at this point so all the input Values must
391406
// have a VPlan couterpart. Fix VPlan phi nodes by adding their corresponding
392407
// VPlan operands.
393408
fixPhiNodes();

0 commit comments

Comments
 (0)