Skip to content

Commit 4eb1a57

Browse files
committed
[Utils] Cleanup similar cases to MergeBlockIntoPredecessor.
Summary: There are two cases where a block is merged into its predecessor and the MergeBlockIntoPredecessor API is not used. Update the API so it can be reused in the other cases, in order to avoid code duplication. Cleanup motivated by D68659. Reviewers: chandlerc, sanjoy.google, george.burgess.iv Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68670 llvm-svn: 375050
1 parent 471dc1f commit 4eb1a57

File tree

4 files changed

+56
-70
lines changed

4 files changed

+56
-70
lines changed

llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,16 @@ bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr);
8383

8484
/// Attempts to merge a block into its predecessor, if possible. The return
8585
/// value indicates success or failure.
86+
/// By default do not merge blocks if BB's predecessor has multiple successors.
87+
/// If PredecessorWithTwoSuccessors = true, the blocks can only be merged
88+
/// if BB's Pred has a branch to BB and to AnotherBB, and BB has a single
89+
/// successor Sing. In this case the branch will be updated with Sing instead of
90+
/// BB, and BB will still be merged into its predecessor and removed.
8691
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
8792
LoopInfo *LI = nullptr,
8893
MemorySSAUpdater *MSSAU = nullptr,
89-
MemoryDependenceResults *MemDep = nullptr);
94+
MemoryDependenceResults *MemDep = nullptr,
95+
bool PredecessorWithTwoSuccessors = false);
9096

9197
/// Replace all uses of an instruction (specified by BI) with a value, then
9298
/// remove and delete the original instruction.

llvm/lib/Transforms/Scalar/LoopUnswitch.cpp

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,43 +1621,24 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
16211621
if (!SinglePred) continue; // Nothing to do.
16221622
assert(SinglePred == Pred && "CFG broken");
16231623

