summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-16 06:35:48 +0000
committerChris Lattner <sabre@nondot.org>2004-02-16 06:35:48 +0000
commit19831ec8531b0710629c1b0a8c0323e70ae0ef07 (patch)
tree2f1f3671316999d408f5dae333e6efd3cc7e64ec /lib
parent5ea27d820a7873400d0c5e8e18253489e1d99c85 (diff)
downloadllvm-19831ec8531b0710629c1b0a8c0323e70ae0ef07.tar.gz
llvm-19831ec8531b0710629c1b0a8c0323e70ae0ef07.tar.bz2
llvm-19831ec8531b0710629c1b0a8c0323e70ae0ef07.tar.xz
Implement test/Regression/Transforms/SimplifyCFG/UncondBranchToReturn.ll,
see the testcase for the reasoning. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11496 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 3518ee5689..b0fc6bca74 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -342,6 +342,54 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
}
}
+ // If this is a returning block with only PHI nodes in it, fold the return
+ // instruction into any unconditional branch predecessors.
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
+ BasicBlock::iterator BBI = BB->getTerminator();
+ if (BBI == BB->begin() || isa<PHINode>(--BBI)) {
+ // Find predecessors that end with unconditional branches.
+ std::vector<BasicBlock*> UncondBranchPreds;
+ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
+ TerminatorInst *PTI = (*PI)->getTerminator();
+ if (BranchInst *BI = dyn_cast<BranchInst>(PTI))
+ if (BI->isUnconditional())
+ UncondBranchPreds.push_back(*PI);
+ }
+
+ // If we found some, do the transformation!
+ if (!UncondBranchPreds.empty()) {
+ while (!UncondBranchPreds.empty()) {
+ BasicBlock *Pred = UncondBranchPreds.back();
+ UncondBranchPreds.pop_back();
+ Instruction *UncondBranch = Pred->getTerminator();
+ // Clone the return and add it to the end of the predecessor.
+ Instruction *NewRet = RI->clone();
+ Pred->getInstList().push_back(NewRet);
+
+ // If the return instruction returns a value, and if the value was a
+ // PHI node in "BB", propagate the right value into the return.
+ if (NewRet->getNumOperands() == 1)
+ if (PHINode *PN = dyn_cast<PHINode>(NewRet->getOperand(0)))
+ if (PN->getParent() == BB)
+ NewRet->setOperand(0, PN->getIncomingValueForBlock(Pred));
+ // Update any PHI nodes in the returning block to realize that we no
+ // longer branch to them.
+ BB->removePredecessor(Pred);
+ Pred->getInstList().erase(UncondBranch);
+ }
+
+ // If we eliminated all predecessors of the block, delete the block now.
+ if (pred_begin(BB) == pred_end(BB))
+ // We know there are no successors, so just nuke the block.
+ M->getBasicBlockList().erase(BB);
+
+
+ return true;
+ }
+ }
+ }
+
+
// Merge basic blocks into their predecessor if there is only one distinct
// pred, and if there is only one distinct successor of the predecessor, and
// if there are no PHI nodes.