[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