This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] for gcc-3.3 *Re: Let's backport speedups from 3.4 to 3.3


On 12 Feb, Karel Gardas wrote:
> On Thu, 13 Feb 2003, Kaoru Fukui wrote:
> 
>> > http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00377.html
>> > http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00560.htm
>> > There is Mike's info.
>> >
>> >
>> > I tried popcontext-fsf-2.diffs which is speedy, see below
>> >
>> > http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00380.html
>> > gcc-3.3 doesn't pch, so it needs to adjust.
>>
>> This is my adjusted Mike's patch for gcc-3.3.

Sorry ,previous patch is Mike's one which is for gcc-3.4.
I was worng.

this is adjusted one.
(deleted some lines for pch)



Kaoru
=========================
diff -urN base/gcc/ggc-page.c fixed/gcc/ggc-page.c
--- base/gcc/ggc-page.c	2003-02-06 18:14:12.000000000 +0900
+++ fixed/gcc/ggc-page.c	2003-02-06 20:12:26.000000000 +0900
@@ -24,7 +24,6 @@
 #include "rtl.h"
 #include "tm_p.h"
 #include "toplev.h"
-#include "varray.h"
 #include "flags.h"
 #include "ggc.h"
 #include "timevar.h"
@@ -251,9 +250,9 @@
   struct page_group *group;
 #endif
 
-  /* Saved in-use bit vector for pages that aren't in the topmost
-     context during collection.  */
-  unsigned long *save_in_use_p;
+  /* This is the index in the by_depth varray where this page table
+     can be found.  */
+  unsigned long index_by_depth;
 
   /* Context depth of this page.  */
   unsigned short context_depth;
@@ -312,6 +311,8 @@
 
 #endif
 
+typedef struct ggc_varray_head_tag *ggc_varray_type;
+
 /* The rest of the global variables.  */
 static struct globals
 {
@@ -359,6 +360,24 @@
 
   /* The file descriptor for debugging output.  */
   FILE *debug_file;
+
+  /* Each element of this array is a page_entry, all page_entries can
+     be found in here by increasing depth.  index_by_depth in the
+     page_entry is the index into this data structure where that
+     page_entry can be found.  This is used to speed up finding all
+     page_entries at a particular depth.  */
+  ggc_varray_type by_depth;
+
+  /* Each element is an index in by_depth where the given depth
+     starts.  This structure is indexed by that given depth we are
+     interested in.  */
+  ggc_varray_type depth;
+
+  /* Each element is a pointer to the saved in_use_p bits, if any,
+     zero otherwise.  We allocate them all together, to enable a
+     better runtime data access pattern.  */
+  ggc_varray_type save_in_use;
+
 } G;
 
 /* The size in bytes required to maintain a bitmap for the objects
@@ -371,6 +390,9 @@
    free list.  This cannot be larger than HOST_BITS_PER_INT for the
    in_use bitmask for page_group.  */
 #define GGC_QUIRE_SIZE 16
+
+/* Initial guess as to how many page table entries we might need.  */
+#define INITIAL_PTE_COUNT 128
 
 static int ggc_allocated_p PARAMS ((const void *));
 static page_entry *lookup_page_table_entry PARAMS ((const void *));
@@ -390,6 +412,8 @@
 static void sweep_pages PARAMS ((void));
 static void ggc_recalculate_in_use_p PARAMS ((page_entry *));
 static void compute_inverse PARAMS ((unsigned));
+static inline void adjust_depth PARAMS ((void));
+static void move_ptes_to_front PARAMS ((int, int));
 
 #ifdef ENABLE_GC_CHECKING
 static void poison_pages PARAMS ((void));
@@ -397,6 +421,169 @@
 
 void debug_print_page_list PARAMS ((int));
 
