diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-02-06 12:05:44 -0600 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-02-06 14:09:17 -0600 |
commit | ee5585ed09aff2e54cb540fad4c33f0c93626b1b (patch) | |
tree | effa420328562433cc470461e12f9ad32abaee92 /llvm/lib/CodeGen/BranchFolding.cpp | |
parent | 725b72c1fa608c886a1a5dbb75df23a05e91d5e8 (diff) | |
download | llvm-ee5585ed09aff2e54cb540fad4c33f0c93626b1b.zip llvm-ee5585ed09aff2e54cb540fad4c33f0c93626b1b.tar.gz llvm-ee5585ed09aff2e54cb540fad4c33f0c93626b1b.tar.bz2 |
Recommit "Improve and enable folding of conditional branches with tail calls." (2nd Try)
Improve and enable folding of conditional branches with tail calls.
1. Make it so that conditional tail calls can be emitted even when
there are multiple predecessors.
2. Don't guard the transformation behind -Os. The rationale for
guarding it was static-prediction can be affected by whether the
branch is forward of backward. This is no longer true for almost any
X86 cpus (anything newer than `SnB`) so is no longer a meaningful
concern.
Reviewed By: pengfei
Differential Revision: https://reviews.llvm.org/D140931
Diffstat (limited to 'llvm/lib/CodeGen/BranchFolding.cpp')
-rw-r--r-- | llvm/lib/CodeGen/BranchFolding.cpp | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index d491691..d5bf62c 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -1507,42 +1507,43 @@ ReoptimizeBlock: } } - bool OptForSize = - MF.getFunction().hasOptSize() || - llvm::shouldOptimizeForSize(MBB, PSI, &MBBFreqInfo); - if (!IsEmptyBlock(MBB) && MBB->pred_size() == 1 && OptForSize) { - // Changing "Jcc foo; foo: jmp bar;" into "Jcc bar;" might change the branch - // direction, thereby defeating careful block placement and regressing - // performance. Therefore, only consider this for optsize functions. + if (!IsEmptyBlock(MBB)) { MachineInstr &TailCall = *MBB->getFirstNonDebugInstr(); if (TII->isUnconditionalTailCall(TailCall)) { - MachineBasicBlock *Pred = *MBB->pred_begin(); - MachineBasicBlock *PredTBB = nullptr, *PredFBB = nullptr; - SmallVector<MachineOperand, 4> PredCond; - bool PredAnalyzable = - !TII->analyzeBranch(*Pred, PredTBB, PredFBB, PredCond, true); - - if (PredAnalyzable && !PredCond.empty() && PredTBB == MBB && - PredTBB != PredFBB) { - // The predecessor has a conditional branch to this block which consists - // of only a tail call. Try to fold the tail call into the conditional - // branch. - if (TII->canMakeTailCallConditional(PredCond, TailCall)) { - // TODO: It would be nice if analyzeBranch() could provide a pointer - // to the branch instruction so replaceBranchWithTailCall() doesn't - // have to search for it. - TII->replaceBranchWithTailCall(*Pred, PredCond, TailCall); - ++NumTailCalls; - Pred->removeSuccessor(MBB); - MadeChange = true; - return MadeChange; + SmallVector<MachineBasicBlock *> PredsChanged; + for (auto &Pred : MBB->predecessors()) { + MachineBasicBlock *PredTBB = nullptr, *PredFBB = nullptr; + SmallVector<MachineOperand, 4> PredCond; + bool PredAnalyzable = + !TII->analyzeBranch(*Pred, PredTBB, PredFBB, PredCond, true); + + // Only eliminate if MBB == TBB (Taken Basic Block) + if (PredAnalyzable && !PredCond.empty() && PredTBB == MBB && + PredTBB != PredFBB) { + // The predecessor has a conditional branch to this block which + // consists of only a tail call. Try to fold the tail call into the + // conditional branch. + if (TII->canMakeTailCallConditional(PredCond, TailCall)) { + // TODO: It would be nice if analyzeBranch() could provide a pointer + // to the branch instruction so replaceBranchWithTailCall() doesn't + // have to search for it. + TII->replaceBranchWithTailCall(*Pred, PredCond, TailCall); + PredsChanged.push_back(Pred); + } } + // If the predecessor is falling through to this block, we could reverse + // the branch condition and fold the tail call into that. However, after + // that we might have to re-arrange the CFG to fall through to the other + // block and there is a high risk of regressing code size rather than + // improving it. + } + if (!PredsChanged.empty()) { + NumTailCalls += PredsChanged.size(); + for (auto &Pred : PredsChanged) + Pred->removeSuccessor(MBB); + + return true; } - // If the predecessor is falling through to this block, we could reverse - // the branch condition and fold the tail call into that. However, after - // that we might have to re-arrange the CFG to fall through to the other - // block and there is a high risk of regressing code size rather than - // improving it. } } |