Re: [PATCH 1/2] x86: Add no_callee_saved_registers function attribute

2024-01-22 Thread H.J. Lu
On Sun, Jan 21, 2024 at 8:03 PM Hongtao Liu  wrote:
>
> On Sat, Jan 20, 2024 at 10:30 PM H.J. Lu  wrote:
> >
> > When an interrupt handler is implemented by an assembly stub which does:
> >
> > 1. Save all registers.
> > 2. Call a C function.
> > 3. Restore all registers.
> > 4. Return from interrupt.
> >
> > it is completely unnecessary to save and restore any registers in the C
> > function called by the assembly stub, even if they would normally be
> > callee-saved.
> >
> > Add no_callee_saved_registers function attribute, which is complementary
> > to no_caller_saved_registers function attribute, to mark a function which
> > doesn't have any callee-saved registers.  Such a function won't save and
> > restore any registers.  Classify function call-saved register handling
> > type with:
> >
> > 1. Default call-saved registers.
> > 2. No caller-saved registers with no_caller_saved_registers attribute.
> > 3. No callee-saved registers with no_callee_saved_registers attribute.
> >
> > Disallow sibcall if callee is a no_callee_saved_registers function
> > and caller isn't a no_callee_saved_registers function.  Otherwise,
> > callee-saved registers won't be preserved.
> >
> > After a no_callee_saved_registers function is called, all registers may
> > be clobbered.  If the calling function isn't a no_callee_saved_registers
> > function, we need to preserve all registers which aren't used by function
> > calls.
> >
> > gcc/
> >
> > PR target/103503
> > PR target/113312
> > * config/i386/i386-expand.cc (ix86_expand_call): Set
> > call_no_callee_saved_registers to true when calling function
> > with no_callee_saved_registers attribute.  Replace
> > no_caller_saved_registers check with call_saved_registers check.
> > * config/i386/i386-options.cc (ix86_set_func_type): Set
> > call_saved_registers to TYPE_NO_CALLEE_SAVED_REGISTERS for
> > noreturn function.  Disallow no_callee_saved_registers with
> > interrupt or no_caller_saved_registers attributes together.
> > (ix86_set_current_function): Replace no_caller_saved_registers
> > check with call_saved_registers check.
> > (ix86_handle_no_caller_saved_registers_attribute): Renamed to ...
> > (ix86_handle_call_saved_registers_attribute): This.
> > (ix86_gnu_attributes): Add
> > ix86_handle_call_saved_registers_attribute.
> > * config/i386/i386.cc (ix86_conditional_register_usage): Replace
> > no_caller_saved_registers check with call_saved_registers check.
> > (ix86_function_ok_for_sibcall): Don't allow callee with
> > no_callee_saved_registers attribute when the calling function
> > has callee-saved registers.
> > (ix86_comp_type_attributes): Also check
> > no_callee_saved_registers.
> > (ix86_epilogue_uses): Replace no_caller_saved_registers check
> > with call_saved_registers check.
> > (ix86_hard_regno_scratch_ok): Likewise.
> > (ix86_save_reg): Replace no_caller_saved_registers check with
> > call_saved_registers check.  Don't save any registers for
> > TYPE_NO_CALLEE_SAVED_REGISTERS.  Save all registers with
> > TYPE_DEFAULT_CALL_SAVED_REGISTERS if function with
> > no_callee_saved_registers attribute is called.
> > (find_drap_reg): Replace no_caller_saved_registers check with
> > call_saved_registers check.
> > * config/i386/i386.h (call_saved_registers_type): New enum.
> > (machine_function): Replace no_caller_saved_registers with
> > call_saved_registers.  Add call_no_callee_saved_registers.
> > * doc/extend.texi: Document no_callee_saved_registers attribute.
> >
> > gcc/testsuite/
> >
> > PR target/103503
> > PR target/113312
> > * gcc.dg/torture/no-callee-saved-run-1a.c: New file.
> > * gcc.dg/torture/no-callee-saved-run-1b.c: Likewise.
> > * gcc.target/i386/no-callee-saved-1.c: Likewise.
> > * gcc.target/i386/no-callee-saved-2.c: Likewise.
> > * gcc.target/i386/no-callee-saved-3.c: Likewise.
> > * gcc.target/i386/no-callee-saved-4.c: Likewise.
> > * gcc.target/i386/no-callee-saved-5.c: Likewise.
> > * gcc.target/i386/no-callee-saved-6.c: Likewise.
> > * gcc.target/i386/no-callee-saved-7.c: Likewise.
> > * gcc.target/i386/no-callee-saved-8.c: Likewise.
> > * gcc.target/i386/no-callee-saved-9.c: Likewise.
> > * gcc.target/i386/no-callee-saved-10.c: Likewise.
> > * gcc.target/i386/no-callee-saved-11.c: Likewise.
> > * gcc.target/i386/no-callee-saved-12.c: Likewise.
> > * gcc.target/i386/no-callee-saved-13.c: Likewise.
> > * gcc.target/i386/no-callee-saved-14.c: Likewise.
> > * gcc.target/i386/no-callee-saved-15.c: Likewise.
> > * gcc.target/i386/no-callee-saved-16.c: Likewise.
> > * 

