public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-12 17:47 Kaoru Fukui
  2003-02-12 21:07 ` Karel Gardas
  2003-02-20 20:09 ` Mark Mitchell
  0 siblings, 2 replies; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-12 17:47 UTC (permalink / raw)
  To: ghazi; +Cc: gcc, gcc-patches

On 13 Feb, To: ghazi@caip.rutgers.edu wrote:
> On 12 Feb, Kaveh R. Ghazi wrote:
>> I've heard some mention that 3.4 is faster in some cases than 3.3.
>> 
>> I know several speedup tweeks have been made since the branch was
>> created.  Not all of them have been backported.
>> 
>> If they're not too invasive, let's consider them for 3.3.  I'm willing
>> to help by regtesting patches if people can point out safe candidates.
>> Though I'd certainly appreciate assistance from others. :-)
>> 
>> 		Thanks,
>> 		--Kaveh
>> --
>> Kaveh R. Ghazi			ghazi@caip.rutgers.edu
> 
> 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.

Thanks Mike
Kaoru

====================================
	* ggc-page.c (struct page_entry): Add index_by_depth field.
	Remove save_in_use_p field.
	(struct globals): Add by_depth, depth, and save_in_use fields.
	(INITIAL_PTE_COUNT): Add.
	(save_in_use_p_i): Add.
	(save_in_use_p): Add.
	(adjust_depth): Add.
	(move_ptes_to_front): Add.
	(free_page): Add support for and use faster data structures.
	(ggc_alloc): Likewise.
	(init_ggc): Likewise.
	(ggc_recalculate_in_use_p): Likewise.
	(ggc_pop_context): Likewise.
	(clear_marks): Likewise.
	(ggc_pch_read): Likewise.

	(ggc_varray_type): Add.
	(ggc_varray_head_tag): Add.
	(ggc_varray_data_enum): Add.
	(GGC_VARRAY_DATA_C): Add.
	(GGC_VARRAY_DATA_GENERICNGC): Add.
	(GGC_VARRAY_DATA_UNGC): Add.
	(GGC_NUM_VARRAY_DATA): Add.
	(union ggc_varray_data_tag): Add.
	(ggc_varray_data): Add.
	(ggc_varray_init): Add.
	(GGC_VARRAY_GENERIC_PTRNGC_INIT): Add.
	(GGC_VARRAY_UINTNGC_INIT): Add.
	(GGC_VARRAY_GENERIC_PTRNGC): Add.
	(GGC_VARRAY_UINTNGC): Add.
	(GGC_VARRAY_PUSH_GENERIC_PTRNGC): Add.
	(GGC_VARRAY_PUSH_UINTNGC): Add.
	(GGC_VARRAY_TOP_GENERIC_PTRNGC): Add.
	(GGC_VARRAY_TOP_UINTNGC): Add.
	(GGC_VARRAY_FREE): Add.
	(GGC_VARRAY_GROW): Add.
	(GGC_VARRAY_PUSH): Add.
	(GGC_VARRAY_POP): Add.
	(GGC_VARRAY_TOP): Add.
	(GGC_VARRAY_HDR_SIZE): Add.
	(ggc_varray_init): Add.
	(ggc_varray_grow): Add.
	(ggc_varray_check_failed): Add.
	(GGC_VARRAY_ACTIVE_SIZE): Add.

	* varray.c (element_size): Remove.
	(uses_ggc): Remove.
	(element): Add.
	(varray_init): Use new interface.
	(varray_grow): Use new interface.
	(varray_clear): Use new interface.

Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.16
diff -p -r1.16 varray.c
*** varray.c	16 Dec 2002 18:20:02 -0000	1.16
--- varray.c	6 Feb 2003 01:54:07 -0000
***************
*** 29,62 ****
  
  #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 *)
! };
  
! 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
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
--- 29,61 ----
  
  #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
  
! /* Do not add any more non-GC items here.  Please either remove or GC those items that
!    are not GCed.  */
  
