On Mon, May 5, 2025 at 9:20 PM Andi Kleen <a...@firstfloor.org> wrote: > > > If the branch edge destination is a basic block with only a direct > > sibcall, change the jcc target to the sibcall target, decrement the > > destination basic block entry label use count and redirect the edge > > to the exit basic block. Call delete_unreachable_blocks to delete > > the unreachable basic blocks at the end if edges are redirected. > > Its hard to believe this needs a new pass. Could the existing middle end > tail call code handle it somehow?
I don't know if all targets support condition tail call and I feel more comfortable with RTL passes. > Each new pass makes the compiler a little slower. > > > + FOR_EACH_BB_FN (bb, cfun) > > + { > > + FOR_BB_INSNS (bb, insn) > > + { > > + if (!JUMP_P (insn)) > > + continue; > > Instead of searching all basic blocks this could search from the end > simllar to tree tailcall Good idea. I can change it to FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) { /* Search backward from sibcalls. */ bb = e->src; insn = BB_END (bb); if (!insn || !CALL_P (insn) || !SIBLING_CALL_P (insn)) continue; edge branch_edge; edge_iterator branch_edgei; /* Check for conditional jump to this block. */ FOR_EACH_EDGE (branch_edge, branch_edgei, bb->preds) With this approach, the pass will run only if there is a tail call. > > + /* opt_pass methods: */ > > + bool gate (function *) final override > > + { > > + return optimize; > > Thia needs to depend on the existing tail call options. I would also I can change it to bool gate (function *) final override { return flag_optimize_sibling_calls != 0 && dbg_cnt (tail_call); } > add a new option because it is highly likely to break some unwinders > and static asm analysis tools like Linux objtool. Does the gcc unwinding > or gdb calltrace still work? > > Andi -- H.J.