On Mon, May 5, 2025 at 9:20 PM Andi Kleen <[email protected]> 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.