aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/SimplifyCFG.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-05-01 23:35:43 +0000
committerChris Lattner <sabre@nondot.org>2004-05-01 23:35:43 +0000
commite67fa05036f634a4ec1e0893033c89250eb58954 (patch)
tree1f2853e944a4e50d2cfc66478704b7c7d910eee1 /lib/Transforms/Utils/SimplifyCFG.cpp
parent470221cfc029b933677d93dce087a8038132f2ca (diff)
Implement SimplifyCFG/branch-cond-merge.ll
Turning "if (A < B && B < C)" into "if (A < B & B < C)" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13311 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp74
1 files changed, 64 insertions, 10 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 7f2060fbfc..dedaa6a657 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -790,17 +790,71 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
if (FoldValueComparisonIntoPredecessors(SI))
return SimplifyCFG(BB) || 1;
} else if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) {
- if (Value *CompVal = isValueEqualityComparison(BB->getTerminator())) {
- // This block must be empty, except for the setcond inst, if it exists.
- BasicBlock::iterator I = BB->begin();
- if (&*I == BI ||
- (&*I == cast<Instruction>(BI->getCondition()) &&
- &*++I == BI))
- if (FoldValueComparisonIntoPredecessors(BI))
- return SimplifyCFG(BB) | true;
- }
-
if (BI->isConditional()) {
+ if (Value *CompVal = isValueEqualityComparison(BI)) {
+ // This block must be empty, except for the setcond inst, if it exists.
+ BasicBlock::iterator I = BB->begin();
+ if (&*I == BI ||
+ (&*I == cast<Instruction>(BI->getCondition()) &&
+ &*++I == BI))
+ if (FoldValueComparisonIntoPredecessors(BI))
+ return SimplifyCFG(BB) | true;
+ }
+
+ // If this basic block is ONLY a setcc and a branch, and if a predecessor
+ // branches to us and one of our successors, fold the setcc into the
+ // predecessor and use logical operations to pick the right destination.
+ if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition()))
+ if (Cond->getParent() == BB && &BB->front() == Cond &&
+ Cond->getNext() == BI && Cond->hasOneUse()) {
+ BasicBlock *TrueDest = BI->getSuccessor(0);
+ BasicBlock *FalseDest = BI->getSuccessor(1);
+
+ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI!=E; ++PI)
+ if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
+ if (PBI->isConditional()) {
+ if (PBI->getSuccessor(0) == FalseDest ||
+ PBI->getSuccessor(1) == TrueDest) {
+ // Invert the predecessors condition test (xor it with true),
+ // which allows us to write this code once.
+ Value *NewCond =
+ BinaryOperator::createNot(PBI->getCondition(),
+ PBI->getCondition()->getName()+".not", PBI);
+ PBI->setCondition(NewCond);
+ BasicBlock *OldTrue = PBI->getSuccessor(0);
+ BasicBlock *OldFalse = PBI->getSuccessor(1);
+ PBI->setSuccessor(0, OldFalse);
+ PBI->setSuccessor(1, OldTrue);
+ }
+
+ if (PBI->getSuccessor(0) == TrueDest ||
+ PBI->getSuccessor(1) == FalseDest) {
+ // Clone Cond into the predecessor basic block, and and the
+ // two conditions together.
+ Instruction *New = Cond->clone();
+ New->setName(Cond->getName());
+ Cond->setName(Cond->getName()+".old");
+ (*PI)->getInstList().insert(PBI, New);
+ Instruction::BinaryOps Opcode =
+ PBI->getSuccessor(0) == TrueDest ?
+ Instruction::Or : Instruction::And;
+ Value *NewCond =
+ BinaryOperator::create(Opcode, PBI->getCondition(),
+ New, "bothcond", PBI);
+ PBI->setCondition(NewCond);
+ if (PBI->getSuccessor(0) == BB) {
+ AddPredecessorToBlock(TrueDest, *PI, BB);
+ PBI->setSuccessor(0, TrueDest);
+ }
+ if (PBI->getSuccessor(1) == BB) {
+ AddPredecessorToBlock(FalseDest, *PI, BB);
+ PBI->setSuccessor(1, FalseDest);
+ }
+ return SimplifyCFG(BB) | 1;
+ }
+ }
+ }
+
// If this block ends with a branch instruction, and if there is one
// predecessor, see if the previous block ended with a branch on the same
// condition, which makes this conditional branch redundant.