aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorXChy <xxs_chy@outlook.com>2024-04-16 18:51:03 +0800
committerGitHub <noreply@github.com>2024-04-16 18:51:03 +0800
commit36b3c26451bf9a42f0b6b415993d3942bb73abdd (patch)
treefe65e4d4ae3e78809913f2d8b9645c7412969fd0 /llvm/lib/Transforms/Utils/Local.cpp
parent1120d8e6f799121b611aa23bdc128e40cf9c6c58 (diff)
downloadllvm-36b3c26451bf9a42f0b6b415993d3942bb73abdd.zip
llvm-36b3c26451bf9a42f0b6b415993d3942bb73abdd.tar.gz
llvm-36b3c26451bf9a42f0b6b415993d3942bb73abdd.tar.bz2
[JumpThreading] Thread over BB with only an unconditional branch (#86312)
Fixes #76609 This patch does: - relax the phis constraint in `CanRedirectPredsOfEmptyBBToSucc` - guarantee the BB has multiple different predecessors to redirect, so that we can handle the case without phis in BB. Without this change and phi constraint, we may redirect the CommonPred. The motivation is consistent with JumpThreading. We always want the branch to jump more direct to the destination, without passing the middle block. In this way, we can expose more other optimization opportunities. An obivous example proposed by @dtcxzyw is like: ```llvm define i32 @test(...) { entry: br i1 %c, label %do.end, label %if.then if.then: ; preds = %entry %call2 = call i32 @dummy() %tobool3.not = icmp eq i32 %call2, 0 br i1 %tobool3.not, label %do.end, label %return do.end: ; preds = %entry, %if.then br label %return return: ; preds = %if.then, %do.end %retval.0 = phi i32 [ 0, %do.end ], [ %call2, %if.then ] ret i32 %retval.0 } ``` `entry` can directly jump to return, without passing `do.end`, and then the if-else pattern can be simplified further: ```llvm define i32 @test(...) { entry: br i1 %c, label %return, label %if.then if.then: ; preds = %entry %call2 = call i32 @dummy() br label %return return: ; preds = %if.then %retval.0 = phi i32 [ 0, %entry ], [ %call2, %if.then ] ret i32 %retval.0 } ```
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index a42ef0c..baec51a 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1019,12 +1019,14 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
const SmallPtrSetImpl<BasicBlock *> &SuccPreds,
BasicBlock *&CommonPred) {
- // There must be phis in BB, otherwise BB will be merged into Succ directly
- if (BB->phis().empty() || Succ->phis().empty())
+ // When Succ has no phis, BB may be merged into Succ directly. We don't need
+ // to redirect the predecessors of BB in this case.
+ if (Succ->phis().empty())
return false;
- // BB must have predecessors not shared that can be redirected to Succ
- if (!BB->hasNPredecessorsOrMore(2))
+ // BB must have multiple different predecessors, so that at least one of
+ // predecessors can be redirected to Succ, except the common predecessor.
+ if (BB->getUniquePredecessor() || pred_empty(BB))
return false;
// Get single common predecessors of both BB and Succ