From 1347e87c7baa78bd442d7017a8d67bd4fe674e01 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 13 Jul 2008 21:12:01 +0000 Subject: [PATCH] Refactor some code out into its own helper function, getting rid of crazy multiline conditionals and commenting the code better. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53526 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyCFG.cpp | 138 ++++++++++++++++----------- 1 file changed, 84 insertions(+), 54 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index c215b91259c..53725ea76c4 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1425,6 +1425,86 @@ static bool SimplifyCondBranchToTwoReturns(BranchInst *BI) { return true; } +/// FoldBranchToCommonDest - 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. +static bool FoldBranchToCommonDest(BranchInst *BI) { + Instruction *Cond = dyn_cast(BI->getCondition()); + if (Cond == 0) return false; + + BasicBlock *BB = BI->getParent(); + + // Only allow this if the condition is a simple instruction that can be + // executed unconditionally. It must be in the same block as the branch, and + // must be at the front of the block. + if ((!isa(Cond) && !isa(Cond)) || + Cond->getParent() != BB || &BB->front() != Cond || !Cond->hasOneUse()) + return false; + + // Make sure the instruction after the condition is the cond branch. + BasicBlock::iterator CondIt = Cond; ++CondIt; + if (&*CondIt != BI) + return false; + + // Finally, don't infinitely unroll conditional loops. + BasicBlock *TrueDest = BI->getSuccessor(0); + BasicBlock *FalseDest = BI->getSuccessor(1); + if (TrueDest == BB || FalseDest == BB) + return false; + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + BasicBlock *PredBlock = *PI; + BranchInst *PBI = dyn_cast(PredBlock->getTerminator()); + if (PBI == 0 || PBI->isUnconditional() || + !SafeToMergeTerminators(BI, PBI)) + continue; + + // Canonicalize the predecessors condition (inverting it) if needed to allow + // this xform to trigger. + if (PBI->getSuccessor(0) == FalseDest || + PBI->getSuccessor(1) == TrueDest) { + 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 && FalseDest != BB) || + (PBI->getSuccessor(1) == FalseDest && TrueDest != BB)) { + // Clone Cond into the predecessor basic block, and or/and the + // two conditions together. + Instruction *New = Cond->clone(); + PredBlock->getInstList().insert(PBI, New); + New->takeName(Cond); + Cond->setName(New->getName()+".old"); + + Value *NewCond; + if (PBI->getSuccessor(0) == TrueDest) + NewCond = BinaryOperator::CreateOr(PBI->getCondition(), New, "or.cond", + PBI); + else + NewCond = BinaryOperator::CreateOr(PBI->getCondition(), New, "and.cond", + PBI); + PBI->setCondition(NewCond); + if (PBI->getSuccessor(0) == BB) { + AddPredecessorToBlock(TrueDest, PredBlock, BB); + PBI->setSuccessor(0, TrueDest); + } + if (PBI->getSuccessor(1) == BB) { + AddPredecessorToBlock(FalseDest, PredBlock, BB); + PBI->setSuccessor(1, FalseDest); + } + return true; + } + } + return false; +} + namespace { /// ConstantIntOrdering - This class implements a stable ordering of constant @@ -1628,7 +1708,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { if (BBI->isTerminator() && // Terminator is the only non-phi instruction! Succ != BB) // Don't hurt infinite loops! if (TryToSimplifyUncondBranchFromEmptyBlock(BB, Succ)) - return 1; + return true; } else { // Conditional branch if (isValueEqualityComparison(BI)) { @@ -1658,59 +1738,9 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { // 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. - BasicBlock *TrueDest = BI->getSuccessor(0); - BasicBlock *FalseDest = BI->getSuccessor(1); - if (Instruction *Cond = dyn_cast(BI->getCondition())) { - BasicBlock::iterator CondIt = Cond; - if ((isa(Cond) || isa(Cond)) && - Cond->getParent() == BB && &BB->front() == Cond && - &*++CondIt == BI && Cond->hasOneUse() && - TrueDest != BB && FalseDest != BB) - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI!=E; ++PI) - if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) - if (PBI->isConditional() && SafeToMergeTerminators(BI, PBI)) { - BasicBlock *PredBlock = *PI; - 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 (FoldBranchToCommonDest(BI)) + return SimplifyCFG(BB) | 1; - if ((PBI->getSuccessor(0) == TrueDest && FalseDest != BB) || - (PBI->getSuccessor(1) == FalseDest && TrueDest != BB)) { - // Clone Cond into the predecessor basic block, and or/and the - // two conditions together. - Instruction *New = Cond->clone(); - PredBlock->getInstList().insert(PBI, New); - New->takeName(Cond); - Cond->setName(New->getName()+".old"); - 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, PredBlock, BB); - PBI->setSuccessor(0, TrueDest); - } - if (PBI->getSuccessor(1) == BB) { - AddPredecessorToBlock(FalseDest, PredBlock, BB); - PBI->setSuccessor(1, FalseDest); - } - return SimplifyCFG(BB) | 1; - } - } - } // Scan predessor blocks for conditional branches. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) @@ -1811,7 +1841,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { DOUT << "FOLDING BRs:" << *PBI->getParent() << "AND: " << *BI->getParent(); - + // BI may have other predecessors. Because of this, we leave // it alone, but modify PBI.