Re: [PATCH 1/2] x86: Add no_callee_saved_registers function attribute

2024-01-21 Thread Hongtao Liu
On Sat, Jan 20, 2024 at 10:30 PM H.J. Lu  wrote:
>
> When an interrupt handler is implemented by an assembly stub which does:
>
> 1. Save all registers.
> 2. Call a C function.
> 3. Restore all registers.
> 4. Return from interrupt.
>
> it is completely unnecessary to save and restore any registers in the C
> function called by the assembly stub, even if they would normally be
> callee-saved.
>
> Add no_callee_saved_registers function attribute, which is complementary
> to no_caller_saved_registers function attribute, to mark a function which
> doesn't have any callee-saved registers.  Such a function won't save and
> restore any registers.  Classify function call-saved register handling
> type with:
>
> 1. Default call-saved registers.
> 2. No caller-saved registers with no_caller_saved_registers attribute.
> 3. No callee-saved registers with no_callee_saved_registers attribute.
>
> Disallow sibcall if callee is a no_callee_saved_registers function
> and caller isn't a no_callee_saved_registers function.  Otherwise,
> callee-saved registers won't be preserved.
>
> After a no_callee_saved_registers function is called, all registers may
> be clobbered.  If the calling function isn't a no_callee_saved_registers
> function, we need to preserve all registers which aren't used by function
> calls.
>
> gcc/
>
> PR target/103503
> PR target/113312
> * config/i386/i386-expand.cc (ix86_expand_call): Set
> call_no_callee_saved_registers to true when calling function
> with no_callee_saved_registers attribute.  Replace
> no_caller_saved_registers check with call_saved_registers check.
> * config/i386/i386-options.cc (ix86_set_func_type): Set
> call_saved_registers to TYPE_NO_CALLEE_SAVED_REGISTERS for
> noreturn function.  Disallow no_callee_saved_registers with
> interrupt or no_caller_saved_registers attributes together.
> (ix86_set_current_function): Replace no_caller_saved_registers
> check with call_saved_registers check.
> (ix86_handle_no_caller_saved_registers_attribute): Renamed to ...
> (ix86_handle_call_saved_registers_attribute): This.
> (ix86_gnu_attributes): Add
> ix86_handle_call_saved_registers_attribute.
> * config/i386/i386.cc (ix86_conditional_register_usage): Replace
> no_caller_saved_registers check with call_saved_registers check.
> (ix86_function_ok_for_sibcall): Don't allow callee with
> no_callee_saved_registers attribute when the calling function
> has callee-saved registers.
> (ix86_comp_type_attributes): Also check
> no_callee_saved_registers.
> (ix86_epilogue_uses): Replace no_caller_saved_registers check
> with call_saved_registers check.
> (ix86_hard_regno_scratch_ok): Likewise.
> (ix86_save_reg): Replace no_caller_saved_registers check with
> call_saved_registers check.  Don't save any registers for
> TYPE_NO_CALLEE_SAVED_REGISTERS.  Save all registers with
> TYPE_DEFAULT_CALL_SAVED_REGISTERS if function with
> no_callee_saved_registers attribute is called.
> (find_drap_reg): Replace no_caller_saved_registers check with
> call_saved_registers check.
> * config/i386/i386.h (call_saved_registers_type): New enum.
> (machine_function): Replace no_caller_saved_registers with
> call_saved_registers.  Add call_no_callee_saved_registers.
> * doc/extend.texi: Document no_callee_saved_registers attribute.
>
> gcc/testsuite/
>
> PR target/103503
> PR target/113312
> * gcc.dg/torture/no-callee-saved-run-1a.c: New file.
> * gcc.dg/torture/no-callee-saved-run-1b.c: Likewise.
> * gcc.target/i386/no-callee-saved-1.c: Likewise.
> * gcc.target/i386/no-callee-saved-2.c: Likewise.
> * gcc.target/i386/no-callee-saved-3.c: Likewise.
> * gcc.target/i386/no-callee-saved-4.c: Likewise.
> * gcc.target/i386/no-callee-saved-5.c: Likewise.
> * gcc.target/i386/no-callee-saved-6.c: Likewise.
> * gcc.target/i386/no-callee-saved-7.c: Likewise.
> * gcc.target/i386/no-callee-saved-8.c: Likewise.
> * gcc.target/i386/no-callee-saved-9.c: Likewise.
> * gcc.target/i386/no-callee-saved-10.c: Likewise.
> * gcc.target/i386/no-callee-saved-11.c: Likewise.
> * gcc.target/i386/no-callee-saved-12.c: Likewise.
> * gcc.target/i386/no-callee-saved-13.c: Likewise.
> * gcc.target/i386/no-callee-saved-14.c: Likewise.
> * gcc.target/i386/no-callee-saved-15.c: Likewise.
> * gcc.target/i386/no-callee-saved-16.c: Likewise.
> * gcc.target/i386/no-callee-saved-17.c: Likewise.
> * gcc.target/i386/no-callee-saved-18.c: Likewise.
> ---
>  gcc/config/i386/i386-expand.cc| 72 ---
>  gcc/config/i386/i386-options.cc   | 49 +
>  

