combine.c (can_combine_p): Don't ignore SETs marked with REG_EH_REGION notes.
authorAlan Modra <amodra@bigpond.net.au>
Sat, 21 Feb 2004 13:03:40 +0000 (13:03 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Sat, 21 Feb 2004 13:03:40 +0000 (23:33 +1030)
* combine.c (can_combine_p): Don't ignore SETs marked with
REG_EH_REGION notes.
(try_combine): When attemting to fix unrecognized insns, don't
split a PARALLEL that contains the original i2.

From-SVN: r78220

gcc/ChangeLog
gcc/combine.c

index d3fc0db66a9d295d970bdb4872ac46e0e9020d23..8c3092affc0454a8cf4631a4906caa26ec73655d 100644 (file)
@@ -1,3 +1,10 @@
+2004-02-21  Alan Modra  <amodra@bigpond.net.au>
+
+       * combine.c (can_combine_p): Don't ignore SETs marked with
+       REG_EH_REGION notes.
+       (try_combine): When attemting to fix unrecognized insns, don't
+       split a PARALLEL that contains the original i2.
+
 2004-02-21  Ziemowit Laski  <zlaski@apple.com>
 
        * config/darwin.h (TARGET_OPTION_TRANSLATE_TABLE): Refer to
index 8911cb2db327c21c16b535509cf0c09535230dfc..55e7ea33047ea7c78569743750988f98d365423a 100644 (file)
@@ -960,6 +960,7 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
       for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
        {
          rtx elt = XVECEXP (PATTERN (insn), 0, i);
+         rtx note;
 
          switch (GET_CODE (elt))
            {
@@ -1010,6 +1011,8 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
              /* Ignore SETs whose result isn't used but not those that
                 have side-effects.  */
              if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
+                 && (!(note = find_reg_note (insn, REG_EH_REGION, NULL_RTX))
+                     || INTVAL (XEXP (note, 0)) <= 0)
                  && ! side_effects_p (elt))
                break;
 
@@ -2019,11 +2022,21 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
      we just need the first SET.   This can occur when simplifying a divmod
      insn.  We *must* test for this case here because the code below that
      splits two independent SETs doesn't handle this case correctly when it
-     updates the register status.  Also check the case where the first
-     SET's destination is unused.  That would not cause incorrect code, but
-     does cause an unneeded insn to remain.  */
+     updates the register status.
 
-  if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
+     It's pointless doing this if we originally had two sets, one from
+     i3, and one from i2.  Combining then splitting the parallel results
+     in the original i2 again plus an invalid insn (which we delete).
+     The net effect is only to move instructions around, which makes
+     debug info less accurate.
+
+     Also check the case where the first SET's destination is unused.
+     That would not cause incorrect code, but does cause an unneeded
+     insn to remain.  */
+
+  if (insn_code_number < 0
+      && !(added_sets_2 && i1 == 0)
+      && GET_CODE (newpat) == PARALLEL
       && XVECLEN (newpat, 0) == 2
       && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
       && GET_CODE (XVECEXP (newpat, 0, 1)) == SET