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