aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrits van Bommel <fvbommel@gmail.com>2011-01-11 12:52:11 +0000
committerFrits van Bommel <fvbommel@gmail.com>2011-01-11 12:52:11 +0000
commit65fdded3197461232d8428af7ddd0107e4a9f946 (patch)
tree9af47880131164022b38fdedc5adbc383ab5229f
parent19823b19baaaa7638e4e69d7e1342dfee0ef9f2f (diff)
downloadexternal_llvm-65fdded3197461232d8428af7ddd0107e4a9f946.zip
external_llvm-65fdded3197461232d8428af7ddd0107e4a9f946.tar.gz
external_llvm-65fdded3197461232d8428af7ddd0107e4a9f946.tar.bz2
Factor the actual simplification out of SimplifyIndirectBrOnSelect and into a new helper function so it can be reused in e.g. an upcoming SimplifySwitchOnSelect.
No functional change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123234 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp63
1 files changed, 37 insertions, 26 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index c4fce5e..f6d7d76 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1728,22 +1728,13 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI) {
return true;
}
-// SimplifyIndirectBrOnSelect - Replaces
-// (indirectbr (select cond, blockaddress(@fn, BlockA),
-// blockaddress(@fn, BlockB)))
-// with
-// (br cond, BlockA, BlockB).
-static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
- // Check that both operands of the select are block addresses.
- BlockAddress *TBA = dyn_cast<BlockAddress>(SI->getTrueValue());
- BlockAddress *FBA = dyn_cast<BlockAddress>(SI->getFalseValue());
- if (!TBA || !FBA)
- return false;
-
- // Extract the actual blocks.
- BasicBlock *TrueBB = TBA->getBasicBlock();
- BasicBlock *FalseBB = FBA->getBasicBlock();
-
+// SimplifyTerminatorOnSelect - Simplifies a terminator by replacing it with a
+// branch to TrueBB if Cond is true or to FalseBB if Cond is false.
+// Takes care of updating the successors and removing the old terminator.
+// Also makes sure not to introduce new successors by assuming that edges to
+// non-successor TrueBBs and FalseBBs aren't reachable.
+static bool SimplifyTerminatorOnSelect(TerminatorInst *OldTerm, Value *Cond,
+ BasicBlock *TrueBB, BasicBlock *FalseBB){
// Remove any superfluous successor edges from the CFG.
// First, figure out which successors to preserve.
// If TrueBB and FalseBB are equal, only try to preserve one copy of that
@@ -1752,15 +1743,15 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
BasicBlock *KeepEdge2 = TrueBB != FalseBB ? FalseBB : 0;
// Then remove the rest.
- for (unsigned I = 0, E = IBI->getNumSuccessors(); I != E; ++I) {
- BasicBlock *Succ = IBI->getSuccessor(I);
+ for (unsigned I = 0, E = OldTerm->getNumSuccessors(); I != E; ++I) {
+ BasicBlock *Succ = OldTerm->getSuccessor(I);
// Make sure only to keep exactly one copy of each edge.
if (Succ == KeepEdge1)
KeepEdge1 = 0;
else if (Succ == KeepEdge2)
KeepEdge2 = 0;
else
- Succ->removePredecessor(IBI->getParent());
+ Succ->removePredecessor(OldTerm->getParent());
}
// Insert an appropriate new terminator.
@@ -1768,31 +1759,51 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
if (TrueBB == FalseBB)
// We were only looking for one successor, and it was present.
// Create an unconditional branch to it.
- BranchInst::Create(TrueBB, IBI);
+ BranchInst::Create(TrueBB, OldTerm);
else
// We found both of the successors we were looking for.
// Create a conditional branch sharing the condition of the select.
- BranchInst::Create(TrueBB, FalseBB, SI->getCondition(), IBI);
+ BranchInst::Create(TrueBB, FalseBB, Cond, OldTerm);
} else if (KeepEdge1 && (KeepEdge2 || TrueBB == FalseBB)) {
// Neither of the selected blocks were successors, so this
- // indirectbr must be unreachable.
- new UnreachableInst(IBI->getContext(), IBI);
+ // terminator must be unreachable.
+ new UnreachableInst(OldTerm->getContext(), OldTerm);
} else {
// One of the selected values was a successor, but the other wasn't.
// Insert an unconditional branch to the one that was found;
// the edge to the one that wasn't must be unreachable.
if (KeepEdge1 == 0)
// Only TrueBB was found.
- BranchInst::Create(TrueBB, IBI);
+ BranchInst::Create(TrueBB, OldTerm);
else
// Only FalseBB was found.
- BranchInst::Create(FalseBB, IBI);
+ BranchInst::Create(FalseBB, OldTerm);
}
- EraseTerminatorInstAndDCECond(IBI);
+ EraseTerminatorInstAndDCECond(OldTerm);
return true;
}
+// SimplifyIndirectBrOnSelect - Replaces
+// (indirectbr (select cond, blockaddress(@fn, BlockA),
+// blockaddress(@fn, BlockB)))
+// with
+// (br cond, BlockA, BlockB).
+static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
+ // Check that both operands of the select are block addresses.
+ BlockAddress *TBA = dyn_cast<BlockAddress>(SI->getTrueValue());
+ BlockAddress *FBA = dyn_cast<BlockAddress>(SI->getFalseValue());
+ if (!TBA || !FBA)
+ return false;
+
+ // Extract the actual blocks.
+ BasicBlock *TrueBB = TBA->getBasicBlock();
+ BasicBlock *FalseBB = FBA->getBasicBlock();
+
+ // Perform the actual simplification.
+ return SimplifyTerminatorOnSelect(IBI, SI->getCondition(), TrueBB, FalseBB);
+}
+
/// TryToSimplifyUncondBranchWithICmpInIt - This is called when we find an icmp
/// instruction (a seteq/setne with a constant) as the only instruction in a
/// block that ends with an uncond branch. We are looking for a very specific