+/* Internal varray management code.  This is separated from varrays to
+   enable the removal of non-GCed objects from varray.[ch] */
+
+enum ggc_varray_data_enum {
+  GGC_VARRAY_DATA_C,
+  GGC_VARRAY_DATA_GENERICNGC,
+  GGC_VARRAY_DATA_UNGC,
+  GGC_NUM_VARRAY_DATA
+};
+
+/* Union of various array types that are used.  */
+typedef union ggc_varray_data_tag {
+  char	       c[1];
+  PTR	       genericngc[1];
+  unsigned int ungc[1];
+} ggc_varray_data;
+
+/* Virtual array of pointers header.  */
+struct ggc_varray_head_tag {
+  size_t	num_elements;	/* Maximum element number allocated.  */
+  size_t        elements_used;  /* The number of elements used, if
+				   using GGC_VARRAY_PUSH/GGC_VARRAY_POP.  */
+  enum ggc_varray_data_enum type;	/* The kind of elements in the varray.  */
+  const char *name;		/* name of the varray for reporting errors */
+  ggc_varray_data data;		/* The data elements follow, must be last.  */
+};
+
+/* Allocate a virtual array with NUM elements, each of which is SIZE bytes
+   long, named NAME.  Array elements are zeroed.  */
+static ggc_varray_type ggc_varray_init	PARAMS ((size_t, enum ggc_varray_data_enum, 
+						 const char *));
+
+#define GGC_VARRAY_GENERIC_PTRNGC_INIT(va, num, name) \
+  va = ggc_varray_init (num, GGC_VARRAY_DATA_GENERICNGC, name)
+
+#define GGC_VARRAY_UINTNGC_INIT(va, num, name) \
+  va = ggc_varray_init (num, GGC_VARRAY_DATA_UNGC, name)
+
+#define GGC_VARRAY_GENERIC_PTRNGC(VA,N)	GGC_VARRAY_CHECK (VA, N, genericngc)
+#define GGC_VARRAY_UINTNGC(VA, N)	GGC_VARRAY_CHECK (VA, N, ungc)
+
+/* Free up memory allocated by the virtual array, but do not free any of the
+   elements involved.  */
+#define GGC_VARRAY_FREE(vp) \
+  do { if (vp) { free (vp); vp = (ggc_varray_type) 0; } } while (0)
+#define GGC_VARRAY_GROW(VA, N) ((VA) = ggc_varray_grow (VA, N))
+
+/* Push X onto VA.  T is the name of the field in varray_data
+   corresponding to the type of X.  */
+#define GGC_VARRAY_PUSH(VA, T, X)			\
+  do							\
+    {							\
+      if ((VA)->elements_used >= (VA)->num_elements)	\
+        GGC_VARRAY_GROW ((VA), 2 * (VA)->num_elements);	\
+      (VA)->data.T[(VA)->elements_used++] = (X);	\
+    }							\
+  while (0)
+
+#define GGC_VARRAY_PUSH_GENERIC_PTRNGC(VA, X)	GGC_VARRAY_PUSH (VA, genericngc, X)
+#define GGC_VARRAY_PUSH_UINTNGC(VA, X)	GGC_VARRAY_PUSH (VA, ungc, X)
+
+/* Pop the top element of VA.  */
+#define GGC_VARRAY_POP(VA) \
+  ((VA)->elements_used--)
+
+/* Return the top element of VA.  */
+#define GGC_VARRAY_TOP(VA, T) \
+  ((VA)->data.T[(VA)->elements_used - 1])
+#define GGC_VARRAY_TOP_GENERIC_PTRNGC(VA)	GGC_VARRAY_TOP (VA, genericngc)
+#define GGC_VARRAY_TOP_UINTNGC(VA)		GGC_VARRAY_TOP (VA, ungc)
+
+#define GGC_VARRAY_HDR_SIZE (sizeof (struct ggc_varray_head_tag) - sizeof (ggc_varray_data))
+
+static const size_t element[GGC_NUM_VARRAY_DATA] = {
+  sizeof (char),
+  sizeof (PTR),
+  sizeof (unsigned int)
+};
+
+static inline ggc_varray_type ggc_varray_grow	PARAMS ((ggc_varray_type, size_t));
+
+/* Allocate a virtual array with NUM_ELEMENT elements, each of which is
+   ELEMENT_SIZE bytes long, named NAME.  Array elements are zeroed.  */
+static ggc_varray_type
+ggc_varray_init (num_elements, element_kind, name)
+     size_t num_elements;
+     enum ggc_varray_data_enum element_kind;
+     const char *name;
+{
+  size_t data_size = num_elements * element[element_kind];
+  ggc_varray_type ptr;
+  ptr = (ggc_varray_type) xcalloc (GGC_VARRAY_HDR_SIZE + data_size, 1);
+
+  ptr->num_elements = num_elements;
+  ptr->elements_used = 0;
+  ptr->type = element_kind;
+  ptr->name = name;
+  return ptr;
+}
+
+/* Grow/shrink the virtual array VA to N elements.  Zero any new elements
+   allocated.  */
+static inline ggc_varray_type
+ggc_varray_grow (va, n)
+     ggc_varray_type va;
+     size_t n;
+{
+  size_t old_elements = va->num_elements;
+
+  if (n != old_elements)
+    {
+      size_t elem_size = element[va->type];
+      size_t old_data_size = old_elements * elem_size;
+      size_t data_size = n * elem_size;
+
+      va = (ggc_varray_type) xrealloc ((char *) va, GGC_VARRAY_HDR_SIZE + data_size);
+      va->num_elements = n;
+      if (n > old_elements)
+	memset (&va->data.c[old_data_size], 0, data_size - old_data_size);
+    }
+
+  return va;
+}
+
+/* Check the bounds of a varray access.  */
+
+#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
+extern void ggc_varray_check_failed PARAMS ((ggc_varray_type, size_t,
+					     const char *, int,
+					     const char *)) ATTRIBUTE_NORETURN;
+#define GGC_VARRAY_CHECK(VA, N, T) __extension__			\
+(*({ ggc_varray_type const _va = (VA);				\
+     const size_t _n = (N); 					\
+     if (_n >= _va->num_elements)				\
+       ggc_varray_check_failed (_va, _n, __FILE__, __LINE__, __FUNCTION__);	\
+     &_va->data.T[_n]; }))
+
+extern void error PARAMS ((const char *, ...))	ATTRIBUTE_PRINTF_1;
+
+void
+ggc_varray_check_failed (va, n, file, line, function)
+     ggc_varray_type va;
+     size_t n;
+     const char *file;
+     int line;
+     const char *function;
+{
+  internal_error ("virtual array %s[%lu]: element %lu out of bounds in %s, at %s:%d",
+		  va->name, (unsigned long) va->num_elements, (unsigned long) n,
+		  function, trim_filename (file), line);
+}
+#else
+#define GGC_VARRAY_CHECK(VA, N, T) ((VA)->data.T[N])
+#endif
+
+#define GGC_VARRAY_ACTIVE_SIZE(VA)	((VA)->elements_used)
+
+
+#define save_in_use_p_i(__i) \
+  (*(unsigned long **)&GGC_VARRAY_GENERIC_PTRNGC (G.save_in_use, __i))
+#define save_in_use_p(__p) \
+  (save_in_use_p_i (__p->index_by_depth))
+
 /* Returns nonzero if P was allocated in GC'able memory.  */
 
 static inline int
