Got it.

thanks.

Qing

> On Oct 21, 2020, at 10:47 AM, Richard Sandiford <richard.sandif...@arm.com> 
> wrote:
> 
> Qing Zhao <qing.z...@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

Reply via email to