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