@@ -762,6 +949,25 @@
   return entry;
 }
 
+/* Adjust the size of G.depth so that no index greater than the one
+   used by the top of the G.by_depth varray is used.  */
+
+static inline void
+adjust_depth ()
+{
+  page_entry *top;
+
+  if (GGC_VARRAY_ACTIVE_SIZE (G.by_depth))
+    {
+      top = GGC_VARRAY_TOP_GENERIC_PTRNGC (G.by_depth);
+      /* Peel back indicies in depth that index into by_depth, so that
+	 as new elements are added to by_depth, we note the indicies
+	 of those elements, if they are for new context depths.  */
+      while (GGC_VARRAY_ACTIVE_SIZE (G.depth) > (size_t)top->context_depth+1)
+	GGC_VARRAY_POP (G.depth);
+    }
+}
+
 /* For a page that is no longer needed, put it on the free page list.  */
 
 static inline void
@@ -783,6 +989,32 @@
   clear_page_group_in_use (entry->group, entry->page);
 #endif
 
+  if (GGC_VARRAY_ACTIVE_SIZE (G.by_depth) > 1)
+    {
+      page_entry *top = GGC_VARRAY_TOP_GENERIC_PTRNGC (G.by_depth);
+
+      /* If they are at the same depth, put top element into freed
+	 slot.  */
+      if (entry->context_depth == top->context_depth)
+	{
+	  int i = entry->index_by_depth;
+	  GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, i) = top;
+	  GGC_VARRAY_GENERIC_PTRNGC (G.save_in_use, i)
+	    = GGC_VARRAY_TOP_GENERIC_PTRNGC (G.save_in_use);
+	  top->index_by_depth = i;
+	}
+      else
+	{
+	  /* We cannot free a page from a context deeper than the
+	     current one.  */
+	  abort ();
+	}
+    }
+  GGC_VARRAY_POP (G.by_depth);
+  GGC_VARRAY_POP (G.save_in_use);
+
+  adjust_depth ();
+
   entry->next = G.free_pages;
   G.free_pages = entry;
 }
