From 2e93c4275ef42f4e51a5eba11de38a1b6633520b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 1 May 2004 23:35:43 +0000 Subject: [PATCH] Implement SimplifyCFG/branch-cond-merge.ll Turning "if (A < B && B < C)" into "if (A < B & B < C)" llvm-svn: 13311 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 74 ++++++++++++++++++++--- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 7f2060fbfc82..dedaa6a657c2 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/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(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(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(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(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((*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.