aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
diff options
context:
space:
mode:
authorAlina Sbirlea <asbirlea@google.com>2019-10-16 22:23:20 +0000
committerAlina Sbirlea <asbirlea@google.com>2019-10-16 22:23:20 +0000
commit4eb1a573fab3b2257e966c97a06d15159ecac922 (patch)
tree1c6501dd1851fded8219b6f3b580e28078a835ae /llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
parent471dc1fb286ae7551da1d4a0349970b2a9491052 (diff)
downloadllvm-4eb1a573fab3b2257e966c97a06d15159ecac922.zip
llvm-4eb1a573fab3b2257e966c97a06d15159ecac922.tar.gz
llvm-4eb1a573fab3b2257e966c97a06d15159ecac922.tar.bz2
[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
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/BasicBlockUtils.cpp37
1 files changed, 31 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index b3dd3c9..d85cc40 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -170,7 +170,8 @@ bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) {
bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
LoopInfo *LI, MemorySSAUpdater *MSSAU,
- MemoryDependenceResults *MemDep) {
+ MemoryDependenceResults *MemDep,
+ bool PredecessorWithTwoSuccessors) {
if (BB->hasAddressTaken())
return false;
@@ -185,9 +186,24 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
return false;
// Can't merge if there are multiple distinct successors.
- if (PredBB->getUniqueSuccessor() != BB)
+ if (!PredecessorWithTwoSuccessors && PredBB->getUniqueSuccessor() != BB)
return false;
+ // Currently only allow PredBB to have two predecessors, one being BB.
+ // Update BI to branch to BB's only successor instead of BB.
+ BranchInst *PredBB_BI;
+ BasicBlock *NewSucc = nullptr;
+ unsigned FallThruPath;
+ if (PredecessorWithTwoSuccessors) {
+ if (!(PredBB_BI = dyn_cast<BranchInst>(PredBB->getTerminator())))
+ return false;
+ BranchInst *BB_JmpI = dyn_cast<BranchInst>(BB->getTerminator());
+ if (!BB_JmpI || !BB_JmpI->isUnconditional())
+ return false;
+ NewSucc = BB_JmpI->getSuccessor(0);
+ FallThruPath = PredBB_BI->getSuccessor(0) == BB ? 0 : 1;
+ }
+
// Can't merge if there is PHI loop.
for (PHINode &PN : BB->phis())
for (Value *IncValue : PN.incoming_values())
@@ -246,11 +262,20 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
// source...
BB->replaceAllUsesWith(PredBB);
- // Delete the unconditional branch from the predecessor...
- PredBB->getInstList().pop_back();
+ if (PredecessorWithTwoSuccessors) {
+ // Delete the unconditional branch from BB.
+ BB->getInstList().pop_back();
- // Move terminator instruction and add unreachable to now empty BB.
- PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
+ // Update branch in the predecessor.
+ PredBB_BI->setSuccessor(FallThruPath, NewSucc);
+ } else {
+ // Delete the unconditional branch from the predecessor.
+ PredBB->getInstList().pop_back();
+
+ // Move terminator instruction.
+ PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
+ }
+ // Add unreachable to now empty BB.
new UnreachableInst(BB->getContext(), BB);
// Eliminate duplicate dbg.values describing the entry PHI node post-splice.