Re: [PATCH 1/2] x86: Add no_callee_saved_registers function attribute
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
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
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