diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-04-28 22:47:15 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-04-29 01:01:01 +0300 |
commit | 1886aad9d03b95c35260d6d8013d746bd39dc94a (patch) | |
tree | 7f74c863f8aee76cbb13878bc9ebffea5693624c | |
parent | 410d03aabf725abcd6e3c5d11f4c2f4c9604627b (diff) | |
download | llvm-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.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll | 9 |
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: |