@@ -906,6 +1138,15 @@
       struct page_entry *new_entry;
       new_entry = alloc_page (order);
 
+      new_entry->index_by_depth = GGC_VARRAY_ACTIVE_SIZE (G.by_depth);
+      GGC_VARRAY_PUSH_GENERIC_PTRNGC (G.by_depth, new_entry);
+      GGC_VARRAY_PUSH_GENERIC_PTRNGC (G.save_in_use, 0);
+
+      /* We can skip context depths, if we do, make sure we go all the
+	 way to the new depth.  */
+      while (new_entry->context_depth >= GGC_VARRAY_ACTIVE_SIZE (G.depth))
+	GGC_VARRAY_PUSH_UINTNGC (G.depth, GGC_VARRAY_ACTIVE_SIZE (G.by_depth)-1);
+
       /* If this is the only entry, it's also the tail.  */
       if (entry == NULL)
 	G.page_tails[order] = new_entry;
@@ -1208,6 +1449,10 @@
       for (i = OBJECT_SIZE (order); size_lookup [i] == o; --i)
 	size_lookup[i] = order;
     }
+
+  GGC_VARRAY_GENERIC_PTRNGC_INIT (G.by_depth, INITIAL_PTE_COUNT, "by_depth");
+  GGC_VARRAY_GENERIC_PTRNGC_INIT (G.save_in_use, INITIAL_PTE_COUNT, "save_in_use");
+  GGC_VARRAY_UINTNGC_INIT (G.depth, 10, "depth");
 }
 
 /* Increment the `GC context'.  Objects allocated in an outer context
@@ -1250,7 +1495,7 @@
 
       /* Something is in use if it is marked, or if it was in use in a
 	 context further down the context stack.  */
-      p->in_use_p[i] |= p->save_in_use_p[i];
+      p->in_use_p[i] |= save_in_use_p (p)[i];
 
       /* Decrement the free object count for every object allocated.  */
       for (j = p->in_use_p[i]; j; j >>= 1)
