2019-01-25 Vladimir Makarov <vmakarov@redhat.com>
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 25 Jan 2019 22:13:43 +0000 (22:13 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 25 Jan 2019 22:13:43 +0000 (22:13 +0000)
PR rtl-optimization/888846
* ira.c (process_set_for_memref_referenced_p): New.
(memref_referenced_p): Add new param.  Use
process_set_for_memref_referenced_p.  Add new switch cases.
(memref_used_between_p): Pass new arg to memref_referenced_p.

From-SVN: r268280

gcc/ChangeLog
gcc/ira.c

index 4b8b1bd..88293be 100644 (file)
@@ -1,3 +1,11 @@
+2019-01-25  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/888846
+       * ira.c (process_set_for_memref_referenced_p): New.
+       (memref_referenced_p): Add new param.  Use
+       process_set_for_memref_referenced_p.  Add new switch cases.
+       (memref_used_between_p): Pass new arg to memref_referenced_p.
+
 2019-01-25  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/88469
index ccdc2ab..fd481d6 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3140,10 +3140,30 @@ equiv_init_movable_p (rtx x, int regno)
   return 1;
 }
 
-/* TRUE if X references a memory location that would be affected by a store
-   to MEMREF.  */
-static int
-memref_referenced_p (rtx memref, rtx x)
+static bool memref_referenced_p (rtx memref, rtx x, bool read_p);
+
+/* Auxiliary function for memref_referenced_p.  Process setting X for
+   MEMREF store.  */
+static bool
+process_set_for_memref_referenced_p (rtx memref, rtx x)
+{
+  /* If we are setting a MEM, it doesn't count (its address does), but any
+     other SET_DEST that has a MEM in it is referencing the MEM.  */
+  if (MEM_P (x))
+    {
+      if (memref_referenced_p (memref, XEXP (x, 0), true))
+       return true;
+    }
+  else if (memref_referenced_p (memref, x, false))
+    return true;
+  
+  return false;
+}
+
+/* TRUE if X references a memory location (as a read if READ_P) that
+   would be affected by a store to MEMREF.  */
+static bool
+memref_referenced_p (rtx memref, rtx x, bool read_p)
 {
   int i, j;
   const char *fmt;
@@ -3159,30 +3179,51 @@ memref_referenced_p (rtx memref, rtx x)
     case CC0:
     case HIGH:
     case LO_SUM:
-      return 0;
+      return false;
 
     case REG:
       return (reg_equiv[REGNO (x)].replacement
              && memref_referenced_p (memref,
-                                     reg_equiv[REGNO (x)].replacement));
+                                     reg_equiv[REGNO (x)].replacement, read_p));
 
     case MEM:
-      if (true_dependence (memref, VOIDmode, x))
-       return 1;
+      /* Memory X might have another effective type than MEMREF.  */
+      if (read_p || true_dependence (memref, VOIDmode, x))
+       return true;
       break;
 
     case SET:
-      /* If we are setting a MEM, it doesn't count (its address does), but any
-        other SET_DEST that has a MEM in it is referencing the MEM.  */
-      if (MEM_P (SET_DEST (x)))
-       {
-         if (memref_referenced_p (memref, XEXP (SET_DEST (x), 0)))
-           return 1;
-       }
-      else if (memref_referenced_p (memref, SET_DEST (x)))
-       return 1;
+      if (process_set_for_memref_referenced_p (memref, SET_DEST (x)))
+       return true;
 
-      return memref_referenced_p (memref, SET_SRC (x));
+      return memref_referenced_p (memref, SET_SRC (x), true);
+
+    case CLOBBER:
+    case CLOBBER_HIGH:
+      if (process_set_for_memref_referenced_p (memref, XEXP (x, 0)))
+       return true;
+
+      return false;
+
+    case PRE_DEC:
+    case POST_DEC:
+    case PRE_INC:
+    case POST_INC:
+      if (process_set_for_memref_referenced_p (memref, XEXP (x, 0)))
+       return true;
+
+      return memref_referenced_p (memref, XEXP (x, 0), true);
+      
+    case POST_MODIFY:
+    case PRE_MODIFY:
+      /* op0 = op0 + op1 */
+      if (process_set_for_memref_referenced_p (memref, XEXP (x, 0)))
+       return true;
+
+      if (memref_referenced_p (memref, XEXP (x, 0), true))
+       return true;
+
+      return memref_referenced_p (memref, XEXP (x, 1), true);
 
     default:
       break;
@@ -3193,17 +3234,17 @@ memref_referenced_p (rtx memref, rtx x)
     switch (fmt[i])
       {
       case 'e':
-       if (memref_referenced_p (memref, XEXP (x, i)))
-         return 1;
+       if (memref_referenced_p (memref, XEXP (x, i), read_p))
+         return true;
        break;
       case 'E':
        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-         if (memref_referenced_p (memref, XVECEXP (x, i, j)))
-           return 1;
+         if (memref_referenced_p (memref, XVECEXP (x, i, j), read_p))
+           return true;
        break;
       }
 
-  return 0;
+  return false;
 }
 
 /* TRUE if some insn in the range (START, END] references a memory location
@@ -3224,7 +3265,7 @@ memref_used_between_p (rtx memref, rtx_insn *start, rtx_insn *end)
       if (!NONDEBUG_INSN_P (insn))
        continue;
 
-      if (memref_referenced_p (memref, PATTERN (insn)))
+      if (memref_referenced_p (memref, PATTERN (insn), false))
        return 1;
 
       /* Nonconst functions may access memory.  */