]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl.h (set_for_reg_notes): Declare.
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 28 May 2014 08:41:27 +0000 (08:41 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Wed, 28 May 2014 08:41:27 +0000 (08:41 +0000)
2014-05-26  Richard Sandiford  <rdsandiford@googlemail.com>
            Olivier Hainque  <hainque@adacore.com>

        * rtl.h (set_for_reg_notes): Declare.
        * emit-rtl.c (set_for_reg_notes): New function.
        (set_unique_reg_note): Use it.
        * optabs.c (add_equal_note): Likewise

Co-Authored-By: Olivier Hainque <hainque@adacore.com>
From-SVN: r210998

ChangeLog
gcc/emit-rtl.c
gcc/optabs.c
gcc/rtl.h

index f0aa0006daae31fee8e4d128de44627e602f3cbe..ba82dd58b84592071f582131fa99c7d352023413 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-05-26  Richard Sandiford  <rdsandiford@googlemail.com>
+           Olivier Hainque  <hainque@adacore.com>
+
+       * rtl.h (set_for_reg_notes): Declare.
+       * emit-rtl.c (set_for_reg_notes): New function.
+       (set_unique_reg_note): Use it.
+       * optabs.c (add_equal_note): Likewise
+
 2014-05-22  Maxim Kuvyrkov  <maxim.kuvyrkov@linaro.org>
 
        * MAINTAINERS: Update my affiliation/email.
index 551524436f3fe5bcc69f293a6427576a4a071b2f..3bf2ff7213690a553bc82e6b8862090db8220f96 100644 (file)
@@ -5086,6 +5086,45 @@ gen_use (rtx x)
   return seq;
 }
 
+/* Notes like REG_EQUAL and REG_EQUIV refer to a set in an instruction.
+   Return the set in INSN that such notes describe, or NULL if the notes
+   have no meaning for INSN.  */
+
+rtx
+set_for_reg_notes (rtx insn)
+{
+  rtx pat, reg;
+
+  if (!INSN_P (insn))
+    return NULL_RTX;
+
+  pat = PATTERN (insn);
+  if (GET_CODE (pat) == PARALLEL)
+    {
+      /* We do not use single_set because that ignores SETs of unused
+        registers.  REG_EQUAL and REG_EQUIV notes really do require the
+        PARALLEL to have a single SET.  */
+      if (multiple_sets (insn))
+       return NULL_RTX;
+      pat = XVECEXP (pat, 0, 0);
+    }
+
+  if (GET_CODE (pat) != SET)
+    return NULL_RTX;
+
+  reg = SET_DEST (pat);
+
+  /* Notes apply to the contents of a STRICT_LOW_PART.  */
+  if (GET_CODE (reg) == STRICT_LOW_PART)
+    reg = XEXP (reg, 0);
+
+  /* Check that we have a register.  */
+  if (!(REG_P (reg) || GET_CODE (reg) == SUBREG))
+    return NULL_RTX;
+
+  return pat;
+}
+
 /* Place a note of KIND on insn INSN with DATUM as the datum. If a
    note of this type already exists, remove it first.  */
 
@@ -5098,39 +5137,26 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
     {
     case REG_EQUAL:
     case REG_EQUIV:
-      /* Don't add REG_EQUAL/REG_EQUIV notes if the insn
-        has multiple sets (some callers assume single_set
-        means the insn only has one set, when in fact it
-        means the insn only has one * useful * set).  */
-      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
-       {
-         gcc_assert (!note);
-         return NULL_RTX;
-       }
+      if (!set_for_reg_notes (insn))
+       return NULL_RTX;
 
       /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
         It serves no useful purpose and breaks eliminate_regs.  */
       if (GET_CODE (datum) == ASM_OPERANDS)
        return NULL_RTX;
-
-      if (note)
-       {
-         XEXP (note, 0) = datum;
-         df_notes_rescan (insn);
-         return note;
-       }
       break;
 
     default:
-      if (note)
-       {
-         XEXP (note, 0) = datum;
-         return note;
-       }
       break;
     }
 
-  add_reg_note (insn, kind, datum);
+  if (note)
+    XEXP (note, 0) = datum;
+  else
+    {
+      add_reg_note (insn, kind, datum);
+      note = REG_NOTES (insn);
+    }
 
   switch (kind)
     {
@@ -5142,14 +5168,14 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
       break;
     }
 
-  return REG_NOTES (insn);
+  return note;
 }
 
 /* Like set_unique_reg_note, but don't do anything unless INSN sets DST.  */
 rtx
 set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
 {
-  rtx set = single_set (insn);
+  rtx set = set_for_reg_notes (insn);
 
   if (set && SET_DEST (set) == dst)
     return set_unique_reg_note (insn, kind, datum);
index 9af52270e9b4f407c38aa799da622db4e9764efc..ca1c1945c37e8dfb3b719c1490874f03c1cbc9ea 100644 (file)
@@ -228,7 +228,7 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
       return 0;
     }
 
-  set = single_set (last_insn);
+  set = set_for_reg_notes (last_insn);
   if (set == NULL_RTX)
     return 1;
 
index 10ae1e9cee5876bbbac4c38b57bae35e7da67edf..02ce4248d9c344a22a2a71a3083726aa6829defa 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2197,6 +2197,7 @@ extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
                                               bool);
 
 /* In emit-rtl.c  */
+extern rtx set_for_reg_notes (rtx);
 extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
 extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
 extern void set_insn_deleted (rtx);