summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/DCE.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-03 21:30:22 +0000
committerChris Lattner <sabre@nondot.org>2001-11-03 21:30:22 +0000
commit081431a639196716fb4b5394db518e521f533ac4 (patch)
treedf4aeea92f0e3978e0587050835f56a1b0e45e57 /lib/Transforms/Scalar/DCE.cpp
parent5b497ee7c24b0cff0b5b5064b086d2ad4b190b6f (diff)
downloadllvm-081431a639196716fb4b5394db518e521f533ac4.tar.gz
llvm-081431a639196716fb4b5394db518e521f533ac4.tar.bz2
llvm-081431a639196716fb4b5394db518e521f533ac4.tar.xz
Avoid making a broken transformation!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1115 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/DCE.cpp')
-rw-r--r--lib/Transforms/Scalar/DCE.cpp53
1 files changed, 33 insertions, 20 deletions
diff --git a/lib/Transforms/Scalar/DCE.cpp b/lib/Transforms/Scalar/DCE.cpp
index ac3ae7b66b..16d9534018 100644
--- a/lib/Transforms/Scalar/DCE.cpp
+++ b/lib/Transforms/Scalar/DCE.cpp
@@ -105,11 +105,13 @@ static void ReplaceUsesWithConstant(Instruction *I) {
// PropogatePredecessors - This gets "Succ" ready to have the predecessors from
// "BB". This is a little tricky because "Succ" has PHI nodes, which need to
// have extra slots added to them to hold the merge edges from BB's
-// predecessors.
+// predecessors. This function returns true (failure) if the Succ BB already
+// has a predecessor that is a predecessor of BB.
//
-// Assumption: BB is the single predecessor of Succ.
+// Assumption: Succ is the single successor for BB.
//
-static void PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
+static bool PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
+ assert(*BB->succ_begin() == Succ && "Succ is not successor of BB!");
assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");
// If there is more than one predecessor, and there are PHI nodes in
@@ -117,6 +119,15 @@ static void PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
//
const vector<BasicBlock*> BBPreds(BB->pred_begin(), BB->pred_end());
+ // Check to see if one of the predecessors of BB is already a predecessor of
+ // Succ. If so, we cannot do the transformation!
+ //
+ for (BasicBlock::pred_iterator PI = Succ->pred_begin(), PE = Succ->pred_end();
+ PI != PE; ++PI) {
+ if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end())
+ return true;
+ }
+
BasicBlock::iterator I = Succ->begin();
do { // Loop over all of the PHI nodes in the successor BB
PHINode *PN = cast<PHINode>(*I);
@@ -131,6 +142,7 @@ static void PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
++I;
} while (isa<PHINode>(*I));
+ return false;
}
@@ -182,28 +194,29 @@ bool opt::SimplifyCFG(Method::iterator &BBIt) {
// successor. If so, replace block references with successor.
BasicBlock::succ_iterator SI(BB->succ_begin());
if (SI != BB->succ_end() && ++SI == BB->succ_end()) { // One succ?
- Instruction *I = BB->front();
- if (I->isTerminator()) { // Terminator is the only instruction!
+ if (BB->front()->isTerminator()) { // Terminator is the only instruction!
BasicBlock *Succ = *BB->succ_begin(); // There is exactly one successor
//cerr << "Killing Trivial BB: \n" << BB;
if (Succ != BB) { // Arg, don't hurt infinite loops!
- if (isa<PHINode>(Succ->front())) {
- // If our successor has PHI nodes, then we need to update them to
- // include entries for BB's predecessors, not for BB itself.
- //
- PropogatePredecessorsForPHIs(BB, Succ);
- }
-
- BB->replaceAllUsesWith(Succ);
- BB = M->getBasicBlocks().remove(BBIt);
+ // If our successor has PHI nodes, then we need to update them to
+ // include entries for BB's predecessors, not for BB itself.
+ // Be careful though, if this transformation fails (returns true) then
+ // we cannot do this transformation!
+ //
+ if (!isa<PHINode>(Succ->front()) ||
+ !PropogatePredecessorsForPHIs(BB, Succ)) {
+
+ BB->replaceAllUsesWith(Succ);
+ BB = M->getBasicBlocks().remove(BBIt);
- if (BB->hasName() && !Succ->hasName()) // Transfer name if we can
- Succ->setName(BB->getName());
- delete BB; // Delete basic block
-
- //cerr << "Method after removal: \n" << M;
- return true;
+ if (BB->hasName() && !Succ->hasName()) // Transfer name if we can
+ Succ->setName(BB->getName());
+ delete BB; // Delete basic block
+
+ //cerr << "Method after removal: \n" << M;
+ return true;
+ }
}
}
}