diff options
author | Qing Zhao <qing.zhao@oracle.com> | 2022-04-01 16:09:43 +0000 |
---|---|---|
committer | Qing Zhao <qing.zhao@oracle.com> | 2022-04-01 16:09:43 +0000 |
commit | 31933f4f788b6cd64cbb7ee42076997f6d0fe212 (patch) | |
tree | 5daa89e8f0c580f945687dc4a47f4eb9d1e7032e /gcc/function.cc | |
parent | 413187b0b3c873333253838e4afbf8463b288b59 (diff) | |
download | gcc-31933f4f788b6cd64cbb7ee42076997f6d0fe212.zip gcc-31933f4f788b6cd64cbb7ee42076997f6d0fe212.tar.gz gcc-31933f4f788b6cd64cbb7ee42076997f6d0fe212.tar.bz2 |
Add an assertion: the zeroed_hardregs set is a subset of all call used regs.
We should make sure that the hard register set that is actually cleared by
the target hook zero_call_used_regs should be a subset of all call used
registers.
At the same time, update documentation for the target hook
TARGET_ZERO_CALL_USED_REGS.
This new assertion identified a bug in the i386 implemenation, which
incorrectly set the zeroed_hardregs for stack registers. Fixed this bug
in i386 implementation.
gcc/ChangeLog:
2022-04-01 Qing Zhao <qing.zhao@oracle.com>
* config/i386/i386.cc (zero_all_st_registers): Return the value of
num_of_st.
(ix86_zero_call_used_regs): Update zeroed_hardregs set according to
the return value of zero_all_st_registers.
* doc/tm.texi: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
* function.cc (gen_call_used_regs_seq): Add an assertion.
* target.def: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
Diffstat (limited to 'gcc/function.cc')
-rw-r--r-- | gcc/function.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/gcc/function.cc b/gcc/function.cc index d5ed51a..ad0096a 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -5892,7 +5892,9 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type) df_simulate_one_insn_backwards (bb, ret, live_out); HARD_REG_SET selected_hardregs; + HARD_REG_SET all_call_used_regs; CLEAR_HARD_REG_SET (selected_hardregs); + CLEAR_HARD_REG_SET (all_call_used_regs); for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { if (!crtl->abi->clobbers_full_reg_p (regno)) @@ -5901,6 +5903,13 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type) continue; if (REGNO_REG_SET_P (live_out, regno)) continue; +#ifdef LEAF_REG_REMAP + if (crtl->uses_only_leaf_regs && LEAF_REG_REMAP (regno) < 0) + continue; +#endif + /* This is a call used register that is dead at return. */ + SET_HARD_REG_BIT (all_call_used_regs, regno); + if (only_gpr && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], regno)) continue; @@ -5908,10 +5917,6 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type) continue; if (only_arg && !FUNCTION_ARG_REGNO_P (regno)) continue; -#ifdef LEAF_REG_REMAP - if (crtl->uses_only_leaf_regs && LEAF_REG_REMAP (regno) < 0) - continue; -#endif /* Now this is a register that we might want to zero. */ SET_HARD_REG_BIT (selected_hardregs, regno); @@ -5925,6 +5930,15 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type) HARD_REG_SET zeroed_hardregs; start_sequence (); zeroed_hardregs = targetm.calls.zero_call_used_regs (selected_hardregs); + + /* For most targets, the returned set of registers is a subset of + selected_hardregs, however, for some of the targets (for example MIPS), + clearing some registers that are in selected_hardregs requires clearing + other call used registers that are not in the selected_hardregs, under + such situation, the returned set of registers must be a subset of + all call used registers. */ + gcc_assert (hard_reg_set_subset_p (zeroed_hardregs, all_call_used_regs)); + rtx_insn *seq = get_insns (); end_sequence (); if (seq) |