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.

Reply via email to