1624-
LLVM_DEBUG(dbgs() << "Merging blocks: " << Pred->getName() << " <- "
1625-
<< Succ->getName() << "\n");
1626-
1627-
// Resolve any single entry PHI nodes in Succ.
1628-
while (PHINode *PN = dyn_cast<PHINode>(Succ->begin()))
1629-
ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM,
1630-
MSSAU.get());
1631-
1632-
Instruction *STI = Succ->getTerminator();
1633-
Instruction *Start = &*Succ->begin();
1634-
// If there's nothing to move, mark the starting instruction as the last
1635-
// instruction in the block.
1636-
if (Start == STI)
1637-
Start = BI;
1638-
1639-
// Move all of the successor contents from Succ to Pred.
1640-
Pred->getInstList().splice(BI->getIterator(), Succ->getInstList(),
1641-
Succ->begin(), STI->getIterator());
1642-
if (MSSAU)
1643-
MSSAU->moveAllAfterMergeBlocks(Succ, Pred, Start);
1644-
1645-
// Move terminator instruction from Succ now, we're deleting BI below.
1646-
// FIXME: remove BI first might be more intuitive.
1647-
Pred->getInstList().splice(Pred->end(), Succ->getInstList());
1648-
1649-
// If Succ has any successors with PHI nodes, update them to have
1650-
// entries coming from Pred instead of Succ.
1651-
Succ->replaceAllUsesWith(Pred);
1652-
1624+
// Make the LPM and Worklist updates specific to LoopUnswitch.
16531625
LPM->deleteSimpleAnalysisValue(BI, L);
16541626
RemoveFromWorklist(BI, Worklist);
1655-
BI->eraseFromParent();
1656-
1657-
// Remove Succ from the loop tree.
1658-
LI->removeBlock(Succ);
16591627
LPM->deleteSimpleAnalysisValue(Succ, L);
1660-
Succ->eraseFromParent();
1628+
auto SuccIt = Succ->begin();
1629+
while (PHINode *PN = dyn_cast<PHINode>(SuccIt++)) {
1630+
for (unsigned It = 0, E = PN->getNumOperands(); It != E; ++It)
1631+
if (Instruction *Use = dyn_cast<Instruction>(PN->getOperand(It)))
1632+
Worklist.push_back(Use);
1633+
for (User *U : PN->users())
1634+
Worklist.push_back(cast<Instruction>(U));
1635+
LPM->deleteSimpleAnalysisValue(PN, L);
1636+
RemoveFromWorklist(PN, Worklist);
1637+
++NumSimplify;
1638+
}
1639+
// Merge the block and make the remaining analyses updates.
1640+
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
1641+
MergeBlockIntoPredecessor(Succ, &DTU, LI, MSSAU.get());
16611642
++NumSimplify;
16621643
continue;
16631644
}

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) {
170170

171171
bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
172172
LoopInfo *LI, MemorySSAUpdater *MSSAU,
173-
MemoryDependenceResults *MemDep) {
173+
MemoryDependenceResults *MemDep,
174+
bool PredecessorWithTwoSuccessors) {
174175
if (BB->hasAddressTaken())
175176
return false;
176177

@@ -185,9 +186,24 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
185186
return false;
186187

187188
// Can't merge if there are multiple distinct successors.
188-
if (PredBB->getUniqueSuccessor() != BB)
189+
if (!PredecessorWithTwoSuccessors && PredBB->getUniqueSuccessor() != BB)
189190
return false;
190191

192+
// Currently only allow PredBB to have two predecessors, one being BB.
193+
// Update BI to branch to BB's only successor instead of BB.
194+
BranchInst *PredBB_BI;
195+
BasicBlock *NewSucc = nullptr;
196+
unsigned FallThruPath;
197+
if (PredecessorWithTwoSuccessors) {
198+
if (!(PredBB_BI = dyn_cast<BranchInst>(PredBB->getTerminator())))
199+
return false;
200+
BranchInst *BB_JmpI = dyn_cast<BranchInst>(BB->getTerminator());
201+
if (!BB_JmpI || !BB_JmpI->isUnconditional())
202+
return false;
203+
NewSucc = BB_JmpI->getSuccessor(0);
204+
FallThruPath = PredBB_BI->getSuccessor(0) == BB ? 0 : 1;
205+
}
206+
191207
// Can't merge if there is PHI loop.
192208
for (PHINode &PN : BB->phis())
193209
for (Value *IncValue : PN.incoming_values())
@@ -246,11 +262,20 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
246262
// source...
247263
BB->replaceAllUsesWith(PredBB);
248264

249-
// Delete the unconditional branch from the predecessor...
250-
PredBB->getInstList().pop_back();
265+
if (PredecessorWithTwoSuccessors) {
266+
// Delete the unconditional branch from BB.
267+
BB->getInstList().pop_back();
251268

252-
// Move terminator instruction and add unreachable to now empty BB.
253-
PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
269+
// Update branch in the predecessor.
270+
PredBB_BI->setSuccessor(FallThruPath, NewSucc);
271+
} else {
272+
// Delete the unconditional branch from the predecessor.
273+
PredBB->getInstList().pop_back();
274+
275+
// Move terminator instruction.
276+
PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
277+
}
278+
// Add unreachable to now empty BB.
254279
new UnreachableInst(BB->getContext(), BB);
255280

256281
// Eliminate duplicate dbg.values describing the entry PHI node post-splice.

llvm/lib/Transforms/Utils/LoopRotationUtils.cpp

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -615,35 +615,9 @@ bool LoopRotate::simplifyLoopLatch(Loop *L) {
615615
LLVM_DEBUG(dbgs() << "Folding loop latch " << Latch->getName() << " into "
616616
<< LastExit->getName() << "\n");
617617

618-
Instruction *FirstLatchInst = &*Latch->begin();
619-
// If there's nothing to move, mark the starting instruction as the last
620-
// instruction in the block.
621-
if (FirstLatchInst == Jmp)
622-
FirstLatchInst = BI;
623-
624-
// Hoist the instructions from Latch into LastExit.
625-
LastExit->getInstList().splice(BI->getIterator(), Latch->getInstList(),
626-
Latch->begin(), Jmp->getIterator());
627-
628-
// Update MemorySSA
629-
if (MSSAU)
630-
MSSAU->moveAllAfterMergeBlocks(Latch, LastExit, FirstLatchInst);
631-
632-
unsigned FallThruPath = BI->getSuccessor(0) == Latch ? 0 : 1;
633-
BasicBlock *Header = Jmp->getSuccessor(0);
634-
assert(Header == L->getHeader() && "expected a backward branch");
635-
636-
// Remove Latch from the CFG so that LastExit becomes the new Latch.
637-
BI->setSuccessor(FallThruPath, Header);
638-
Latch->replaceSuccessorsPhiUsesWith(LastExit);
639-
Jmp->eraseFromParent();
640-
641-
// Nuke the Latch block.
642-
assert(Latch->empty() && "unable to evacuate Latch");
643-
LI->removeBlock(Latch);
644-
if (DT)
645-
DT->eraseNode(Latch);
646-
Latch->eraseFromParent();
618+
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
619+
MergeBlockIntoPredecessor(Latch, &DTU, LI, MSSAU, nullptr,
620+
/*PredecessorWithTwoSuccessors=*/true);
647621

648622
if (MSSAU && VerifyMemorySSA)
649623
MSSAU->getMemorySSA()->verifyMemorySSA();

0 commit comments

Comments
 (0)