[llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Feb 16 00:36:04 PST 2004
Changes in directory llvm/lib/Transforms/Utils:
SimplifyCFG.cpp updated: 1.22 -> 1.23
---
Log message:
Implement test/Regression/Transforms/SimplifyCFG/UncondBranchToReturn.ll,
see the testcase for the reasoning.
---
Diffs of the changes: (+48 -0)
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.22 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.23
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.22 Tue Feb 10 21:36:04 2004
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp Mon Feb 16 00:35:48 2004
@@ -342,6 +342,54 @@
}
}
+ // 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.
More information about the llvm-commits
mailing list