From 9f717d7b941fbc42bef017b84c4dd0f65ce06e7a Mon Sep 17 00:00:00 2001 From: Juneyoung Lee Date: Fri, 31 Jul 2020 23:25:56 +0900 Subject: [PATCH] [JumpThreading] Allow duplicating a basic block into preds when its branch condition is freeze(phi) This is the last JumpThreading patch for getting the performance numbers shown at https://reviews.llvm.org/D84940#2184653 . This patch makes ProcessBlock call ProcessBranchOnPHI when the branch condition is freeze(phi) as well (originally it calls the function when the condition is phi only). Since what ProcessBranchOnPHI does is to duplicate the basic block into predecessors if profitable, it is still valid when the condition is freeze(phi) too. ``` p = phi [a, pred1] [b, pred2] p.fr = freeze p br p.fr, ... => pred1: p.fr = freeze a br p.fr, ... pred2: p.fr2 = freeze b br p.fr2, ... ``` Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D85029 --- llvm/lib/Transforms/Scalar/JumpThreading.cpp | 20 +++++++++++++------- .../Transforms/JumpThreading/phi-copy-to-pred.ll | 14 ++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 57ebeea..311ca11 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1190,11 +1190,14 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { if (ProcessThreadableEdges(CondInst, BB, Preference, Terminator)) return true; - // If this is an otherwise-unfoldable branch on a phi node in the current - // block, see if we can simplify. - if (PHINode *PN = dyn_cast(CondInst)) - if (PN->getParent() == BB && isa(BB->getTerminator())) - return ProcessBranchOnPHI(PN); + // If this is an otherwise-unfoldable branch on a phi node or freeze(phi) in + // the current block, see if we can simplify. + PHINode *PN = dyn_cast( + isa(CondInst) ? cast(CondInst)->getOperand(0) + : CondInst); + + if (PN && PN->getParent() == BB && isa(BB->getTerminator())) + return ProcessBranchOnPHI(PN); // If this is an otherwise-unfoldable branch on a XOR, see if we can simplify. if (CondInst->getOpcode() == Instruction::Xor && @@ -1750,8 +1753,8 @@ bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB, } /// ProcessBranchOnPHI - We have an otherwise unthreadable conditional branch on -/// a PHI node in the current block. See if there are any simplifications we -/// can do based on inputs to the phi node. +/// a PHI node (or freeze PHI) in the current block. See if there are any +/// simplifications we can do based on inputs to the phi node. bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) { BasicBlock *BB = PN->getParent(); @@ -1764,6 +1767,9 @@ bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) { // *duplicate* the conditional branch into that block in order to further // encourage jump threading and to eliminate cases where we have branch on a // phi of an icmp (branch on icmp is much better). + // This is still beneficial when a frozen phi is used as the branch condition + // because it allows CodeGenPrepare to further canonicalize br(freeze(icmp)) + // to br(icmp(freeze ...)). for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { BasicBlock *PredBB = PN->getIncomingBlock(i); if (BranchInst *PredBr = dyn_cast(PredBB->getTerminator())) diff --git a/llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll b/llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll index 9d16b44..0266e15 100644 --- a/llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll +++ b/llvm/test/Transforms/JumpThreading/phi-copy-to-pred.ll @@ -37,17 +37,15 @@ EXIT2: define i32 @test2(i1 %cond, i1 %a, i1 %b) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] +; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[C:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @f() -; CHECK-NEXT: br label [[C:%.*]] -; CHECK: B: -; CHECK-NEXT: call void @g() -; CHECK-NEXT: br label [[C]] +; CHECK-NEXT: [[P_FR1:%.*]] = freeze i1 [[A:%.*]] +; CHECK-NEXT: br i1 [[P_FR1]], label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: C: -; CHECK-NEXT: [[P:%.*]] = phi i1 [ [[A:%.*]], [[A]] ], [ [[B:%.*]], [[B]] ] -; CHECK-NEXT: [[P_FR:%.*]] = freeze i1 [[P]] -; CHECK-NEXT: br i1 [[P_FR]], label [[EXIT1:%.*]], label [[EXIT2:%.*]] +; CHECK-NEXT: call void @g() +; CHECK-NEXT: [[P_FR:%.*]] = freeze i1 [[B:%.*]] +; CHECK-NEXT: br i1 [[P_FR]], label [[EXIT1]], label [[EXIT2]] ; CHECK: EXIT1: ; CHECK-NEXT: ret i32 0 ; CHECK: EXIT2: -- 2.7.4