summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-06-29 23:56:58 +0000
committerChris Lattner <sabre@nondot.org>2001-06-29 23:56:58 +0000
commit7ce8b17e60bc8e34b96f4a8e5a7aee579e73bd67 (patch)
treeacb2fcb1650c22b75171333163adbe31304d4b68 /llvm/lib/Transforms
parent10b250eb4db3bf2753f003fcd3eac7f023144fae (diff)
downloadbcm5719-llvm-7ce8b17e60bc8e34b96f4a8e5a7aee579e73bd67.tar.gz
bcm5719-llvm-7ce8b17e60bc8e34b96f4a8e5a7aee579e73bd67.zip
Export ConstantFoldTerminator, allow it to fold conditional branches to
the same label. llvm-svn: 107
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/ConstantProp.cpp38
1 files changed, 30 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/ConstantProp.cpp b/llvm/lib/Transforms/Scalar/ConstantProp.cpp
index 2df4f01a7e6..51800f5a6b6 100644
--- a/llvm/lib/Transforms/Scalar/ConstantProp.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantProp.cpp
@@ -120,28 +120,50 @@ ConstantFoldBinaryInst(Method *M, Method::inst_iterator &DI,
return true;
}
-inline static bool ConstantFoldTerminator(TerminatorInst *T) {
+// ConstantFoldTerminator - If a terminator instruction is predicated on a
+// constant value, convert it into an unconditional branch to the constant
+// destination.
+//
+bool ConstantFoldTerminator(TerminatorInst *T) {
// Branch - See if we are conditional jumping on constant
if (T->getInstType() == Instruction::Br) {
BranchInst *BI = (BranchInst*)T;
- if (!BI->isUnconditional() && // Are we branching on constant?
- BI->getOperand(2)->isConstant()) {
+ if (BI->isUnconditional()) return false; // Can't optimize uncond branch
+ BasicBlock *Dest1 = BI->getOperand(0)->castBasicBlockAsserting();
+ BasicBlock *Dest2 = BI->getOperand(1)->castBasicBlockAsserting();
+
+ if (BI->getOperand(2)->isConstant()) { // Are we branching on constant?
// YES. Change to unconditional branch...
ConstPoolBool *Cond = (ConstPoolBool*)BI->getOperand(2);
- Value *Destination = BI->getOperand(Cond->getValue() ? 0 : 1);
- Value *OldDest = BI->getOperand(Cond->getValue() ? 1 : 0);
+ BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
+ BasicBlock *OldDest = Cond->getValue() ? Dest2 : Dest1;
- //cerr << "Method: " << T->getParent()->getParent() << "\nRemoving branch from " << T->getParent() << "\n\nTo: " << OldDest << endl;
+ //cerr << "Method: " << T->getParent()->getParent()
+ // << "\nRemoving branch from " << T->getParent()
+ // << "\n\nTo: " << OldDest << endl;
// Let the basic block know that we are letting go of it. Based on this,
// it will adjust it's PHI nodes.
- assert(T->getParent() && "Terminator not inserted in block!");
- OldDest->castBasicBlockAsserting()->removePredecessor(T->getParent());
+ assert(BI->getParent() && "Terminator not inserted in block!");
+ OldDest->removePredecessor(BI->getParent());
BI->setOperand(0, Destination); // Set the unconditional destination
BI->setOperand(1, 0); // Clear the conditional destination
BI->setOperand(2, 0); // Clear the condition...
return true;
+ } else if (Dest2 == Dest1) { // Conditional branch to same location?
+ // This branch matches something like this:
+ // br bool %cond, label %Dest, label %Dest
+ // and changes it into: br label %Dest
+
+ // Let the basic block know that we are letting go of one copy of it.
+ assert(BI->getParent() && "Terminator not inserted in block!");
+ Dest1->removePredecessor(BI->getParent());
+
+ // Nuke the second destination, and the use of the condition variable
+ BI->setOperand(1, 0); // Clear the conditional destination
+ BI->setOperand(2, 0); // Clear the condition...
+ return true;
}
}
return false;
OpenPOWER on IntegriCloud