aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-05-06 17:49:35 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-05-06 17:49:35 -0400
commit0e6362d98458b52d39b83445276245acc4bd5c21 (patch)
treedfc1dfff8414adfa4b29f8047a0bcb1f77741a54
parent6b67ec08ceed9e120a93fe1fea50d77dc8969eac (diff)
downloadgcc-0e6362d98458b52d39b83445276245acc4bd5c21.zip
gcc-0e6362d98458b52d39b83445276245acc4bd5c21.tar.gz
gcc-0e6362d98458b52d39b83445276245acc4bd5c21.tar.bz2
(insert_save_restore): Change from USE and CLOBBER insns to using
CALL_INSN_FUNCTION_USAGE. From-SVN: r7243
-rw-r--r--gcc/caller-save.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index c0aafec..5b09606 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -424,32 +424,55 @@ save_call_clobbered_regs (insn_mode)
live, call-used, not fixed, and not already saved. We must
test at this point because registers that die in a CALL_INSN
are not live across the call and likewise for registers that
- are born in the CALL_INSN. */
+ are born in the CALL_INSN.
+
+ If registers are filled with parameters for this function,
+ and some of these are also being set by this function, then
+ they will not appear to die (no REG_DEAD note for them),
+ to check if in fact they do, collect the set registers in
+ hard_regs_live first. */
if (code == CALL_INSN)
{
+ HARD_REG_SET this_call_sets;
+ {
+ HARD_REG_SET old_hard_regs_live;
+
+ /* Save the hard_regs_live information. */
+ COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
+
+ /* Now calculate hard_regs_live for this CALL_INSN
+ only. */
+ CLEAR_HARD_REG_SET (hard_regs_live);
+ note_stores (PATTERN (insn), set_reg_live);
+ COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
+
+ /* Restore the hard_regs_live information. */
+ COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
+ }
+
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (call_used_regs[regno] && ! call_fixed_regs[regno]
&& TEST_HARD_REG_BIT (hard_regs_live, regno)
+ /* It must not be set by this instruction. */
+ && ! TEST_HARD_REG_BIT (this_call_sets, regno)
&& ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
regno += insert_save_restore (insn, 1, regno,
insn_mode, 0);
-#ifdef HARD_REG_SET
- hard_regs_need_restore = hard_regs_saved;
-#else
- COPY_HARD_REG_SET (hard_regs_need_restore,
- hard_regs_saved);
-#endif
+
+ /* Put the information for this CALL_INSN on top of what
+ we already had. */
+ IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
+ COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
/* Must recompute n_regs_saved. */
n_regs_saved = 0;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
n_regs_saved++;
-
}
-
- note_stores (PATTERN (insn), set_reg_live);
+ else
+ note_stores (PATTERN (insn), set_reg_live);
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_UNUSED)
@@ -633,14 +656,6 @@ insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
if (regno_save_mem[regno][1] == 0)
abort ();
- /* If INSN is a CALL_INSN, we must insert our insns before any
- USE insns in front of the CALL_INSN. */
-
- if (GET_CODE (insn) == CALL_INSN)
- while (GET_CODE (PREV_INSN (insn)) == INSN
- && GET_CODE (PATTERN (PREV_INSN (insn))) == USE)
- insn = PREV_INSN (insn);
-
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an