summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/JumpThreading.cpp
diff options
context:
space:
mode:
authorXin Tong <trent.xin.tong@gmail.com>2017-04-23 20:56:29 +0000
committerXin Tong <trent.xin.tong@gmail.com>2017-04-23 20:56:29 +0000
commitf98602a1abe1c40921c8b67627b43cce36550b2f (patch)
tree257682987f7aa5f1200c3c344ccb7f0000253812 /llvm/lib/Transforms/Scalar/JumpThreading.cpp
parent1d2169e2ee40011489c0660452188c288a9d2e39 (diff)
downloadbcm5719-llvm-f98602a1abe1c40921c8b67627b43cce36550b2f.tar.gz
bcm5719-llvm-f98602a1abe1c40921c8b67627b43cce36550b2f.zip
[JumpThread] We want to fold (not thread) when all predecessor go to single BB's successor.
Summary: In case all predecessor go to a single successor of current BB. We want to fold (not thread). I failed to update the phi nodes properly in the last patch https://reviews.llvm.org/rL300657. Phi nodes values are per predecessor in LLVM. Reviewers: sanjoy Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32400 llvm-svn: 301139
Diffstat (limited to 'llvm/lib/Transforms/Scalar/JumpThreading.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 08eb95a1a3d..a0da81605a8 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1289,6 +1289,36 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
if (PredToDestList.empty())
return false;
+ // If all the predecessors go to a single known successor, we want to fold,
+ // not thread. By doing so, we do not need to duplicate the current block and
+ // also miss potential opportunities in case we dont/cant duplicate.
+ if (OnlyDest && OnlyDest != MultipleDestSentinel) {
+ if (PredToDestList.size() ==
+ (size_t)std::distance(pred_begin(BB), pred_end(BB))) {
+ bool SeenFirstBranchToOnlyDest = false;
+ for (BasicBlock *SuccBB : successors(BB)) {
+ if (SuccBB == OnlyDest && !SeenFirstBranchToOnlyDest)
+ SeenFirstBranchToOnlyDest = true; // Don't modify the first branch.
+ else
+ SuccBB->removePredecessor(BB, true); // This is unreachable successor.
+ }
+
+ // Finally update the terminator.
+ TerminatorInst *Term = BB->getTerminator();
+ BranchInst::Create(OnlyDest, Term);
+ Term->eraseFromParent();
+
+ // If the condition is now dead due to the removal of the old terminator,
+ // erase it.
+ auto *CondInst = dyn_cast<Instruction>(Cond);
+ if (CondInst && CondInst->use_empty())
+ CondInst->eraseFromParent();
+ // FIXME: in case this instruction is defined in the current BB and it
+ // resolves to a single value from all predecessors, we can do RAUW.
+ return true;
+ }
+ }
+
// Determine which is the most common successor. If we have many inputs and
// this block is a switch, we want to start by threading the batch that goes
// to the most popular destination first. If we only know about one
OpenPOWER on IntegriCloud