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