! 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
*************** varray_init (num_elements, element_kind,
*** 67,75 ****
       enum varray_data_enum element_kind;
       const char *name;
  {
!   size_t data_size = num_elements * element_size[element_kind];
    varray_type ptr;
!   if (uses_ggc [element_kind])
      ptr = (varray_type) ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
    else
      ptr = (varray_type) xcalloc (VARRAY_HDR_SIZE + data_size, 1);
--- 66,74 ----
       enum varray_data_enum element_kind;
       const char *name;
  {
!   size_t data_size = num_elements * element[element_kind].size;
    varray_type ptr;
!   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);
*************** varray_grow (va, n)
*** 92,102 ****
  
    if (n != old_elements)
      {
!       size_t elem_size = element_size[va->type];
        size_t old_data_size = old_elements * elem_size;
        size_t data_size = n * elem_size;
  
!       if (uses_ggc[va->type])
  	va = (varray_type) ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
        else
  	va = (varray_type) xrealloc ((char *) va, VARRAY_HDR_SIZE + data_size);
--- 91,101 ----
  
    if (n != old_elements)
      {
!       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 (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);
*************** void
*** 113,119 ****
  varray_clear (va)
       varray_type va;
  {
!   size_t data_size = element_size[va->type] * va->num_elements;
  
    memset (va->data.c, 0, data_size);
    va->elements_used = 0;
--- 112,118 ----
  varray_clear (va)
       varray_type va;
  {
!   size_t data_size = element[va->type].size * va->num_elements;
  
    memset (va->data.c, 0, data_size);
    va->elements_used = 0;
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.29
diff -p -r1.29 varray.h
*** varray.h	16 Dec 2002 18:20:02 -0000	1.29
--- varray.h	6 Feb 2003 01:54:07 -0000
*************** struct const_equiv_data GTY(()) {
*** 57,63 ****
  };
  
  /* Enum indicating what the varray contains.  
!    If this is changed, `element_size' in varray.c needs to be updated.  */
  
  enum varray_data_enum {
    VARRAY_DATA_C,
--- 57,63 ----
  };
  
  /* Enum indicating what the varray contains.  
!    If this is changed, `element' in varray.c needs to be updated.  */
  
  enum varray_data_enum {
    VARRAY_DATA_C,
Index: ggc-page.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-page.c,v
retrieving revision 1.61
diff -p -r1.61 ggc-page.c
*** ggc-page.c	30 Jan 2003 18:14:06 -0000	1.61
--- ggc-page.c	6 Feb 2003 01:54:09 -0000
*************** Software Foundation, 59 Temple Place - S
*** 26,32 ****
  #include "rtl.h"
  #include "tm_p.h"
  #include "toplev.h"
- #include "varray.h"
  #include "flags.h"
  #include "ggc.h"
  #include "timevar.h"
--- 26,31 ----
*************** typedef struct page_entry
*** 253,261 ****
    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;
  
    /* Context depth of this page.  */
    unsigned short context_depth;
--- 252,260 ----
    struct page_group *group;
  #endif
  
!   /* 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;
*************** typedef struct page_table_chain
*** 314,319 ****
--- 313,320 ----
  
  #endif
  
+ typedef struct ggc_varray_head_tag *ggc_varray_type;
+ 
  /* The rest of the global variables.  */
  static struct globals
  {
*************** static struct globals
*** 367,372 ****
--- 368,391 ----
  
    /* 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
*************** static struct globals
*** 379,384 ****
--- 398,406 ----
     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
  \f
  static int ggc_allocated_p PARAMS ((const void *));
  static page_entry *lookup_page_table_entry PARAMS ((const void *));
*************** static void clear_marks PARAMS ((void));
*** 398,403 ****
--- 420,427 ----
  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));
*************** static void poison_pages PARAMS ((void))
*** 405,410 ****
--- 429,597 ----
  
  void debug_print_page_list PARAMS ((int));
  \f
+ /* 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)
+ \f
+ 
+ #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))
+ \f
  /* Returns nonzero if P was allocated in GC'able memory.  */
  
  static inline int
*************** alloc_page (order)
*** 772,777 ****
--- 959,983 ----
    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
*************** free_page (entry)
*** 793,798 ****
--- 999,1030 ----
    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;
  }
*************** ggc_alloc (size)
*** 916,921 ****
--- 1148,1162 ----
        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;
*************** init_ggc ()
*** 1218,1223 ****
--- 1459,1468 ----
        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
*************** ggc_recalculate_in_use_p (p)
*** 1260,1266 ****
  
        /* 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];
  
        /* Decrement the free object count for every object allocated.  */
        for (j = p->in_use_p[i]; j; j >>= 1)
--- 1505,1511 ----
  
        /* 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] |= 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)
*************** void
*** 1278,1284 ****
  ggc_pop_context ()
  {
    unsigned long omask;
!   unsigned order, depth;
  
    depth = --G.context_depth;
    omask = (unsigned long)1 << (depth + 1);
--- 1523,1532 ----
  ggc_pop_context ()
  {
    unsigned long omask;
!   unsigned depth, i, e;
! #ifdef ENABLE_CHECKING
!   unsigned order;
! #endif
  
    depth = --G.context_depth;
    omask = (unsigned long)1 << (depth + 1);
*************** ggc_pop_context ()
*** 1290,1298 ****
    G.context_depth_allocations &= omask - 1;
    G.context_depth_collections &= omask - 1;
  
!   /* 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.  */
    for (order = 2; order < NUM_ORDERS; order++)
      {
        page_entry *p;
--- 1538,1603 ----
    G.context_depth_allocations &= omask - 1;
    G.context_depth_collections &= omask - 1;
  
!   /* 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;
*************** ggc_pop_context ()
*** 1300,1317 ****
        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;
! 	    }
  	}
      }
  }
  \f
  /* Unmark all objects.  */
--- 1605,1616 ----
        for (p = G.pages[order]; p != NULL; p = p->next)
  	{
  	  if (p->context_depth > depth)
! 	    abort ();
! 	  else if (p->context_depth == depth && save_in_use_p (p))
! 	    abort ();
  	}
      }
+ #endif
  }
  \f
  /* Unmark all objects.  */
*************** clear_marks ()
*** 1341,1349 ****
  	     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);
  	    }
  
  	  /* Reset reset the number of free objects and clear the
--- 1640,1648 ----
  	     marks.  So, back them up first.  */
  	  if (p->context_depth < G.context_depth)
  	    {
! 	      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
*************** ggc_pch_finish (d, f)
*** 1777,1782 ****
--- 2076,2148 ----
    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;
*************** ggc_pch_read (f, addr)
*** 1785,1793 ****
    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.  */
    clear_marks ();
  #ifdef GGC_POISON
    poison_pages ();
--- 2151,2163 ----
    struct ggc_pch_ondisk d;
    unsigned i;
    char *offs = addr;
!   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 ();
*************** ggc_pch_read (f, addr)
*** 1818,1827 ****
        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) 
--- 2188,2197 ----
        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) 
*************** ggc_pch_read (f, addr)
*** 1852,1858 ****
--- 2222,2243 ----
        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;

^ permalink raw reply	[flat|nested] 29+ messages in thread
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-22  2:51 Kaoru Fukui
  0 siblings, 0 replies; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-22  2:51 UTC (permalink / raw)
  To: ghazi; +Cc: gcc-patches, gcc, mark, zack

On 21 Feb, Kaveh R. Ghazi wrote:

>  > mainline 3.4 was included Zack's BI tree which was just faster than the
>  > mainline(this is 3.3 now) on that tme.
>  > Kaoru
> 
> Sorry, I'm not sure what you mean.  Are you saying that there is a
> patch we should backport to 3.3?  Or are you saying that this patch is
> now in 3.3 and made 3.3 as fast as 3.4?
> 
gcc-3_4-basic-improvements was just faster than mainline Which become to
gcc-3.3.

gcc-3.4 has merged,so it be just different speed without mike's patch.

Kaoru
PS sorry my English.

^ permalink raw reply	[flat|nested] 29+ messages in thread
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-21 18:02 Kaoru Fukui
  2003-02-22  1:06 ` Kaveh R. Ghazi
  0 siblings, 1 reply; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-21 18:02 UTC (permalink / raw)
  To: ghazi; +Cc: gcc-patches, gcc, k_fukui, mark

On 21 Feb, Kaveh R. Ghazi wrote:
>  > From: Gabriel Dos Reis <gdr@integrable-solutions.net>
>  > 
>  > "Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> writes:
>  > 
>  > |  > From: Mark Mitchell <mark@codesourcery.com>
>  > |  > 
>  > |  > Just to  make sure  I'm clear,  I don't object  in any  way to
>  > |  > backporting changes that  speed up the compiler --  as long as
>  > |  > the person approving them  feels that they're safe.  Let's not
>  > |  > do  anything too  radical, but  relatively simple  changes are
>  > |  > fine.
>  > | 
>  > | Are there any more anyone would like to recommend for consideration?
>  > 
>  > Not one that is currently on mainline.  
>  > -- Gaby
> 
> Ok, I'm asking because various people claim 3.4 is faster than 3.3
> (independent of 3.4-only things like PCH.)  I wonder if that's still
> the case.
> 

mainline 3.4 was included Zack's BI tree which was just faster than the
mainline(this is 3.3 now) on that tme.

Kaoru

^ permalink raw reply	[flat|nested] 29+ messages in thread
[parent not found: <6A8EF29C-3FA3-11D7-AFC7-003065A77310@apple.com>]
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-12 21:53 Kaoru Fukui
  2003-02-12 22:06 ` Karel Gardas
  0 siblings, 1 reply; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-12 21:53 UTC (permalink / raw)
  To: kgardas; +Cc: gcc

> Sorry, but I'm not able to patch my todays gcc3.3 sources:
> 
> thinkpad:~/cvs/gcc/gcc33-test/gcc$ patch < /tmp/gcc33-patch
> patching file varray.c
> Hunk #1 succeeded at 27 (offset -2 lines).
> Hunk #2 succeeded at 64 (offset -2 lines).
> Hunk #3 succeeded at 89 (offset -2 lines).
> Hunk #4 succeeded at 110 (offset -2 lines).
> patching file varray.h
> Hunk #1 succeeded at 55 (offset -2 lines).
> patching file ggc-page.c
> Hunk #1 succeeded at 24 (offset -2 lines).
> Hunk #2 succeeded at 238 (offset -14 lines).
> Hunk #3 succeeded at 299 (offset -14 lines).
> Hunk #4 succeeded at 348 (offset -20 lines).
> Hunk #5 succeeded at 378 (offset -20 lines).
> Hunk #6 succeeded at 400 (offset -20 lines).
> Hunk #7 succeeded at 409 (offset -20 lines).
> Hunk #8 succeeded at 937 (offset -22 lines).
> Hunk #9 succeeded at 977 (offset -22 lines).
> Hunk #10 succeeded at 1126 (offset -22 lines).
> Hunk #11 succeeded at 1437 (offset -22 lines).
> Hunk #12 succeeded at 1483 (offset -22 lines).
> Hunk #13 FAILED at 1501.

fixable fail for looking the source.

> Hunk #14 succeeded at 1507 with fuzz 2 (offset -31 lines).
> Hunk #15 succeeded at 1574 (offset -31 lines).
> Hunk #16 succeeded at 1608 (offset -32 lines).
> Hunk #17 succeeded at 1835 with fuzz 2 (offset -241 lines).
> Hunk #18 FAILED at 1910.
> Hunk #19 FAILED at 1947.
> Hunk #20 FAILED at 1981.

no need,these are for pch

Kaoru



^ permalink raw reply	[flat|nested] 29+ messages in thread
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-12 17:29 Kaoru Fukui
  0 siblings, 0 replies; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-12 17:29 UTC (permalink / raw)
  To: ghazi; +Cc: gcc

On 12 Feb, Kaveh R. Ghazi wrote:
> I've heard some mention that 3.4 is faster in some cases than 3.3.
> 
> I know several speedup tweeks have been made since the branch was
> created.  Not all of them have been backported.
> 
> If they're not too invasive, let's consider them for 3.3.  I'm willing
> to help by regtesting patches if people can point out safe candidates.
> Though I'd certainly appreciate assistance from others. :-)
> 
> 		Thanks,
> 		--Kaveh
> --
> Kaveh R. Ghazi			ghazi@caip.rutgers.edu

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.
Kaoru



^ permalink raw reply	[flat|nested] 29+ messages in thread
* Re: Let's backport speedups from 3.4 to 3.3
@ 2003-02-12 17:29 Kaoru Fukui
  0 siblings, 0 replies; 29+ messages in thread
From: Kaoru Fukui @ 2003-02-12 17:29 UTC (permalink / raw)
  To: ghazi; +Cc: gcc

On 13 Feb, To: ghazi@caip.rutgers.edu wrote:
> On 12 Feb, Kaveh R. Ghazi wrote:
>> I've heard some mention that 3.4 is faster in some cases than 3.3.
>> 
>> I know several speedup tweeks have been made since the branch was
>> created.  Not all of them have been backported.
>> 
>> If they're not too invasive, let's consider them for 3.3.  I'm willing
>> to help by regtesting patches if people can point out safe candidates.
>> Though I'd certainly appreciate assistance from others. :-)
>> 
>> 		Thanks,
>> 		--Kaveh
>> --
>> Kaveh R. Ghazi			ghazi@caip.rutgers.edu
> 
> 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.

Sorry, it was that gcc-3.3 doesn't have pch
K

^ permalink raw reply	[flat|nested] 29+ messages in thread
* Let's backport speedups from 3.4 to 3.3
@ 2003-02-12 16:21 Kaveh R. Ghazi
  2003-02-12 17:05 ` Karel Gardas
  2003-02-12 22:08 ` Mike Stump
  0 siblings, 2 replies; 29+ messages in thread
From: Kaveh R. Ghazi @ 2003-02-12 16:21 UTC (permalink / raw)
  To: gcc

I've heard some mention that 3.4 is faster in some cases than 3.3.

I know several speedup tweeks have been made since the branch was
created.  Not all of them have been backported.

If they're not too invasive, let's consider them for 3.3.  I'm willing
to help by regtesting patches if people can point out safe candidates.
Though I'd certainly appreciate assistance from others. :-)

		Thanks,
		--Kaveh
--
Kaveh R. Ghazi			ghazi@caip.rutgers.edu

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2003-02-22  2:51 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-12 17:47 Let's backport speedups from 3.4 to 3.3 Kaoru Fukui
2003-02-12 21:07 ` Karel Gardas
2003-02-20 20:09 ` Mark Mitchell
2003-02-20 21:15   ` Kaveh R. Ghazi
2003-02-20 22:48     ` Mike Stump
2003-02-20 23:33       ` Mark Mitchell
2003-02-21  0:46       ` Zack Weinberg
2003-02-21  1:21         ` Mike Stump
2003-02-21  1:45       ` Kaveh R. Ghazi
2003-02-22  5:13         ` Mark Mitchell
2003-02-21  9:13     ` Gabriel Dos Reis
2003-02-21 15:13       ` Kaveh R. Ghazi
  -- strict thread matches above, loose matches on Subject: below --
2003-02-22  2:51 Kaoru Fukui
2003-02-21 18:02 Kaoru Fukui
2003-02-22  1:06 ` Kaveh R. Ghazi
     [not found] <6A8EF29C-3FA3-11D7-AFC7-003065A77310@apple.com>
2003-02-19 16:06 ` Karel Gardas
2003-02-12 21:53 Kaoru Fukui
2003-02-12 22:06 ` Karel Gardas
2003-02-12 22:11   ` Mike Stump
2003-02-12 22:23     ` Karel Gardas
2003-02-12 22:16   ` Karel Gardas
2003-02-13  0:31     ` Mike Stump
2003-02-13 22:31       ` Karel Gardas
2003-02-12 17:29 Kaoru Fukui
2003-02-12 17:29 Kaoru Fukui
2003-02-12 16:21 Kaveh R. Ghazi
2003-02-12 17:05 ` Karel Gardas
2003-02-12 22:08 ` Mike Stump
2003-02-13  2:43   ` Kaveh R. Ghazi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).