re PR bootstrap/51725 (segfault in stage 3 when compiling gcc/opts.c for sparc64...
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 7 Jan 2012 21:37:15 +0000 (21:37 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 7 Jan 2012 21:37:15 +0000 (21:37 +0000)
PR bootstrap/51725
* cselib.c (new_elt_loc_list): Promote addr_list to canonical node.
Add canonical node to containing_mem chain after the non-canonical
one, even if there weren't any locs to propagate.
(remove_useless_values): Keep only canonical values.
(add_mem_for_addr, cselib_lookup_mem): Canonicalize addr.
(cselib_invalidate_mem): Likewise.  Ensure v is canonical, and
canonicalize mem_chain elements that are not discarded.

From-SVN: r182982

gcc/ChangeLog
gcc/cselib.c

index 6186612a41581a3547622551497eb1c06503051e..c3a9eaef68d6897bb86008f0f2eacbfa77f6269f 100644 (file)
@@ -1,3 +1,14 @@
+2012-01-07  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR bootstrap/51725
+       * cselib.c (new_elt_loc_list): Promote addr_list to canonical node.
+       Add canonical node to containing_mem chain after the non-canonical
+       one, even if there weren't any locs to propagate.
+       (remove_useless_values): Keep only canonical values.
+       (add_mem_for_addr, cselib_lookup_mem): Canonicalize addr.
+       (cselib_invalidate_mem): Likewise.  Ensure v is canonical, and
+       canonicalize mem_chain elements that are not discarded.
+
 2012-01-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/47333
index 7db24ae729aac097895b307b0310a89da36eb8bd..ab9c458fe8213fd375034a62850b8b43934e54ea 100644 (file)
@@ -277,12 +277,27 @@ new_elt_loc_list (cselib_val *val, rtx loc)
            }
          el->next = val->locs;
          next = val->locs = CSELIB_VAL_PTR (loc)->locs;
-         if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL
-             && val->next_containing_mem == NULL)
-           {
-             val->next_containing_mem = first_containing_mem;
-             first_containing_mem = val;
-           }
+       }
+
+      if (CSELIB_VAL_PTR (loc)->addr_list)
+       {
+         /* Bring in addr_list into canonical node.  */
+         struct elt_list *last = CSELIB_VAL_PTR (loc)->addr_list;
+         while (last->next)
+           last = last->next;
+         last->next = val->addr_list;
+         val->addr_list = CSELIB_VAL_PTR (loc)->addr_list;
+         CSELIB_VAL_PTR (loc)->addr_list = NULL;
+       }
+
+      if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL
+         && val->next_containing_mem == NULL)
+       {
+         /* Add VAL to the containing_mem list after LOC.  LOC will
+            be removed when we notice it doesn't contain any
+            MEMs.  */
+         val->next_containing_mem = CSELIB_VAL_PTR (loc)->next_containing_mem;
+         CSELIB_VAL_PTR (loc)->next_containing_mem = val;
        }
 
       /* Chain LOC back to VAL.  */
@@ -641,7 +656,7 @@ remove_useless_values (void)
 
   p = &first_containing_mem;
   for (v = *p; v != &dummy_val; v = v->next_containing_mem)
-    if (v->locs)
+    if (v->locs && v == canonical_cselib_val (v))
       {
        *p = v;
        p = &(*p)->next_containing_mem;
@@ -1274,6 +1289,7 @@ add_mem_for_addr (cselib_val *addr_elt, cselib_val *mem_elt, rtx x)
 {
   struct elt_loc_list *l;
 
+  addr_elt = canonical_cselib_val (addr_elt);
   mem_elt = canonical_cselib_val (mem_elt);
 
   /* Avoid duplicates.  */
@@ -1322,6 +1338,7 @@ cselib_lookup_mem (rtx x, int create)
   if (! addr)
     return 0;
 
+  addr = canonical_cselib_val (addr);
   /* Find a value that describes a value of our mode at that address.  */
   for (l = addr->addr_list; l; l = l->next)
     if (GET_MODE (l->elt->val_rtx) == mode)
@@ -2218,15 +2235,22 @@ cselib_invalidate_mem (rtx mem_rtx)
          /* We must have a mapping from this MEM's address to the
             value (E).  Remove that, too.  */
          addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0, GET_MODE (x));
+         addr = canonical_cselib_val (addr);
+         gcc_checking_assert (v == canonical_cselib_val (v));
          mem_chain = &addr->addr_list;
          for (;;)
            {
-             if (canonical_cselib_val ((*mem_chain)->elt) == v)
+             cselib_val *canon = canonical_cselib_val ((*mem_chain)->elt);
+
+             if (canon == v)
                {
                  unchain_one_elt_list (mem_chain);
                  break;
                }
 
+             /* Record canonicalized elt.  */
+             (*mem_chain)->elt = canon;
+
              mem_chain = &(*mem_chain)->next;
            }