OSDN Git Service

* cselib.c (cselib_invalidate_mem_1): Move too ...
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Mar 2003 21:52:42 +0000 (21:52 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Mar 2003 21:52:42 +0000 (21:52 +0000)
(cselib_invalidate_mem): ... here; use new list
(dummy_val, first_containing_mem): New static variables.
(clear_table): Initialize first_containing_mem.
(discard_useless_values):  Compact the containing_mem list.
(add_mem_for_addr): Add to the list.
* cselib.h (cselib_val): Add next_containing_mem.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64191 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cselib.c
gcc/cselib.h

index c05eeb6..a3ec4c6 100644 (file)
@@ -1,3 +1,13 @@
+Tue Mar 11 22:48:03 CET 2003  Jan Hubicka  <jh@suse.cz>
+
+       * cselib.c (cselib_invalidate_mem_1): Move too ...
+       (cselib_invalidate_mem): ... here; use new list
+       (dummy_val, first_containing_mem): New static variables.
+       (clear_table): Initialize first_containing_mem.
+       (discard_useless_values):  Compact the containing_mem list.
+       (add_mem_for_addr): Add to the list.
+       * cselib.h (cselib_val): Add next_containing_mem.
+
 2003-03-11  Aldy Hernandez  <aldyh@redhat.com>
 
         * config/rs6000/rs6000.c (rs6000_override_options): Disable string
index 63fab22..564afba 100644 (file)
@@ -63,7 +63,6 @@ static cselib_val *cselib_lookup_mem  PARAMS ((rtx, int));
 static void cselib_invalidate_regno    PARAMS ((unsigned int,
                                                 enum machine_mode));
 static int cselib_mem_conflict_p       PARAMS ((rtx, rtx));
-static int cselib_invalidate_mem_1     PARAMS ((void **, void *));
 static void cselib_invalidate_mem      PARAMS ((rtx));
 static void cselib_invalidate_rtx      PARAMS ((rtx, rtx, void *));
 static void cselib_record_set          PARAMS ((rtx, cselib_val *,
@@ -128,6 +127,15 @@ static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists;
 /* Set by discard_useless_locs if it deleted the last location of any
    value.  */
 static int values_became_useless;
+
+/* Used as stop element of the containing_mem list so we can check
+   presence in the list by checking the next pointer.  */
+static cselib_val dummy_val;
+
+/* Used to list all values that contain memory reference. 
+   May or may not contain the useless values - the list is compacted
+   each time memory is invalidated.  */
+static cselib_val *first_containing_mem = &dummy_val;
 \f
 
 /* Allocate a struct elt_list and fill in its two elements with the
@@ -237,6 +245,8 @@ clear_table (clear_all)
   n_useless_values = 0;
 
   next_unknown_value = 0;
+
+  first_containing_mem = &dummy_val;
 }
 
 /* The equality test for our hash table.  The first argument ENTRY is a table
@@ -371,6 +381,7 @@ discard_useless_values (x, info)
 static void
 remove_useless_values ()
 {
+  cselib_val **p, *v;
   /* First pass: eliminate locations that reference the value.  That in
      turn can make more values useless.  */
   do
@@ -383,6 +394,15 @@ remove_useless_values ()
   /* Second pass: actually remove the values.  */
   htab_traverse (hash_table, discard_useless_values, 0);
 
+  p = &first_containing_mem;
+  for (v = *p; v != &dummy_val; v = v->next_containing_mem)
+    if (v->locs)
+      {
+       *p = v;
+       p = &(*p)->next_containing_mem;
+      }
+  *p = &dummy_val;
+
   if (n_useless_values != 0)
     abort ();
 }
@@ -706,6 +726,7 @@ new_cselib_val (value, mode)
   CSELIB_VAL_PTR (e->u.val_rtx) = e;
   e->addr_list = 0;
   e->locs = 0;
+  e->next_containing_mem = 0;
   return e;
 }
 
@@ -730,6 +751,11 @@ add_mem_for_addr (addr_elt, mem_elt, x)
   mem_elt->locs
     = new_elt_loc_list (mem_elt->locs,
                        replace_equiv_address_nv (x, addr_elt->u.val_rtx));
+  if (mem_elt->next_containing_mem == NULL)
+    {
+      mem_elt->next_containing_mem = first_containing_mem;
+      first_containing_mem = mem_elt;
+    }
 }
 
 /* Subroutine of cselib_lookup.  Return a value for X, which is a MEM rtx.
@@ -1078,68 +1104,75 @@ cselib_mem_conflict_p (mem_base, val)
   return 0;
 }
 
-/* For the value found in SLOT, walk its locations to determine if any overlap
-   INFO (which is a MEM rtx).  */
+/* Invalidate any locations in the table which are changed because of a
+   store to MEM_RTX.  If this is called because of a non-const call
+   instruction, MEM_RTX is (mem:BLK const0_rtx).  */
 
