]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR debug/52001 (Huge compile-time regression with var-tracking)
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 25 Feb 2012 12:09:41 +0000 (12:09 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 25 Feb 2012 12:09:41 +0000 (12:09 +0000)
PR debug/52001
* alias.c (refs_newer_value_cb, refs_newer_value_p): New.
(get_addr): Walk canonical value's locs.  Avoid returning VALUEs
and locs that reference values newer than the non-canonical value
at hand.  Return the canonical value as a worst case.
(memrefs_conflict_p): Walk canonical value's locs.

From-SVN: r184572

gcc/ChangeLog
gcc/alias.c

index 4a2c9fb6c2fe9be1f55877cb88de3917c5442c15..5dfe71f3c2f4991b8f2f76501ef8e625d336e07f 100644 (file)
@@ -1,5 +1,12 @@
 2012-02-25  Alexandre Oliva  <aoliva@redhat.com>
 
+       PR debug/52001
+       * alias.c (refs_newer_value_cb, refs_newer_value_p): New.
+       (get_addr): Walk canonical value's locs.  Avoid returning VALUEs
+       and locs that reference values newer than the non-canonical value
+       at hand.  Return the canonical value as a worst case.
+       (memrefs_conflict_p): Walk canonical value's locs.
+
        PR debug/52001
        * cselib.c (preserve_only_constants): Rename to...
        (preserve_constants_and_equivs): ... this.  Split out...
index b9b9676b1736ec4e88a7abb14ae5c6ce1e70fc1b..4bda40d8836dae52a1e2ecfdf61290c67360aab4 100644 (file)
@@ -1773,6 +1773,29 @@ base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
   return 1;
 }
 
+/* Callback for for_each_rtx, that returns 1 upon encountering a VALUE
+   whose UID is greater than the int uid that D points to.  */
+
+static int
+refs_newer_value_cb (rtx *x, void *d)
+{
+  if (GET_CODE (*x) == VALUE && CSELIB_VAL_PTR (*x)->uid > *(int *)d)
+    return 1;
+
+  return 0;
+}
+
+/* Return TRUE if EXPR refers to a VALUE whose uid is greater than
+   that of V.  */
+
+static bool
+refs_newer_value_p (rtx expr, rtx v)
+{
+  int minuid = CSELIB_VAL_PTR (v)->uid;
+
+  return for_each_rtx (&expr, refs_newer_value_cb, &minuid);
+}
+
 /* Convert the address X into something we can use.  This is done by returning
    it unchanged unless it is a value; in the latter case we call cselib to get
    a more useful rtx.  */
@@ -1788,14 +1811,20 @@ get_addr (rtx x)
   v = CSELIB_VAL_PTR (x);
   if (v)
     {
+      v = canonical_cselib_val (v);
       for (l = v->locs; l; l = l->next)
        if (CONSTANT_P (l->loc))
          return l->loc;
       for (l = v->locs; l; l = l->next)
-       if (!REG_P (l->loc) && !MEM_P (l->loc))
+       if (!REG_P (l->loc) && !MEM_P (l->loc) && GET_CODE (l->loc) != VALUE
+           && !refs_newer_value_p (l->loc, x))
+         return l->loc;
+      for (l = v->locs; l; l = l->next)
+       if (REG_P (l->loc) || (GET_CODE (l->loc) != VALUE
+                              && !refs_newer_value_p (l->loc, x)))
          return l->loc;
-      if (v->locs)
-       return v->locs->loc;
+      /* Return the canonical value.  */
+      return v->val_rtx;
     }
   return x;
 }
@@ -1873,7 +1902,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
        {
          struct elt_loc_list *l = NULL;
          if (CSELIB_VAL_PTR (x))
-           for (l = CSELIB_VAL_PTR (x)->locs; l; l = l->next)
+           for (l = canonical_cselib_val (CSELIB_VAL_PTR (x))->locs;
+                l; l = l->next)
              if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, y))
                break;
          if (l)
@@ -1891,7 +1921,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
        {
          struct elt_loc_list *l = NULL;
          if (CSELIB_VAL_PTR (y))
-           for (l = CSELIB_VAL_PTR (y)->locs; l; l = l->next)
+           for (l = canonical_cselib_val (CSELIB_VAL_PTR (y))->locs;
+                l; l = l->next)
              if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, x))
                break;
          if (l)