aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-09-19 17:01:31 -0700
committerRichard Henderson <rth@gcc.gnu.org>1998-09-19 17:01:31 -0700
commitf5c9764010389128f598f5c2f484e268210535b9 (patch)
treec94d12e5ec3fecf3937f1e0686b63e8510af6e51
parenta58bd5080ad5fc39a02eb1e786f71615ed3146fe (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/combine.c33
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