[PATCH 1/2] x86: Add no_callee_saved_registers function attribute

2024-01-20 Thread H.J. Lu
When an interrupt handler is implemented by an assembly stub which does:

1. Save all registers.
2. Call a C function.
3. Restore all registers.
4. Return from interrupt.

it is completely unnecessary to save and restore any registers in the C
function called by the assembly stub, even if they would normally be
callee-saved.

Add no_callee_saved_registers function attribute, which is complementary
to no_caller_saved_registers function attribute, to mark a function which
doesn't have any callee-saved registers.  Such a function won't save and
restore any registers.  Classify function call-saved register handling
type with:

1. Default call-saved registers.
2. No caller-saved registers with no_caller_saved_registers attribute.
3. No callee-saved registers with no_callee_saved_registers attribute.

Disallow sibcall if callee is a no_callee_saved_registers function
and caller isn't a no_callee_saved_registers function.  Otherwise,
callee-saved registers won't be preserved.

After a no_callee_saved_registers function is called, all registers may
be clobbered.  If the calling function isn't a no_callee_saved_registers
function, we need to preserve all registers which aren't used by function
calls.

gcc/

PR target/103503
PR target/113312
* config/i386/i386-expand.cc (ix86_expand_call): Set
call_no_callee_saved_registers to true when calling function
with no_callee_saved_registers attribute.  Replace
no_caller_saved_registers check with call_saved_registers check.
* config/i386/i386-options.cc (ix86_set_func_type): Set
call_saved_registers to TYPE_NO_CALLEE_SAVED_REGISTERS for
noreturn function.  Disallow no_callee_saved_registers with
interrupt or no_caller_saved_registers attributes together.
(ix86_set_current_function): Replace no_caller_saved_registers
check with call_saved_registers check.
(ix86_handle_no_caller_saved_registers_attribute): Renamed to ...
(ix86_handle_call_saved_registers_attribute): This.
(ix86_gnu_attributes): Add
ix86_handle_call_saved_registers_attribute.
* config/i386/i386.cc (ix86_conditional_register_usage): Replace
no_caller_saved_registers check with call_saved_registers check.
(ix86_function_ok_for_sibcall): Don't allow callee with
no_callee_saved_registers attribute when the calling function
has callee-saved registers.
(ix86_comp_type_attributes): Also check
no_callee_saved_registers.
(ix86_epilogue_uses): Replace no_caller_saved_registers check
with call_saved_registers check.
(ix86_hard_regno_scratch_ok): Likewise.
(ix86_save_reg): Replace no_caller_saved_registers check with
call_saved_registers check.  Don't save any registers for
TYPE_NO_CALLEE_SAVED_REGISTERS.  Save all registers with
TYPE_DEFAULT_CALL_SAVED_REGISTERS if function with
no_callee_saved_registers attribute is called.
(find_drap_reg): Replace no_caller_saved_registers check with
call_saved_registers check.
* config/i386/i386.h (call_saved_registers_type): New enum.
(machine_function): Replace no_caller_saved_registers with
call_saved_registers.  Add call_no_callee_saved_registers.
* doc/extend.texi: Document no_callee_saved_registers attribute.

gcc/testsuite/

PR target/103503
PR target/113312
* gcc.dg/torture/no-callee-saved-run-1a.c: New file.
* gcc.dg/torture/no-callee-saved-run-1b.c: Likewise.
* gcc.target/i386/no-callee-saved-1.c: Likewise.
* gcc.target/i386/no-callee-saved-2.c: Likewise.
* gcc.target/i386/no-callee-saved-3.c: Likewise.
* gcc.target/i386/no-callee-saved-4.c: Likewise.
* gcc.target/i386/no-callee-saved-5.c: Likewise.
* gcc.target/i386/no-callee-saved-6.c: Likewise.
* gcc.target/i386/no-callee-saved-7.c: Likewise.
* gcc.target/i386/no-callee-saved-8.c: Likewise.
* gcc.target/i386/no-callee-saved-9.c: Likewise.
* gcc.target/i386/no-callee-saved-10.c: Likewise.
* gcc.target/i386/no-callee-saved-11.c: Likewise.
* gcc.target/i386/no-callee-saved-12.c: Likewise.
* gcc.target/i386/no-callee-saved-13.c: Likewise.
* gcc.target/i386/no-callee-saved-14.c: Likewise.
* gcc.target/i386/no-callee-saved-15.c: Likewise.
* gcc.target/i386/no-callee-saved-16.c: Likewise.
* gcc.target/i386/no-callee-saved-17.c: Likewise.
* gcc.target/i386/no-callee-saved-18.c: Likewise.
---
 gcc/config/i386/i386-expand.cc| 72 ---
 gcc/config/i386/i386-options.cc   | 49 +
 gcc/config/i386/i386.cc   | 70 ++
 gcc/config/i386/i386.h| 20 +-
 gcc/doc/extend.texi   |  8 +++
 .../gcc.dg/torture/no-callee-saved-run-1a.c   | 23