[llvm] r251557 - [JumpThreading] Use dominating conditions to prove implications

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 28 14:27:08 PDT 2015


Author: sanjoy
Date: Wed Oct 28 16:27:08 2015
New Revision: 251557

URL: http://llvm.org/viewvc/llvm-project?rev=251557&view=rev
Log:
[JumpThreading] Use dominating conditions to prove implications

Summary:
If P branches to Q conditional on C and Q branches to R conditional on
C' and C => C' then the branch conditional on C' can be folded to an
unconditional branch.

Reviewers: reames

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13972

Added:
    llvm/trunk/test/Transforms/JumpThreading/implied-cond.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=251557&r1=251556&r2=251557&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Oct 28 16:27:08 2015
@@ -29,6 +29,7 @@
 #include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
@@ -57,6 +58,13 @@ BBDuplicateThreshold("jump-threading-thr
           cl::desc("Max block size to duplicate for jump threading"),
           cl::init(6), cl::Hidden);
 
+static cl::opt<unsigned>
+ImplicationSearchThreshold(
+  "jump-threading-implication-search-threshold",
+  cl::desc("The number of predecessors to search for a stronger "
+           "condition to use to thread over a weaker condition"),
+  cl::init(3), cl::Hidden);
+
 namespace {
   // These are at global scope so static functions can use them too.
   typedef SmallVectorImpl<std::pair<Constant*, BasicBlock*> > PredValueInfo;
@@ -151,6 +159,7 @@ namespace {
 
     bool ProcessBranchOnPHI(PHINode *PN);
     bool ProcessBranchOnXOR(BinaryOperator *BO);
+    bool ProcessImpliedCondition(BasicBlock *BB);
 
     bool SimplifyPartiallyRedundantLoad(LoadInst *LI);
     bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
@@ -868,9 +877,38 @@ bool JumpThreading::ProcessBlock(BasicBl
       CondInst->getParent() == BB && isa<BranchInst>(BB->getTerminator()))
     return ProcessBranchOnXOR(cast<BinaryOperator>(CondInst));
 
+  // Search for a stronger dominating condition that can be used to simplify a
+  // conditional branch leaving BB.
+  if (ProcessImpliedCondition(BB))
+    return true;
+
+  return false;
+}
 
-  // TODO: If we have: "br (X > 0)"  and we have a predecessor where we know
-  // "(X == 4)", thread through this block.
+bool JumpThreading::ProcessImpliedCondition(BasicBlock *BB) {
+  auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
+  if (!BI || !BI->isConditional())
+    return false;
+
+  Value *Cond = BI->getCondition();
+  BasicBlock *CurrentBB = BB;
+  BasicBlock *CurrentPred = BB->getSinglePredecessor();
+  unsigned Iter = 0;
+
+  while (CurrentPred && Iter++ < ImplicationSearchThreshold) {
+    auto *PBI = dyn_cast<BranchInst>(CurrentPred->getTerminator());
+    if (!PBI || !PBI->isConditional() || PBI->getSuccessor(0) != CurrentBB)
+      return false;
+
+    if (isImpliedCondition(PBI->getCondition(), Cond)) {
+      BI->getSuccessor(1)->removePredecessor(BB);
+      BranchInst::Create(BI->getSuccessor(0), BI);
+      BI->eraseFromParent();
+      return true;
+    }
+    CurrentBB = CurrentPred;
+    CurrentPred = CurrentBB->getSinglePredecessor();
+  }
 
   return false;
 }

Added: llvm/trunk/test/Transforms/JumpThreading/implied-cond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/implied-cond.ll?rev=251557&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/implied-cond.ll (added)
+++ llvm/trunk/test/Transforms/JumpThreading/implied-cond.ll Wed Oct 28 16:27:08 2015
@@ -0,0 +1,98 @@
+; RUN: opt -jump-threading -S < %s | FileCheck %s
+
+declare void @side_effect(i32)
+
+define void @test0(i32 %i, i32 %len) {
+; CHECK-LABEL: @test0(
+ entry:
+  call void @side_effect(i32 0)
+  %i.inc = add nuw i32 %i, 1
+  %c0 = icmp ult i32 %i.inc, %len
+  br i1 %c0, label %left, label %right
+
+ left:
+; CHECK: entry:
+; CHECK: br i1 %c0, label %left0, label %right
+
+; CHECK: left0:
+; CHECK: call void @side_effect
+; CHECK-NOT: br i1 %c1
+; CHECK: call void @side_effect
+  call void @side_effect(i32 0)
+  %c1 = icmp ult i32 %i, %len
+  br i1 %c1, label %left0, label %right
+
+ left0:
+  call void @side_effect(i32 0)
+  ret void
+
+ right:
+  %t = phi i32 [ 1, %left ], [ 2, %entry ]
+  call void @side_effect(i32 %t)
+  ret void
+}
+
+define void @test1(i32 %i, i32 %len) {
+; CHECK-LABEL: @test1(
+ entry:
+  call void @side_effect(i32 0)
+  %i.inc = add nsw i32 %i, 1
+  %c0 = icmp slt i32 %i.inc, %len
+  br i1 %c0, label %left, label %right
+
+ left:
+; CHECK: entry:
+; CHECK: br i1 %c0, label %left0, label %right
+
+; CHECK: left0:
+; CHECK: call void @side_effect
+; CHECK-NOT: br i1 %c1
+; CHECK: call void @side_effect
+  call void @side_effect(i32 0)
+  %c1 = icmp slt i32 %i, %len
+  br i1 %c1, label %left0, label %right
+
+ left0:
+  call void @side_effect(i32 0)
+  ret void
+
+ right:
+  %t = phi i32 [ 1, %left ], [ 2, %entry ]
+  call void @side_effect(i32 %t)
+  ret void
+}
+
+define void @test2(i32 %i, i32 %len, i1* %c.ptr) {
+; CHECK-LABEL: @test2(
+
+; CHECK: entry:
+; CHECK: br i1 %c0, label %cont, label %right
+; CHECK: cont:
+; CHECK: br i1 %c, label %left0, label %right
+; CHECK: left0:
+; CHECK: call void @side_effect(i32 0)
+; CHECK: call void @side_effect(i32 0)
+ entry:
+  call void @side_effect(i32 0)
+  %i.inc = add nsw i32 %i, 1
+  %c0 = icmp slt i32 %i.inc, %len
+  br i1 %c0, label %cont, label %right
+
+ cont:
+  %c = load i1, i1* %c.ptr
+  br i1 %c, label %left, label %right
+
+ left:
+  call void @side_effect(i32 0)
+  %c1 = icmp slt i32 %i, %len
+  br i1 %c1, label %left0, label %right
+
+ left0:
+  call void @side_effect(i32 0)
+  ret void
+
+ right:
+  %t = phi i32 [ 1, %left ], [ 2, %entry ], [ 3, %cont ]
+  call void @side_effect(i32 %t)
+  ret void
+}




More information about the llvm-commits mailing list