summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-07-13 21:12:01 +0000
committerChris Lattner <sabre@nondot.org>2008-07-13 21:12:01 +0000
commit1347e87c7baa78bd442d7017a8d67bd4fe674e01 (patch)
tree5fa024996afb70d4af372f8cb54ad295fabd4fd9 /lib/Transforms/Utils
parent56eb1330953edc1769f3add1d5cccfac3c26de25 (diff)
downloadllvm-1347e87c7baa78bd442d7017a8d67bd4fe674e01.tar.gz
llvm-1347e87c7baa78bd442d7017a8d67bd4fe674e01.tar.bz2
llvm-1347e87c7baa78bd442d7017a8d67bd4fe674e01.tar.xz
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
Diffstat (limited to 'lib/Transforms/Utils')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp138
1 files changed, 84 insertions, 54 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index c215b91259..53725ea76c 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<Instruction>(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<CmpInst>(Cond) && !isa<BinaryOperator>(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<BranchInst>(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<Instruction>(BI->getCondition())) {
- BasicBlock::iterator CondIt = Cond;
- if ((isa<CmpInst>(Cond) || isa<BinaryOperator>(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<BranchInst>((*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.