diff options
author | Richard Henderson <rth@cygnus.com> | 1998-09-19 17:01:31 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-09-19 17:01:31 -0700 |
commit | f5c9764010389128f598f5c2f484e268210535b9 (patch) | |
tree | c94d12e5ec3fecf3937f1e0686b63e8510af6e51 | |
parent | a58bd5080ad5fc39a02eb1e786f71615ed3146fe (diff) | |
download | gcc-f5c9764010389128f598f5c2f484e268210535b9.zip gcc-f5c9764010389128f598f5c2f484e268210535b9.tar.gz gcc-f5c9764010389128f598f5c2f484e268210535b9.tar.bz2 |
combine.c (distribute_notes): If an insn is a cc0 user, only delete it if we can also delete the cc0 setter.
* combine.c (distribute_notes): If an insn is a cc0 user, only
delete it if we can also delete the cc0 setter.
From-SVN: r22489
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/combine.c | 33 |
2 files changed, 36 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ae27929..9bed901 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Sun Sep 20 00:00:51 1998 Richard Henderson <rth@cygnus.com> + + * combine.c (distribute_notes): If an insn is a cc0 user, only + delete it if we can also delete the cc0 setter. + Sun Sep 20 00:22:23 1998 Michael Tiemann <michael@impact.tiemann.org> * fold-const.c (fold): Fix typo in COND_EXPR handling code. diff --git a/gcc/combine.c b/gcc/combine.c index 024cb51..e2a0095 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -11542,6 +11542,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) { rtx set = single_set (tem); rtx inner_dest = 0; + rtx cc0_setter = NULL_RTX; if (set != 0) for (inner_dest = SET_DEST (set); @@ -11552,10 +11553,21 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) ; /* Verify that it was the set, and not a clobber that - modified the register. */ + modified the register. + + CC0 targets must be careful to maintain setter/user + pairs. If we cannot delete the setter due to side + effects, mark the user with an UNUSED note instead + of deleting it. */ if (set != 0 && ! side_effects_p (SET_SRC (set)) - && rtx_equal_p (XEXP (note, 0), inner_dest)) + && rtx_equal_p (XEXP (note, 0), inner_dest) +#ifdef HAVE_cc0 + && (! reg_mentioned_p (cc0_rtx, SET_SRC (set)) + || ((cc0_setter = prev_cc0_setter (tem)) != NULL + && sets_cc0_p (PATTERN (cc0_setter)) > 0)) +#endif + ) { /* Move the notes and links of TEM elsewhere. This might delete other dead insns recursively. @@ -11571,6 +11583,23 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) PUT_CODE (tem, NOTE); NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (tem) = 0; + +#ifdef HAVE_cc0 + /* Delete the setter too. */ + if (cc0_setter) + { + PATTERN (cc0_setter) = pc_rtx; + + distribute_notes (REG_NOTES (cc0_setter), + cc0_setter, cc0_setter, + NULL_RTX, NULL_RTX, NULL_RTX); + distribute_links (LOG_LINKS (cc0_setter)); + + PUT_CODE (cc0_setter, NOTE); + NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (cc0_setter) = 0; + } +#endif } /* If the register is both set and used here, put the REG_DEAD note here, but place a REG_UNUSED note |