@@ -1267,13 +1512,74 @@
 void
 ggc_pop_context ()
 {
-  unsigned order, depth;
+   unsigned depth, i, e;
+#ifdef ENABLE_CHECKING
+   unsigned order;
+#endif
+
 
   depth = --G.context_depth;
 
-  /* Any remaining pages in the popped context are lowered to the new
-     current context; i.e. objects allocated in the popped context and
-     left over are imported into the previous context.  */
+  /* The G.depth array is shortend so that the last index is the
+     context_depth of the top element of by_depth.  */
+  if (depth+1 < GGC_VARRAY_ACTIVE_SIZE (G.depth))
+    e = GGC_VARRAY_UINTNGC (G.depth, depth+1);
+  else
+    e = GGC_VARRAY_ACTIVE_SIZE (G.by_depth);
+
+  /* We might not have any PTEs of depth depth.  */
+  if (depth < GGC_VARRAY_ACTIVE_SIZE (G.depth))
+    {    
+
+      /* First we go through all the pages at depth depth to
+	 recalculate the in use bits.  */
+      for (i = GGC_VARRAY_UINTNGC (G.depth, depth); i < e; ++i)
+	{
+	  page_entry *p;
+
+#ifdef ENABLE_CHECKING
+	  p = GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, i);
+
+	  /* Check that all of the pages really are at the depth that
+	     we expect.  */
+	  if (p->context_depth != depth)
+	    abort ();
+	  if (p->index_by_depth != i)
+	    abort ();
+#endif
+
+	  __builtin_prefetch (&save_in_use_p_i (i+8));
+	  __builtin_prefetch (&save_in_use_p_i (i+16));
+	  if (save_in_use_p_i (i))
+	    {
+	      p = GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, i);
+	      ggc_recalculate_in_use_p (p);
+	      free (save_in_use_p_i (i));
+	      save_in_use_p_i (i) = 0;
+	    }
+	}
+    }
+
+  /* Then, we reset all page_entries with a depth greater than depth
+     to be at depth.  */
+  for (i = e; i < GGC_VARRAY_ACTIVE_SIZE (G.by_depth); ++i)
+    {
+      page_entry *p = GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, i);
+
+      /* Check that all of the pages really are at the depth we
+	 expect.  */
+#ifdef ENABLE_CHECKING
+      if (p->context_depth <= depth)
+	abort ();
+      if (p->index_by_depth != i)
+	abort ();
+#endif
+      p->context_depth = depth;
+    }
+
+  adjust_depth ();
+
+#ifdef ENABLE_CHECKING
   for (order = 2; order < NUM_ORDERS; order++)
     {
       page_entry *p;
@@ -1281,18 +1587,12 @@
       for (p = G.pages[order]; p != NULL; p = p->next)
 	{
 	  if (p->context_depth > depth)
-	    p->context_depth = depth;
-
-	  /* If this page is now in the topmost context, and we'd
-	     saved its allocation state, restore it.  */
-	  else if (p->context_depth == depth && p->save_in_use_p)
-	    {
-	      ggc_recalculate_in_use_p (p);
-	      free (p->save_in_use_p);
-	      p->save_in_use_p = 0;
-	    }
+	    abort ();
+	  else if (p->context_depth == depth && save_in_use_p (p))
+	    abort ();
 	}
     }
+#endif
 }
 
 /* Unmark all objects.  */
@@ -1322,9 +1622,9 @@
 	     marks.  So, back them up first.  */
 	  if (p->context_depth < G.context_depth)
 	    {
-	      if (! p->save_in_use_p)
-		p->save_in_use_p = xmalloc (bitmap_size);
-	      memcpy (p->save_in_use_p, p->in_use_p, bitmap_size);
+	      if (! save_in_use_p (p))
+		save_in_use_p (p) = xmalloc (bitmap_size);
+	      memcpy (save_in_use_p (p), p->in_use_p, bitmap_size);
 	    }
 
 	  /* Reset reset the number of free objects and clear the
@@ -1755,6 +2055,73 @@
   free (d);
 }
 
+/* Move the PCH PTE entries just added to the end of by_depth, to the
+   front.  */
+
+static void
+move_ptes_to_front (count_old_page_tables, count_new_page_tables)
+     int count_old_page_tables;
+     int count_new_page_tables;
+{
+  unsigned i;
+
+  /* First, we swap the new entries to the front of the varrays.  */
+
+  ggc_varray_type new_by_depth;
+  ggc_varray_type new_save_in_use;
+  int c;
+
+  c = count_old_page_tables + count_new_page_tables;
+  /* Allow for at least 25% growth without resizing.  */
+  c = c + c/4;
+  c = MAX (c, INITIAL_PTE_COUNT);
+
+  GGC_VARRAY_GENERIC_PTRNGC_INIT (new_by_depth,
+				  c,
+				  "by_depth");
+  GGC_VARRAY_GENERIC_PTRNGC_INIT (new_save_in_use,
+			      c,
+			      "save_in_use");
+  GGC_VARRAY_ACTIVE_SIZE (new_by_depth) = count_old_page_tables
+    + count_new_page_tables;
+  GGC_VARRAY_ACTIVE_SIZE (new_save_in_use) = count_old_page_tables
+    + count_new_page_tables;
+
+  memcpy (&GGC_VARRAY_GENERIC_PTRNGC (new_by_depth, 0),
+	  &GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, count_old_page_tables),
+	  count_new_page_tables * sizeof (void *));
+  memcpy (&GGC_VARRAY_GENERIC_PTRNGC (new_by_depth, count_new_page_tables),
+	  &GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, 0),
+	  count_old_page_tables * sizeof (void *));
+  memcpy (&GGC_VARRAY_GENERIC_PTRNGC (new_save_in_use, 0),
+	  &GGC_VARRAY_GENERIC_PTRNGC (G.save_in_use, count_old_page_tables),
+	  count_new_page_tables * sizeof (void *));
+  memcpy (&GGC_VARRAY_GENERIC_PTRNGC (new_save_in_use, count_new_page_tables),
+	  &GGC_VARRAY_GENERIC_PTRNGC (G.save_in_use, 0),
+	  count_old_page_tables * sizeof (void *));
+
+  GGC_VARRAY_FREE (G.by_depth);
+  GGC_VARRAY_FREE (G.save_in_use);
+    
+  G.by_depth = new_by_depth;
+  G.save_in_use = new_save_in_use;
+
+  /* Now update all the index_by_depth fields.  */
+  for (i = GGC_VARRAY_ACTIVE_SIZE (G.by_depth); i > 0; --i)
+    {
+      page_entry *p = GGC_VARRAY_GENERIC_PTRNGC (G.by_depth, i-1);
+      p->index_by_depth = i-1;
+    }
+
+  /* And last, we update the depth pointers in G.depth.  The first
+     entry is already 0, and context 0 entries always start at index
+     0, so there is nothing to update in the first slot.  We need a
+     second slot, only if we have old ptes, and if we do, they start
+     at index count_new_page_tables.  */
+  if (count_old_page_tables)
+    GGC_VARRAY_PUSH_UINTNGC (G.depth, count_new_page_tables);
+}
+
 void
 ggc_pch_read (f, addr)
      FILE *f;
