On Wed, Feb 22, 2023 at 7:42 PM Takayuki 'January June' Suwa
<jjsuwa_sys3...@yahoo.co.jp> wrote:
>
> In commit b2ef02e8cbbaf95fee98be255f697f47193960ec, the sibling call
> insn included (use (reg:SI A0_REG)) to fix the problem, which added
> a USE chain unconditionally to the data flow of register A0 during
> the sibling call.
>
> As a result, df_regs_ever_live_p (A0_REG) returns true, so even if
> register A0 is not used outside of the sibling call insn, saves and
> restores to stack slots are emitted in pro/epilogue, and finally
> code size increases.
> (This is why I never included (use A0) in sibling calls)
>
>     /* example */
>     extern int foo(int);
>     int test(int a) {
>       return foo(a * 3 + 1);
>     }
>
> ;; before
>     test:
>         addi    sp, sp, -16     ;; unneeded stack frame allocation (induced)
>         s32i.n  a0, sp, 12      ;; unneeded saving of register A0
>         l32i.n  a0, sp, 12      ;; unneeded restoration of register A0
>         addx2   a2, a2, a2
>         addi.n  a2, a2, 1
>         addi    sp, sp, 16      ;; unneeded stack frame freeing (induced)
>         j.l     foo, a9         ;; sibling call (truly needs register A0)
>
> The essential cause is that we emit (use A0) *before* the insns that
> does the stack pointer adjustment during epilogue expansion, so the
> liveness of register A0 ends early, so register A0 is reused afterwards.
>
> This patch fixes the problem and avoids such regression by doing the
> emit of (use A0) in the sibling call epilogue expansion at the end.
>
> ;; after
> test:
>         addx2   a2, a2, a2
>         addi.n  a2, a2, 1
>         j.l     foo, a9
>
> >From RTL-pass "315r.rnreg" by
> "gfortran -O3 -funroll-loops -mabi=call0 -S -da 
> gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":
>
>     ;; Function selector_init (__selectors_MOD_selector_init, funcdef_no=2, 
> decl_uid=987, cgraph_uid=3, symbol_order=4)
>     ...
>     (insn 3807 3806 3808 121 (set (reg:SI 15 a15)
>             (mem/c:SI (plus:SI (reg/f:SI 1 sp)
>                     (const_int 268 [0x10c])) [31  S4 A32])) 
> "gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":35:30 53 
> {movsi_internal}
>          (nil))
>     (insn 3808 3807 3809 121 (set (reg:SI 7 a7)
>             (const_int 288 [0x120])) 
> "gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":35:30 53 
> {movsi_internal}
>          (nil))
>     (insn 3809 3808 3810 121 (set (reg/f:SI 1 sp)
>             (plus:SI (reg/f:SI 1 sp)
>                 (reg:SI 7 a7))) 
> "gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":35:30 1 
> {addsi3}
>          (expr_list:REG_DEAD (reg:SI 9 a9)
>             (nil)))
>     (insn 3810 3809 721 121 (use (reg:SI 0 a0)) 
> "gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":35:30 -1
>          (expr_list:REG_DEAD (reg:SI 0 a0)
>             (nil)))
>     (call_insn/j 721 3810 722 121 (call (mem:SI (symbol_ref:SI ("free") 
> [flags 0x41]  <function_decl 0x7f7c885f6000 __builtin_free>) [0 
> __builtin_free S4 A32])
>             (const_int 0 [0])) 
> "gcc-gnu/gcc/testsuite/gfortran.dg/allocate_with_source_5.f90":35:30 discrim 
> 1 106 {sibcall_internal}
>          (expr_list:REG_DEAD (reg:SI 2 a2)
>             (expr_list:REG_CALL_DECL (symbol_ref:SI ("free") [flags 0x41]  
> <function_decl 0x7f7c885f6000 __builtin_free>)
>                 (expr_list:REG_EH_REGION (const_int 0 [0])
>                     (nil))))
>         (expr_list:SI (use (reg:SI 2 a2))
>             (nil)))
>
> (IMHO the "rnreg" pass doesn't take REG_ALLOC_ORDER into account;
> it just seems to allocate registers in fixed_regs index order,
> which may have hurt register A0 that became allocatable in the recent
> patch)
>
> gcc/ChangeLog:
>
>         * config/xtensa/xtensa.cc (xtensa_expand_epilogue):
>         Emit (use (reg:SI A0_REG)) at the end in the sibling call
>         (i.e. the same place as (return) in the normal call).
>         * config/xtensa/xtensa.md
>         (sibcall, sibcall_internal, sibcall_value, sibcall_value_internal):
>         Revert changes by the previous patch.
> ---
>  gcc/config/xtensa/xtensa.cc |  4 +++-
>  gcc/config/xtensa/xtensa.md | 20 +++++++-------------
>  2 files changed, 10 insertions(+), 14 deletions(-)

I've reverted my fix and committed this fix minus the revert.

-- 
Thanks.
-- Max

Reply via email to