[llvm] [BranchFolding] Fold fallthroughs into conditional tailcalls if profitable (PR #140476)
Nabeel Omer via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 15 08:50:31 PDT 2025
================
@@ -1553,32 +1554,54 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
MachineInstr &TailCall = *MBB->getFirstNonDebugInstr();
if (TII->isUnconditionalTailCall(TailCall)) {
SmallVector<MachineBasicBlock *> PredsChanged;
- for (auto &Pred : MBB->predecessors()) {
+ for (auto *Pred : MBB->predecessors()) {
+ bool PredHasHotSuccessor = false;
+ for (MachineBasicBlock *const PredSucc : Pred->successors()) {
+ PredHasHotSuccessor |= MBPI.isEdgeHot(Pred, PredSucc);
+ }
+
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.
+ bool IsEdgeCold = !MBPI.isEdgeHot(Pred, MBB);
+ bool CanFoldFallThrough =
+ PredHasHotSuccessor && IsEdgeCold &&
+ (MBB == PredFBB ||
+ (PredFBB == nullptr && Pred->getFallThrough() == MBB));
+ bool CanFoldTakenBlock =
+ (MBB == PredTBB && (PredHasHotSuccessor ? IsEdgeCold : true));
+
+ // When we have PGO (or equivalent) information, we want to fold the
+ // fallthrough if it's cold. Folding a fallthrough puts it behind a
+ // conditional branch which isn't desirable if it's hot. When there
+ // isn't any PGO information available we want to fold the taken block
+ // if it's possible and we never want to fold the fallthrough as we
+ // don't know if that is desirable.
+ if (PredAnalyzable && !PredCond.empty() && PredTBB != PredFBB &&
+ (CanFoldTakenBlock || CanFoldFallThrough)) {
+ SmallVector<MachineOperand, 4> ReversedCond(PredCond);
+ if (CanFoldFallThrough) {
+ DebugLoc Dl = MBB->findBranchDebugLoc();
+ TII->reverseBranchCondition(ReversedCond);
----------------
omern1 wrote:
I think I'm not understanding your concern, could you please clarify further?
With my patch applied we get the following probability out of branch-folder for the `true_likely` test:
```
bb.0 (%ir-block.1):
successors: %bb.1(0x7fef9fcb); %bb.1(99.95%)
...
```
`%bb.1` is the hot fallthrough successor.
The probabilities in the input MIR are:
```
...
successors: %bb.1(0x7fef9fcb), %bb.2(0x00106035); %bb.1(99.95%), %bb.2(0.05%)
...
```
This seems correct to me based on the following assumptions:
- I don't think there's a way of expressing the probability of a tailcall edge.
- The probability of reaching the successor appears to be correct.
https://github.com/llvm/llvm-project/pull/140476
More information about the llvm-commits
mailing list