"H.J. Lu" <[email protected]> writes:
> On Wed, May 13, 2026 at 7:11 PM Richard Sandiford
> <[email protected]> wrote:
>>
>> "H.J. Lu" <[email protected]> writes:
>> > Implement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers
>> > when calling functions with no_caller_saved_registers attribute.
>> >
>> > 1. For functions with no_callee_saved_registers attribute, frame register
>> > is preserved to mitigate PR target/114116.  MMX and x87 registers aren't
>> > clobbered if MMX and x87 aren't enabled.
>> > 2. For functions with no_caller_saved_registers attribute, MMX and x87
>> > registers are clobbered since saving and restoring registers doesn't
>> > include MMX nor x87 registers.
>> > 3. Don't mark disabled registers as call used to avoid reg_to_stack
>> > crashes when x87 registers are still accessed even with -mno-mmx
>> > -mno-80387.
>> > 4. Add ABI_ORIGINAL which is the function ABI without attributes on
>> > the current function.
>> > 5. Add ABI_ALTERNATE which is the alternate function ABI from ABI_DEFAULT.
>> > If ix86_abi is SYSV_ABI, ABI_ALTERNATE is the function ABI for MS_ABI.
>> > Otherwise, ABI_ALTERNATE is the function ABI for SYSV_ABI.
>> >
>> > Tested on Linux/x86-64 and with CPython 3.14.4.
>>
>> Like I mentioned in the PR trail for 125266, I don't think
>> the ix86_original_abi stuff, and the use of cfun in
>> ix86_conditional_register_usage, is correct.  Maybe the simplest
>> thing would be for me to come up with a counterproposal, based on
>> this patch.  It might be a few days before I can give it a go though.
>
> Hi Richard,
>
> I found a typo in the v2 patch.   Here is the v3 patch.  I also changed
> ix86_original_abi and ix86_alternate_abi implementation:
>
> /* Return the descriptor of the standard function ABI type.  If
>    ABI_TYPE == ABI_ALTERNATE, return the function alternate ABI type.  */
>
> static const predefined_function_abi &
> ix86_standard_abi (int abi_type)
> {
>   static const char ix86_call_used_regs[] = CALL_USED_REGISTERS;
>   auto &standard_abi = function_abis[abi_type];
>   if (!standard_abi.initialized_p ())
>     {
>       HARD_REG_SET full_reg_clobbers = {};
>
>       /* Add all registers that are clobbered by the call.  NB: If the
>          current ABI is SYSV_ABI, the alternate ABI is MS_ABI.   */
>       bool is_64bit_ms_abi = (TARGET_64BIT
>                               && ix86_abi == (abi_type == ABI_ALTERNATE
>                                               ? SYSV_ABI : MS_ABI));
>       char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
>       for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>         if (global_regs[i]
>             || (!fixed_regs[i]
>                 && (ix86_call_used_regs[i] == 1
>                     || (ix86_call_used_regs[i] & c_mask))))
>           SET_HARD_REG_BIT (full_reg_clobbers, i);
>
>       SET_HARD_REG_BIT (full_reg_clobbers, FLAGS_REG);
>       SET_HARD_REG_BIT (full_reg_clobbers, FPSR_REG);
>
>       standard_abi.initialize (abi_type, full_reg_clobbers);
>     }
>   return standard_abi;
> }
>
> /* Return the descriptor of the function ABI type without attributes
>    on the current function.  */
>
> static const predefined_function_abi &
> ix86_original_abi (void)
> {
>   return ix86_standard_abi (ABI_ORIGINAL);
> }
>
> /* Return the descriptor of the function alternate ABI type.  */
>
> static const predefined_function_abi &
> ix86_alternate_abi (void)
> {
>   return ix86_standard_abi (ABI_ALTERNATE);
> }

Thanks.  I made a start on what I wanted to try today, but realised
that I needed a target-independent patch first.  I'll send that in a sec.

Richard

Reply via email to