[PATCH][middle-end][i386][version 3]Add -fzero-call-used-regs=[skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all]
Qing Zhao
QING.ZHAO@ORACLE.COM
Wed Oct 21 16:52:51 GMT 2020
Got it.
thanks.
Qing
> On Oct 21, 2020, at 10:47 AM, Richard Sandiford <richard.sandiford@arm.com> wrote:
>
> Qing Zhao <QING.ZHAO@ORACLE.COM> writes:
>>>> + /* For each of the hard registers, check to see whether we should zero it if:
>>>> + 1. it is a call-used-registers;
>>>> + and 2. it is not a fixed-registers;
>>>> + and 3. it is not live at the return of the routine;
>>>> + and 4. it is general registor if gpr_only is true;
>>>> + and 5. it is used in the routine if used_only is true;
>>>> + and 6. it is a register that passes parameter if arg_only is true;
>>>> + */
>>>> +
>>>> + HARD_REG_SET need_zeroed_hardregs;
>>>> + CLEAR_HARD_REG_SET (need_zeroed_hardregs);
>>>> + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
>>>> + {
>>>> + if (!this_target_hard_regs->x_call_used_regs[regno])
>>>> + continue;
>>>
>>> This should use crtl->abi instead. The set of call-used registers
>>> can vary from function to function.
>>
>> You mean to use:
>>
>> If (!crtl->abi->clobbers_full_reg_p(regno))
>>
>> ?
>
> Yeah, that's right. (But with a space before “(regno)” :-))
>
>>>> +static unsigned int
>>>> +rest_of_zero_call_used_regs (void)
>>>> +{
>>>> + basic_block bb;
>>>> + rtx_insn *insn;
>>>> +
>>>> + /* This pass needs data flow information. */
>>>> + df_analyze ();
>>>> +
>>>> + /* Search all the "return"s in the routine, and insert instruction sequence to
>>>> + zero the call used registers. */
>>>> + FOR_EACH_BB_REVERSE_FN (bb, cfun)
>>>> + if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
>>>> + || (single_succ_p (bb)
>>>> + && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)))
>>>> + FOR_BB_INSNS_REVERSE (bb, insn)
>>>> + if (JUMP_P (insn) && ANY_RETURN_P (JUMP_LABEL (insn)))
>>>> + {
>>>> + /* Now we can insert the instruction sequence to zero the call used
>>>> + registers before this insn. */
>>>> + gen_call_used_regs_seq (insn);
>>>> + break;
>>>> + }
>>>
>>> The exit block never has instructions, so it's only necessary to process
>>> predecessors. A simpler way to do that is to iterate over the edges in:
>>>
>>> EXIT_BLOCK_PTR_FOR_FN (cfun)->preds
>>>
>>> You shouldn't need to use FOR_BB_INSNS_REVERSE: it should be enough
>>> to check only BB_END (bb), since returns always end blocks.
>>
>> Something like the following?
>>
>> FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
>> {
>> insn = BB_END (e->src);
>> If (JUMP_P (insn) && ANY_RETURN_P (JUMP_LABEL (insn)))
>> {
>> /* Now we can insert the instruction sequence to zero the call used
>> registers before this insn. */
>> gen_call_used_regs_seq (insn);
>> break;
>> }
>> }
>
> With this you don't want/need the break, since it would break out
> of the edge traversal (instead of the FOR_BB_INSNS_REVERSE, as above).
> Also, I think the code becomes simple enough that the comment isn't
> really needed.
>
> Thanks,
> Richard
More information about the Gcc-patches
mailing list