@@ -1763,9 +2130,13 @@
   struct ggc_pch_ondisk d;
   unsigned i;
   char *offs = addr;
-  
-  /* We've just read in a PCH file.  So, every object that used to be allocated
-     is now free.  */
+  unsigned long count_old_page_tables;
+  unsigned long count_new_page_tables;
+
+  count_old_page_tables = GGC_VARRAY_ACTIVE_SIZE (G.by_depth);
+
+  /* We've just read in a PCH file.  So, every object that used to be
+     allocated is now free.  */
   clear_marks ();
 #ifdef GGC_POISON
   poison_pages ();
@@ -1796,10 +2167,10 @@
       size_t bytes;
       size_t num_objs;
       size_t j;
-      
+
       if (d.totals[i] == 0)
 	continue;
-      
+
       bytes = ROUND_UP (d.totals[i] * OBJECT_SIZE (i), G.pagesize);
       num_objs = bytes / OBJECT_SIZE (i);
       entry = xcalloc (1, (sizeof (struct page_entry) 
@@ -1830,8 +2201,23 @@
       else
 	G.pages[i] = entry;
       G.page_tails[i] = entry;
+
+      /* We start off by just adding all the new information to the
+	 end of the varrays, later, we will move the new information
+	 to the front of the varrays, as the PCH page tables are at
+	 context 0.  */
+      GGC_VARRAY_PUSH_GENERIC_PTRNGC (G.by_depth, entry);
+      GGC_VARRAY_PUSH_GENERIC_PTRNGC (G.save_in_use, 0);
     }
 
+  /* Now, we update the various data structures that speed page table
+     handling.  */
+
+  count_new_page_tables = GGC_VARRAY_ACTIVE_SIZE (G.by_depth)
+    - count_old_page_tables;
+
+  move_ptes_to_front (count_old_page_tables, count_new_page_tables);
+
   /* Update the statistics.  */
   G.allocated = G.allocated_last_gc = offs - (char *)addr;
 }
diff -urN base/gcc/varray.c fixed/gcc/varray.c
--- base/gcc/varray.c	2002-06-04 16:08:17.000000000 +0900
+++ fixed/gcc/varray.c	2003-02-06 18:16:11.000000000 +0900
@@ -27,34 +27,33 @@
 
 #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
 
-static const size_t element_size[NUM_VARRAY_DATA] = {
-  sizeof (char),
-  sizeof (unsigned char),
-  sizeof (short),
-  sizeof (unsigned short),
-  sizeof (int),
-  sizeof (unsigned int),
-  sizeof (long),
-  sizeof (unsigned long),
-  sizeof (HOST_WIDE_INT),
-  sizeof (unsigned HOST_WIDE_INT),
-  sizeof (PTR),
-  sizeof (char *),
-  sizeof (struct rtx_def *),
-  sizeof (struct rtvec_def *),
-  sizeof (union tree_node *),
-  sizeof (struct bitmap_head_def *),
-  sizeof (struct reg_info_def *),
-  sizeof (struct const_equiv_data),
-  sizeof (struct basic_block_def *),
-  sizeof (struct elt_list *)
-};
+/* Do not add any more non-GC items here.  Please either remove or GC those items that
+   are not GCed.  */
 
-static const int uses_ggc[NUM_VARRAY_DATA] = {
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* unsigned HOST_WIDE_INT */
-  1, /* PTR */
-  1, 1, 1, 1, 1, /* bitmap_head_def */
-  0, 0, 0, 1
+static const struct {
+  size_t size;
+  int uses_ggc;
+} element[NUM_VARRAY_DATA] = {
+  { sizeof (char), 1 },
+  { sizeof (unsigned char), 1 },
+  { sizeof (short), 1 },
+  { sizeof (unsigned short), 1 },
+  { sizeof (int), 1 },
+  { sizeof (unsigned int), 1 },
+  { sizeof (long), 1 },
+  { sizeof (unsigned long), 1 },
+  { sizeof (HOST_WIDE_INT), 1 },
+  { sizeof (unsigned HOST_WIDE_INT), 1 },
+  { sizeof (PTR), 1 },
+  { sizeof (char *), 1 },
+  { sizeof (struct rtx_def *), 1 },
+  { sizeof (struct rtvec_def *), 1 },
+  { sizeof (union tree_node *), 1 },
+  { sizeof (struct bitmap_head_def *), 1 },
+  { sizeof (struct reg_info_def *), 0 },
+  { sizeof (struct const_equiv_data), 0 },
+  { sizeof (struct basic_block_def *), 0 },
+  { sizeof (struct elt_list *), 1 },
 };
 
 /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
@@ -65,9 +64,9 @@
      enum varray_data_enum element_kind;
      const char *name;
 {
-  size_t data_size = num_elements * element_size[element_kind];
+  size_t data_size = num_elements * element[element_kind].size;
   varray_type ptr;
-  if (uses_ggc [element_kind])
+  if (element[element_kind].uses_ggc)
     ptr = (varray_type) ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
   else
     ptr = (varray_type) xcalloc (VARRAY_HDR_SIZE + data_size, 1);
@@ -90,11 +89,11 @@
 
   if (n != old_elements)
     {
-      size_t elem_size = element_size[va->type];
+      size_t elem_size = element[va->type].size;
       size_t old_data_size = old_elements * elem_size;
       size_t data_size = n * elem_size;
 
-      if (uses_ggc[va->type])
+      if (element[va->type].uses_ggc)
 	va = (varray_type) ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
       else
 	va = (varray_type) xrealloc ((char *) va, VARRAY_HDR_SIZE + data_size);
@@ -111,7 +110,7 @@
 varray_clear (va)
      varray_type va;
 {
-  size_t data_size = element_size[va->type] * va->num_elements;
+  size_t data_size = element[va->type].size * va->num_elements;
 
   memset (va->data.c, 0, data_size);
   va->elements_used = 0;
diff -urN base/gcc/varray.h fixed/gcc/varray.h
--- base/gcc/varray.h	2002-06-04 16:08:18.000000000 +0900
+++ fixed/gcc/varray.h	2003-02-06 18:16:11.000000000 +0900
@@ -55,7 +55,7 @@
 };
 
 /* Enum indicating what the varray contains.  
-   If this is changed, `element_size' in varray.c needs to be updated.  */
+   If this is changed, `element' in varray.c needs to be updated.  */
 
 enum varray_data_enum {
   VARRAY_DATA_C,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]