-static int
-cselib_invalidate_mem_1 (slot, info)
-     void **slot;
-     void *info;
+static void
+cselib_invalidate_mem (mem_rtx)
+     rtx mem_rtx;
 {
-  cselib_val *v = (cselib_val *) *slot;
-  rtx mem_rtx = (rtx) info;
-  struct elt_loc_list **p = &v->locs;
-  int had_locs = v->locs != 0;
+  cselib_val **vp, *v, *next;
 
-  while (*p)
+  vp = &first_containing_mem;
+  for (v = *vp; v != &dummy_val; v = next)
     {
-      rtx x = (*p)->loc;
-      cselib_val *addr;
-      struct elt_list **mem_chain;
-
-      /* MEMs may occur in locations only at the top level; below
-        that every MEM or REG is substituted by its VALUE.  */
-      if (GET_CODE (x) != MEM
-         || ! cselib_mem_conflict_p (mem_rtx, x))
-       {
-         p = &(*p)->next;
-         continue;
-       }
+      bool has_mem = false;
+      struct elt_loc_list **p = &v->locs;
+      int had_locs = v->locs != 0;
 
-      /* This one overlaps.  */
-      /* 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);
-      mem_chain = &addr->addr_list;
-      for (;;)
+      while (*p)
        {
-         if ((*mem_chain)->elt == v)
+         rtx x = (*p)->loc;
+         cselib_val *addr;
+         struct elt_list **mem_chain;
+
+         /* MEMs may occur in locations only at the top level; below
+            that every MEM or REG is substituted by its VALUE.  */
+         if (GET_CODE (x) != MEM)
            {
-             unchain_one_elt_list (mem_chain);
-             break;
+             p = &(*p)->next;
+             continue;
+           }
+         if (! cselib_mem_conflict_p (mem_rtx, x))
+           {
+             has_mem = true;
+             p = &(*p)->next;
+             continue;
            }
 
-         mem_chain = &(*mem_chain)->next;
-       }
-
-      unchain_one_elt_loc_list (p);
-    }
+         /* This one overlaps.  */
+         /* 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);
+         mem_chain = &addr->addr_list;
+         for (;;)
+           {
+             if ((*mem_chain)->elt == v)
+               {
+                 unchain_one_elt_list (mem_chain);
+                 break;
+               }
 
-  if (had_locs && v->locs == 0)
-    n_useless_values++;
+             mem_chain = &(*mem_chain)->next;
+           }
 
-  return 1;
-}
+         unchain_one_elt_loc_list (p);
+       }
 
-/* Invalidate any locations in the table which are changed because of a
-   store to MEM_RTX.  If this is called because of a non-const call
-   instruction, MEM_RTX is (mem:BLK const0_rtx).  */
+      if (had_locs && v->locs == 0)
+       n_useless_values++;
 
-static void
-cselib_invalidate_mem (mem_rtx)
-     rtx mem_rtx;
-{
-  htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx);
+      next = v->next_containing_mem;
+      if (has_mem)
+       {
+         *vp = v;
+         vp = &(*vp)->next_containing_mem;
+       }
+      else
+       v->next_containing_mem = NULL;
+    }
+  *vp = &dummy_val;
 }
 
 /* Invalidate DEST, which is being assigned to or clobbered.  The second and
index f29ee8d..9cceddb 100644 (file)
@@ -38,6 +38,8 @@ typedef struct cselib_val_struct GTY(())
   /* If this value is used as an address, points to a list of values that
      use it as an address in a MEM.  */
   struct elt_list *addr_list;
+
+  struct cselib_val_struct *next_containing_mem;
 } cselib_val;
 
 /* A list of rtl expressions that hold the same value.  */