summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2021-04-28 22:47:15 +0300
committerRoman Lebedev <lebedev.ri@gmail.com>2021-04-29 01:01:01 +0300
commit1886aad9d03b95c35260d6d8013d746bd39dc94a (patch)
tree7f74c863f8aee76cbb13878bc9ebffea5693624c
parent410d03aabf725abcd6e3c5d11f4c2f4c9604627b (diff)
downloadllvm-1886aad9d03b95c35260d6d8013d746bd39dc94a.tar.gz
[SimplifyCFG] Common code sinking: relax restriction on non-uncond predecessors
While we have a known profitability issue for sinking in presence of non-unconditional predecessors, there isn't any known issues for having multiple such non-unconditional predecessors, so said restriction appears to be artificial. Lift it.
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp16
-rw-r--r--llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll9
2 files changed, 10 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 77c0890fa91e..0704c5f2321a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1988,15 +1988,13 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
// [ end ]
//
SmallVector<BasicBlock*,4> UnconditionalPreds;
- Instruction *Cond = nullptr;
- for (auto *B : predecessors(BB)) {
- auto *T = B->getTerminator();
- if (isa<BranchInst>(T) && cast<BranchInst>(T)->isUnconditional())
- UnconditionalPreds.push_back(B);
- else if ((isa<BranchInst>(T) || isa<SwitchInst>(T)) && !Cond)
- Cond = T;
+ bool AllPredsAreUnconditional = false;
+ for (auto *PredBB : predecessors(BB)) {
+ auto *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator());
+ if (PredBr && PredBr->isUnconditional())
+ UnconditionalPreds.push_back(PredBB);
else
- return false;
+ AllPredsAreUnconditional = true;
}
if (UnconditionalPreds.size() < 2)
return false;
@@ -2063,7 +2061,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
bool Changed = false;
- if (Cond) {
+ if (AllPredsAreUnconditional) {
// It is always legal to sink common instructions from unconditional
// predecessors. However, if not all predecessors are unconditional,
// this transformation might be pessimizing. So as a rule of thumb,
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
index ade36c7019d1..a85ad8e69a20 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
@@ -1538,14 +1538,11 @@ define void @multiple_cond_preds(i1 %c0, i1 %c1, i1 %c2) {
; CHECK-NEXT: br i1 [[C0:%.*]], label [[DISPATCH1:%.*]], label [[DISPATCH2:%.*]]
; CHECK: dispatch1:
; CHECK-NEXT: call void @direct_callee2()
-; CHECK-NEXT: br i1 [[C1:%.*]], label [[UNCOND_PRED0:%.*]], label [[END:%.*]]
+; CHECK-NEXT: br i1 [[C1:%.*]], label [[END_SINK_SPLIT:%.*]], label [[END:%.*]]
; CHECK: dispatch2:
; CHECK-NEXT: call void @direct_callee3()
-; CHECK-NEXT: br i1 [[C2:%.*]], label [[UNCOND_PRED1:%.*]], label [[END]]
-; CHECK: uncond_pred0:
-; CHECK-NEXT: call void @direct_callee()
-; CHECK-NEXT: br label [[END]]
-; CHECK: uncond_pred1:
+; CHECK-NEXT: br i1 [[C2:%.*]], label [[END_SINK_SPLIT]], label [[END]]
+; CHECK: end.sink.split:
; CHECK-NEXT: call void @direct_callee()
; CHECK-NEXT: br label [[END]]
; CHECK: end: