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

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



Sanjoy Das via llvm-commits wrote:
> 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

Just FYI: this was reviewed and LGTM'ed by hfinkel.  The commit message 
is stale.

-- Sanjoy

>
> 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
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list