public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Committed] Use special-purpose hash table to speed up walk_tree
@ 2004-10-14 23:22 Matt Austern
  2004-10-14 23:24 ` Phil Edwards
  2004-10-16 10:17 ` Jakub Jelinek
  0 siblings, 2 replies; 20+ messages in thread
From: Matt Austern @ 2004-10-14 23:22 UTC (permalink / raw)
  To: GCC Patches

This patch isn't really as big as it looks.  walk_tree allows you to 
provide a hash table to keep track of which nodes have already been 
seen.  We were using htab_t, a general-purpose hash table with lots of 
knobs for the client to tweak.  This patch replaces it with a 
special-purpose hash table that has no more functionality than 
walk_tree needs.  In particular, this special-purpose hash table 
doesn't support deletion, doesn't give its client control over resizing 
policy, and doesn't allow its client to specify the hash function or 
equality function.  (It just uses the values of the pointers 
themselves.)

Bootstrapped and tested (C, C++, Java) on powerpc-apple-darwin.  This 
gives a 2% speedup on building QT.

Approved by Mark Mitchell offline.

			--Matt

Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.5888
diff -p -r2.5888 ChangeLog
*** ChangeLog	14 Oct 2004 22:30:37 -0000	2.5888
--- ChangeLog	14 Oct 2004 23:06:05 -0000
***************
*** 1,3 ****
--- 1,27 ----
+ 2004-10-14  Matt Austern  <austern@apple.com>
+
+ 	* pointer-set.c: New file, special-purpose hash table.
+ 	* pointer-set.h: New file.
+ 	* tree.h (struct pointer_set_t): Declare as opaque type.
+ 	(tree_walk): Last argument is pointer_set_t* now.
+ 	* tree-inline.c (WALK_SUBTREE): Convert from htab to pset.
+ 	(walk_type_fields):
+ 	(walk_tree): Convert from htab_t to pointer_set_t for keeping
+ 	track of which nodes have already been visited.
+ 	(walk_tree_without_duplicates): Convert from htab_t to pointer_set_t.
+ 	* cgraphunit.c (cgraph_create_edges): Likewise.
+ 	(cgraph_characterize_statics_local): Likewise.
+ 	* tree-dfa.c (collect_dfa_stats): Likewise.
+ 	* langhooks-def.h (lhd_tree_inlining_walk_subtrees): Last arg is
+ 	pointer_set_t* now.
+ 	* langhooks.c (lhd_tree_inlining_walk_subtrees): Likewise.
+ 	* langhooks.h (struct lang_hooks_for_tree_inlining): Last arg type
+ 	of walk_subtrees is pointer_set_t* now.
+ 	* Makefile.in (OBJS-common): add pointer-set.o
+ 	(tree-inline.o): Depends on pointer-set.h
+ 	(tree-dfa.o): Likewise
+ 	(cgraphunit.o): Likewise
+ 	
   2004-10-14  Geoffrey Keating  <geoffk@apple.com>

   	* config/rs6000/darwin.h (ASM_SPEC): Delete.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1410
diff -p -r1.1410 Makefile.in
*** Makefile.in	13 Oct 2004 03:48:01 -0000	1.1410
--- Makefile.in	14 Oct 2004 23:06:05 -0000
*************** OBJS-common = \
*** 914,920 ****
    params.o postreload.o postreload-gcse.o predict.o			   \
    insn-preds.o integrate.o intl.o jump.o langhooks.o lcm.o lists.o 	   
\
    local-alloc.o loop.o modulo-sched.o optabs.o options.o opts.o		   \
!  params.o postreload.o postreload-gcse.o predict.o			   \
    print-rtl.o print-tree.o value-prof.o var-tracking.o			   \
    profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o	   \
    real.o recog.o reg-stack.o regclass.o regmove.o regrename.o		   \
--- 914,920 ----
    params.o postreload.o postreload-gcse.o predict.o			   \
    insn-preds.o integrate.o intl.o jump.o langhooks.o lcm.o lists.o 	   
\
    local-alloc.o loop.o modulo-sched.o optabs.o options.o opts.o		   \
!  params.o pointer-set.o postreload.o postreload-gcse.o predict.o 	   \
    print-rtl.o print-tree.o value-prof.o var-tracking.o			   \
    profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o	   \
    real.o recog.o reg-stack.o regclass.o regmove.o regrename.o		   \
*************** tree-inline.o : tree-inline.c $(CONFIG_H
*** 1592,1598 ****
      $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h 
insn-config.h \
      $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
      langhooks.h $(C_COMMON_H) tree-inline.h $(CGRAPH_H) intl.h 
function.h \
!    $(TREE_GIMPLE_H)
   print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) $(TREE_H) \
      $(GGC_H) langhooks.h real.h
   stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) \
--- 1592,1598 ----
      $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h 
insn-config.h \
      $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
      langhooks.h $(C_COMMON_H) tree-inline.h $(CGRAPH_H) intl.h 
function.h \
!    pointer-set.h $(TREE_GIMPLE_H)
   print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) $(TREE_H) \
      $(GGC_H) langhooks.h real.h
   stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) \
*************** tree-iterator.o : tree-iterator.c $(CONF
*** 1686,1692 ****
      coretypes.h $(GGC_H) tree-iterator.h tree-gimple.h 
gt-tree-iterator.h
   tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
      $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h 
diagnostic.h \
!    errors.h tree-inline.h $(HASHTAB_H) $(FLAGS_H) function.h 
$(TIMEVAR_H) \
      convert.h $(TM_H) coretypes.h langhooks.h \
      $(TREE_DUMP_H) tree-pass.h params.h $(CGRAPH_H)
   tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
--- 1686,1692 ----
      coretypes.h $(GGC_H) tree-iterator.h tree-gimple.h 
gt-tree-iterator.h
   tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
      $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h 
diagnostic.h \
!    errors.h tree-inline.h $(HASHTAB_H) pointer-set.h $(FLAGS_H) 
function.h $(TIMEVAR_H) \
      convert.h $(TM_H) coretypes.h langhooks.h \
      $(TREE_DUMP_H) tree-pass.h params.h $(CGRAPH_H)
   tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
*************** cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM
*** 1923,1929 ****
      output.h intl.h
   cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) $(TREE_H) \
      langhooks.h tree-inline.h toplev.h $(FLAGS_H) $(GGC_H)  
$(TARGET_H) $(CGRAPH_H) intl.h \
!    function.h $(TREE_GIMPLE_H) $(TREE_FLOW_H)
   coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
\
      $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) 
function.h \
      toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h 
\
--- 1923,1929 ----
      output.h intl.h
   cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
$(TM_H) $(TREE_H) \
      langhooks.h tree-inline.h toplev.h $(FLAGS_H) $(GGC_H)  
$(TARGET_H) $(CGRAPH_H) intl.h \
!    pointer-set.h function.h $(TREE_GIMPLE_H) $(TREE_FLOW_H)
   coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h 
\
      $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) 
function.h \
      toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h 
\
*************** lambda-code.o: lambda-code.c $(LAMBDA_H)
*** 2172,2177 ****
--- 2172,2178 ----
      $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) cfgloop.h \
      $(TREE_DATA_REF_H) $(SCEV_H)
   params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) 
$(PARAMS_H) toplev.h
+ pointer-set.o: pointer-set.c pointer-set.h $(CONFIG_H) $(SYSTEM_H)
   hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) 
$(HOOKS_H)
   pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h 
$(PRETTY_PRINT_H) \
      $(TREE_H)
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.86
diff -p -r1.86 cgraphunit.c
*** cgraphunit.c	1 Oct 2004 15:11:10 -0000	1.86
--- cgraphunit.c	14 Oct 2004 23:06:06 -0000
*************** Software Foundation, 59 Temple Place - S
*** 186,192 ****
   #include "tree-flow.h"
   #include "tree-inline.h"
   #include "langhooks.h"
! #include "hashtab.h"
   #include "toplev.h"
   #include "flags.h"
   #include "ggc.h"
--- 186,192 ----
   #include "tree-flow.h"
   #include "tree-inline.h"
   #include "langhooks.h"
! #include "pointer-set.h"
   #include "toplev.h"
   #include "flags.h"
   #include "ggc.h"
*************** static int overall_insns;
*** 223,229 ****
      walk_tree_without_duplicates doesn't guarantee each node is visited
      once because it gets a new htab upon each recursive call from
      record_calls_1.  */
! static htab_t visited_nodes;

   static FILE *cgraph_dump_file;

--- 223,229 ----
      walk_tree_without_duplicates doesn't guarantee each node is visited
      once because it gets a new htab upon each recursive call from
      record_calls_1.  */
! static struct pointer_set_t *visited_nodes;

   static FILE *cgraph_dump_file;

*************** cgraph_create_edges (struct cgraph_node
*** 698,707 ****
   {
     /* The nodes we're interested in are never shared, so walk
        the tree ignoring duplicates.  */
!   visited_nodes = htab_create (37, htab_hash_pointer,
! 				    htab_eq_pointer, NULL);
     walk_tree (&body, record_call_1, node, visited_nodes);
!   htab_delete (visited_nodes);
     visited_nodes = NULL;
   }

--- 698,706 ----
   {
     /* The nodes we're interested in are never shared, so walk
        the tree ignoring duplicates.  */
!   visited_nodes = pointer_set_create ();
     walk_tree (&body, record_call_1, node, visited_nodes);
!   pointer_set_destroy (visited_nodes);
     visited_nodes = NULL;
   }

*************** cgraph_characterize_statics_local (struc
*** 2288,2295 ****

     /* The nodes we're interested in are never shared, so walk
        the tree ignoring duplicates.  */
!   visited_nodes = htab_create (37, htab_hash_pointer,
! 			       htab_eq_pointer, NULL);

     /* FIXME -- PROFILE-RESTRUCTURE: Remove creation of _decl_uid vars. 
  */
     l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
--- 2287,2293 ----

     /* The nodes we're interested in are never shared, so walk
        the tree ignoring duplicates.  */
!   visited_nodes = pointer_set_create ();

     /* FIXME -- PROFILE-RESTRUCTURE: Remove creation of _decl_uid vars. 
  */
     l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
*************** cgraph_characterize_statics_local (struc
*** 2299,2305 ****
       fprintf (cgraph_dump_file, "\n local analysis of %s", 
cgraph_node_name (fn));

     walk_tree (&DECL_SAVED_TREE (decl), scan_for_static_refs, fn, 
visited_nodes);
!   htab_delete (visited_nodes);
     visited_nodes = NULL;
   }

--- 2297,2303 ----
       fprintf (cgraph_dump_file, "\n local analysis of %s", 
cgraph_node_name (fn));

     walk_tree (&DECL_SAVED_TREE (decl), scan_for_static_refs, fn, 
visited_nodes);
!   pointer_set_destroy (visited_nodes);
     visited_nodes = NULL;
   }

Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.93
diff -p -r1.93 langhooks-def.h
*** langhooks-def.h	15 Sep 2004 17:02:55 -0000	1.93
--- langhooks-def.h	14 Oct 2004 23:06:06 -0000
*************** extern size_t lhd_tree_size (enum tree_c
*** 73,79 ****

   /* Declarations of default tree inlining hooks.  */
   extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, 
walk_tree_fn,
! 					     void *, void *);
   extern int lhd_tree_inlining_cannot_inline_tree_fn (tree *);
   extern int lhd_tree_inlining_disregard_inline_limits (tree);
   extern tree lhd_tree_inlining_add_pending_fn_decls (void *, tree);
--- 73,79 ----

   /* Declarations of default tree inlining hooks.  */
   extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, 
walk_tree_fn,
! 					     void *, struct pointer_set_t*);
   extern int lhd_tree_inlining_cannot_inline_tree_fn (tree *);
   extern int lhd_tree_inlining_disregard_inline_limits (tree);
   extern tree lhd_tree_inlining_add_pending_fn_decls (void *, tree);
Index: langhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.c,v
retrieving revision 1.78
diff -p -r1.78 langhooks.c
*** langhooks.c	17 Sep 2004 21:54:35 -0000	1.78
--- langhooks.c	14 Oct 2004 23:06:06 -0000
*************** lhd_tree_inlining_walk_subtrees (tree *t
*** 298,304 ****
   				 int *subtrees ATTRIBUTE_UNUSED,
   				 walk_tree_fn func ATTRIBUTE_UNUSED,
   				 void *data ATTRIBUTE_UNUSED,
! 				 void *htab ATTRIBUTE_UNUSED)
   {
     return NULL_TREE;
   }
--- 298,304 ----
   				 int *subtrees ATTRIBUTE_UNUSED,
   				 walk_tree_fn func ATTRIBUTE_UNUSED,
   				 void *data ATTRIBUTE_UNUSED,
! 				 struct pointer_set_t *pset ATTRIBUTE_UNUSED)
   {
     return NULL_TREE;
   }
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.101
diff -p -r1.101 langhooks.h
*** langhooks.h	17 Sep 2004 21:54:35 -0000	1.101
--- langhooks.h	14 Oct 2004 23:06:06 -0000
*************** struct lang_hooks_for_tree_inlining
*** 35,41 ****
   {
     tree (*walk_subtrees) (tree *, int *,
   			 tree (*) (tree *, int *, void *),
! 			 void *, void *);
     int (*cannot_inline_tree_fn) (tree *);
     int (*disregard_inline_limits) (tree);
     tree (*add_pending_fn_decls) (void *, tree);
--- 35,41 ----
   {
     tree (*walk_subtrees) (tree *, int *,
   			 tree (*) (tree *, int *, void *),
! 			 void *, struct pointer_set_t*);
     int (*cannot_inline_tree_fn) (tree *);
     int (*disregard_inline_limits) (tree);
     tree (*add_pending_fn_decls) (void *, tree);
Index: pointer-set.c
===================================================================
RCS file: pointer-set.c
diff -N pointer-set.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- pointer-set.c	14 Oct 2004 23:06:06 -0000
***************
*** 0 ****
--- 1,167 ----
+ /* Set operations on pointers
+    Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+
+ #include "config.h"
+ #include "system.h"
+ #include "pointer-set.h"
+
+ /* A pointer sets is represented as a simple open-addressing hash
+    table.  Simplifications: The hash code is based on the value of the
+    pointer, not what it points to.  The number of buckets is always a
+    power of 2.  Null pointers are a reserved value.  Deletion is not
+    supported.  There is no mechanism for user control of hash
+    function, equality comparison, initial size, or resizing policy.
+ */
+
+ struct pointer_set_t
+ {
+   size_t log_slots;
+   size_t n_slots;		/* n_slots = 2^log_slots */
+   size_t n_elements;
+
+   void **slots;
+ };
+
+ /* Use the multiplicative method, as described in Knuth 6.4, to obtain
+    a hash code for P in the range [0, MAX).  MAX == 2^LOGMAX.
+
+    Summary of this method: Multiply p by some number A that's
+    relatively prime to 2^sizeof(size_t).  The result is two words.
+    Discard the most significant word, and return the most significant
+    N bits of the least significant word.  As suggested by Knuth, our
+    choice for A is the integer part of 2^32 / phi, where phi is the
+    golden ratio.
+
+    We don't need to do anything special for full-width multiplication
+    because we're only interested in the least significant word of the
+    product, and unsigned arithmetic in C is modulo the word size. */
+
+ static inline size_t
+ hash1 (const void *p, unsigned long max, unsigned long logmax)
+ {
+   const unsigned long A = 0x9e3779b9u;
+   const unsigned long shift = sizeof(unsigned long) * CHAR_BIT - 
logmax;
+
+   return ((A * (unsigned long) p) >> shift) & (max - 1);
+ }
+
+ /* Allocate an empty pointer set. */
+ struct pointer_set_t *
+ pointer_set_create (void)
+ {
+   struct pointer_set_t *result = XNEW (struct pointer_set_t);
+
+   result->n_elements = 0;
+   result->log_slots = 8;
+   result->n_slots = (size_t) 1 << result->log_slots;
+
+   result->slots = XCNEWVEC (void *, result->n_slots);
+   return result;
+ }
+
+ /* Reclaims all memory associated with PSET. */
+ void pointer_set_destroy (struct pointer_set_t *pset)
+ {
+   XDELETEVEC (pset->slots);
+   XDELETE (pset);
+ }
+
+ /* Returns nonzero if PSET contains P.  P must be nonnull.
+
+    Collisions are resolved by linear probing.  More complicated
+    collision management schemes are only useful when the load factor
+    significatly exceeds 0.5, and we never let that happen. */
+ int
+ pointer_set_contains (struct pointer_set_t *pset, void *p)
+ {
+   size_t n = hash1 (p, pset->n_slots, pset->log_slots);
+
+   while (true)
+     {
+       if (pset->slots[n] == p)
+ 	return 1;
+       else if (pset->slots[n] == 0)
+ 	return 0;
+       else
+ 	{
+ 	  ++n;
+ 	  if (n == pset->n_slots)
+ 	    n = 0;
+ 	}
+     }
+ }
+
+ /* Subroutine of pointer_set_insert.  Inserts P into an empty
+    element of SLOTS, an array of length N_SLOTS.  Returns nonzero
+    if P was already present in N_SLOTS. */
+ static int
+ insert_aux (void *p, void **slots, size_t n_slots, size_t log_slots)
+ {
+   size_t n = hash1 (p, n_slots, log_slots);
+   while (true)
+     {
+       if (slots[n] == p)
+ 	return 1;
+       else if (slots[n] == 0)
+ 	{
+ 	  slots[n] = p;
+ 	  return 0;
+ 	}
+       else
+ 	{
+ 	  ++n;
+ 	  if (n == n_slots)
+ 	    n = 0;
+ 	}
+     }
+ }
+
+ /* Inserts P into PSET if it wasn't already there.  Returns nonzero
+    if it was already there. P must be nonnull. */
+ int
+ pointer_set_insert (struct pointer_set_t *pset, void *p)
+ {
+   if (insert_aux (p, pset->slots, pset->n_slots, pset->log_slots))
+     return 1;
+
+   /* We've inserted a new element.  Expand the table if necessary to 
keep
+      the load factor small. */
+   ++pset->n_elements;
+   if (pset->n_elements > pset->n_slots / 4)
+     {
+       size_t new_log_slots = pset->log_slots + 1;
+       size_t new_n_slots = pset->n_slots * 2;
+       void **new_slots = XCNEWVEC (void *, new_n_slots);
+       size_t i;
+
+       for (i = 0; i < pset->n_slots; ++i)
+ 	{
+ 	  if (pset->slots[i])
+ 	    insert_aux (pset->slots[i], new_slots, new_n_slots, 
new_log_slots);
+ 	}
+
+       XDELETEVEC (pset->slots);
+       pset->n_slots = new_n_slots;
+       pset->log_slots = new_log_slots;
+       pset->slots = new_slots;
+     }
+
+   return 0;
+ }
Index: pointer-set.h
===================================================================
RCS file: pointer-set.h
diff -N pointer-set.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- pointer-set.h	14 Oct 2004 23:06:06 -0000
***************
*** 0 ****
--- 1,32 ----
+ /* Set operations on pointers
+    Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+
+ #ifndef POINTER_SET_H
+ #define POINTER_SET_H
+
+ struct pointer_set_t;
+
+ struct pointer_set_t *pointer_set_create (void);
+ void pointer_set_destroy (struct pointer_set_t *pset);
+
+ int pointer_set_contains (struct pointer_set_t *pset, void *p);
+ int pointer_set_insert (struct pointer_set_t *pset, void *p);
+
+ #endif  /* POINTER_SET_H  */
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v
retrieving revision 2.36
diff -p -r2.36 tree-dfa.c
*** tree-dfa.c	30 Sep 2004 14:09:37 -0000	2.36
--- tree-dfa.c	14 Oct 2004 23:06:06 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 24,29 ****
--- 24,30 ----
   #include "coretypes.h"
   #include "tm.h"
   #include "hashtab.h"
+ #include "pointer-set.h"
   #include "tree.h"
   #include "rtl.h"
   #include "tm_p.h"
*************** debug_dfa_stats (void)
*** 759,765 ****
   static void
   collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
   {
!   htab_t htab;
     basic_block bb;
     block_stmt_iterator i;

--- 760,766 ----
   static void
   collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
   {
!   struct pointer_set_t *pset;
     basic_block bb;
     block_stmt_iterator i;

*************** collect_dfa_stats (struct dfa_stats_d *d
*** 769,781 ****

     /* Walk all the trees in the function counting references.  Start at
        basic block 0, but don't stop at block boundaries.  */
!   htab = htab_create (30, htab_hash_pointer, htab_eq_pointer, NULL);

     for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i))
       walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) 
dfa_stats_p,
! 	       (void *) htab);

!   htab_delete (htab);

     FOR_EACH_BB (bb)
       {
--- 770,782 ----

     /* Walk all the trees in the function counting references.  Start at
        basic block 0, but don't stop at block boundaries.  */
!   pset = pointer_set_create ();

     for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i))
       walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) 
dfa_stats_p,
! 	       pset);

!   pointer_set_destroy (pset);

     FOR_EACH_BB (bb)
       {
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.145
diff -p -r1.145 tree-inline.c
*** tree-inline.c	7 Oct 2004 08:36:15 -0000	1.145
--- tree-inline.c	14 Oct 2004 23:06:06 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 35,40 ****
--- 35,41 ----
   #include "integrate.h"
   #include "varray.h"
   #include "hashtab.h"
+ #include "pointer-set.h"
   #include "splay-tree.h"
   #include "langhooks.h"
   #include "cgraph.h"
*************** save_body (tree fn, tree *arg_copy, tree
*** 1877,1883 ****
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, htab);	\
         if (result)					\
   	return result;					\
       }							\
--- 1878,1884 ----
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, pset);	\
         if (result)					\
   	return result;					\
       }							\
*************** save_body (tree fn, tree *arg_copy, tree
*** 1888,1894 ****
      value are as for walk_tree.  */

   static tree
! walk_type_fields (tree type, walk_tree_fn func, void *data, void 
*htab)
   {
     tree result = NULL_TREE;

--- 1889,1896 ----
      value are as for walk_tree.  */

   static tree
! walk_type_fields (tree type, walk_tree_fn func, void *data,
! 		  struct pointer_set_t *pset)
   {
     tree result = NULL_TREE;

*************** walk_type_fields (tree type, walk_tree_f
*** 1906,1912 ****
         if (POINTER_TYPE_P (TREE_TYPE (type))
   	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
   	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
! 	  && !htab)
   	{
   	  result = walk_tree_without_duplicates (&TREE_TYPE (type),
   						 func, data);
--- 1908,1914 ----
         if (POINTER_TYPE_P (TREE_TYPE (type))
   	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
   	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
! 	  && !pset)
   	{
   	  result = walk_tree_without_duplicates (&TREE_TYPE (type),
   						 func, data);
*************** walk_type_fields (tree type, walk_tree_f
*** 1971,1983 ****
   /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.  
FUNC is
      called with the DATA and the address of each sub-tree.  If FUNC 
returns a
      non-NULL value, the traversal is aborted, and the value returned 
by FUNC
!    is returned.  If HTAB is non-NULL it is used to record the nodes 
visited,
      and to avoid visiting a node more than once.  */

   tree
! walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
   {
-   htab_t htab = (htab_t) htab_;
     enum tree_code code;
     int walk_subtrees;
     tree result;
--- 1973,1984 ----
   /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.  
FUNC is
      called with the DATA and the address of each sub-tree.  If FUNC 
returns a
      non-NULL value, the traversal is aborted, and the value returned 
by FUNC
!    is returned.  If PSET is non-NULL it is used to record the nodes 
visited,
      and to avoid visiting a node more than once.  */

   tree
! walk_tree (tree *tp, walk_tree_fn func, void *data, struct 
pointer_set_t *pset)
   {
     enum tree_code code;
     int walk_subtrees;
     tree result;
*************** walk_tree (tree *tp, walk_tree_fn func,
*** 1995,2011 ****
     if (!*tp)
       return NULL_TREE;

!   if (htab)
!     {
!       void **slot;
!
!       /* Don't walk the same tree twice, if the user has requested
!          that we avoid doing so.  */
!       slot = htab_find_slot (htab, *tp, INSERT);
!       if (*slot)
! 	return NULL_TREE;
!       *slot = *tp;
!     }

     /* Call the function.  */
     walk_subtrees = 1;
--- 1996,2005 ----
     if (!*tp)
       return NULL_TREE;

!   /* Don't walk the same tree twice, if the user has requested
!      that we avoid doing so.  */
!   if (pset && pointer_set_insert (pset, *tp))
!     return NULL_TREE;

     /* Call the function.  */
     walk_subtrees = 1;
*************** walk_tree (tree *tp, walk_tree_fn func,
*** 2029,2035 ****
       }

     result = lang_hooks.tree_inlining.walk_subtrees (tp, 
&walk_subtrees, func,
! 						   data, htab);
     if (result || ! walk_subtrees)
       return result;

--- 2023,2029 ----
       }

     result = lang_hooks.tree_inlining.walk_subtrees (tp, 
&walk_subtrees, func,
! 						   data, pset);
     if (result || ! walk_subtrees)
       return result;

*************** walk_tree (tree *tp, walk_tree_fn func,
*** 2053,2059 ****
         if (result || !walk_subtrees)
   	return NULL_TREE;

!       result = walk_type_fields (*type_p, func, data, htab_);
         if (result)
   	return result;

--- 2047,2053 ----
         if (result || !walk_subtrees)
   	return NULL_TREE;

!       result = walk_type_fields (*type_p, func, data, pset);
         if (result)
   	return result;

*************** walk_tree (tree *tp, walk_tree_fn func,
*** 2124,2130 ****
     /* If this is a type, walk the needed fields in the type.  */
     else if (TYPE_P (*tp))
       {
!       result = walk_type_fields (*tp, func, data, htab_);
         if (result)
   	return result;
       }
--- 2118,2124 ----
     /* If this is a type, walk the needed fields in the type.  */
     else if (TYPE_P (*tp))
       {
!       result = walk_type_fields (*tp, func, data, pset);
         if (result)
   	return result;
       }
*************** tree
*** 2227,2237 ****
   walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
   {
     tree result;
!   htab_t htab;

!   htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
!   result = walk_tree (tp, func, data, htab);
!   htab_delete (htab);
     return result;
   }

--- 2221,2231 ----
   walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
   {
     tree result;
!   struct pointer_set_t *pset;

!   pset = pointer_set_create ();
!   result = walk_tree (tp, func, data, pset);
!   pointer_set_destroy (pset);
     return result;
   }

Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.638
diff -p -r1.638 tree.h
*** tree.h	14 Oct 2004 16:44:43 -0000	1.638
--- tree.h	14 Oct 2004 23:06:06 -0000
*************** extern void dwarf2out_return_reg (const
*** 3790,3799 ****

   /* In tree-inline.c  */

   /* The type of a callback function for walking over tree structure.  
*/

   typedef tree (*walk_tree_fn) (tree *, int *, void *);
! extern tree walk_tree (tree*, walk_tree_fn, void*, void*);
   extern tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);

   /* In tree-dump.c */
--- 3790,3803 ----

   /* In tree-inline.c  */

+ /* The type of a set of already-visited pointers.  Functions for 
creating
+    and manipulating it are declared in pointer-set.h */
+ struct pointer_set_t;
+
   /* The type of a callback function for walking over tree structure.  
*/

   typedef tree (*walk_tree_fn) (tree *, int *, void *);
! extern tree walk_tree (tree*, walk_tree_fn, void*, struct 
pointer_set_t*);
   extern tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);

   /* In tree-dump.c */
Index: cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.4432
diff -p -r1.4432 ChangeLog
*** cp/ChangeLog	13 Oct 2004 17:18:08 -0000	1.4432
--- cp/ChangeLog	14 Oct 2004 23:06:07 -0000
***************
*** 1,3 ****
--- 1,11 ----
+ 2004-10-14  Matt Austern  <austern@apple.com>
+
+ 	* Make-lang.in (pt.o): depends on pointer-set.h
+ 	* cp-tree.h (cp_walk_subtrees): Last argument is pointer_set_t*	now.
+ 	* pt.c (struct pair_fn_data): Use pointer_set_t, not htab_t
+ 	(for_each_template_parm): Convert from htab_t to pointer_set_t.
+ 	* tree.c (cp_walk_subtrees): Last argument is pointer_set_t* now.
+ 	
   2004-10-13  Andrew Pinski  <pinskia@physics.uc.edu>

   	PR c++/17661
Index: cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.194
diff -p -r1.194 Make-lang.in
*** cp/Make-lang.in	9 Sep 2004 22:53:51 -0000	1.194
--- cp/Make-lang.in	14 Oct 2004 23:06:07 -0000
*************** cp/except.o: cp/except.c $(CXX_TREE_H) $
*** 260,266 ****
   cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) 
toplev.h \
     except.h $(TM_P_H)
   cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h \
!   toplev.h $(RTL_H) except.h tree-inline.h gt-cp-pt.h
   cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) 
\
     flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H)
   cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \
--- 260,266 ----
   cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) 
toplev.h \
     except.h $(TM_P_H)
   cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h \
!   toplev.h $(RTL_H) except.h tree-inline.h pointer-set.h gt-cp-pt.h
   cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) 
\
     flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H)
   cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1062
diff -p -r1.1062 cp-tree.h
*** cp/cp-tree.h	11 Oct 2004 22:49:59 -0000	1.1062
--- cp/cp-tree.h	14 Oct 2004 23:06:07 -0000
*************** extern void verify_stmt_tree
*** 4215,4221 ****
   extern tree find_tree                           (tree, tree);
   extern linkage_kind decl_linkage                (tree);
   extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
! 				      void*, void*);
   extern int cp_cannot_inline_tree_fn (tree*);
   extern tree cp_add_pending_fn_decls (void*,tree);
   extern int cp_is_overload_p (tree);
--- 4215,4221 ----
   extern tree find_tree                           (tree, tree);
   extern linkage_kind decl_linkage                (tree);
   extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
! 				      void*, struct pointer_set_t*);
   extern int cp_cannot_inline_tree_fn (tree*);
   extern tree cp_add_pending_fn_decls (void*,tree);
   extern int cp_is_overload_p (tree);
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.935
diff -p -r1.935 pt.c
*** cp/pt.c	11 Oct 2004 22:50:00 -0000	1.935
--- cp/pt.c	14 Oct 2004 23:06:07 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 32,37 ****
--- 32,38 ----
   #include "tm.h"
   #include "obstack.h"
   #include "tree.h"
+ #include "pointer-set.h"
   #include "flags.h"
   #include "cp-tree.h"
   #include "tree-inline.h"
*************** static tree convert_nontype_argument (tr
*** 113,119 ****
   static tree convert_template_argument (tree, tree, tree,
   				       tsubst_flags_t, int, tree);
   static tree get_bindings_overload (tree, tree, tree);
! static int for_each_template_parm (tree, tree_fn_t, void*, htab_t);
   static tree build_template_parm_index (int, int, int, tree, tree);
   static int inline_needs_template_parms (tree);
   static void push_inline_template_parms_recursive (tree, int);
--- 114,121 ----
   static tree convert_template_argument (tree, tree, tree,
   				       tsubst_flags_t, int, tree);
   static tree get_bindings_overload (tree, tree, tree);
! static int for_each_template_parm (tree, tree_fn_t, void*,
! 				   struct pointer_set_t*);
   static tree build_template_parm_index (int, int, int, tree, tree);
   static int inline_needs_template_parms (tree);
   static void push_inline_template_parms_recursive (tree, int);
*************** struct pair_fn_data
*** 4683,4689 ****
   {
     tree_fn_t fn;
     void *data;
!   htab_t visited;
   };

   /* Called from for_each_template_parm via walk_tree.  */
--- 4685,4691 ----
   {
     tree_fn_t fn;
     void *data;
!   struct pointer_set_t *visited;
   };

   /* Called from for_each_template_parm via walk_tree.  */
*************** for_each_template_parm_r (tree *tp, int
*** 4865,4871 ****
      considered to be the function which always returns 1.  */

   static int
! for_each_template_parm (tree t, tree_fn_t fn, void* data, htab_t 
visited)
   {
     struct pair_fn_data pfd;
     int result;
--- 4867,4874 ----
      considered to be the function which always returns 1.  */

   static int
! for_each_template_parm (tree t, tree_fn_t fn, void* data,
! 			struct pointer_set_t *visited)
   {
     struct pair_fn_data pfd;
     int result;
*************** for_each_template_parm (tree t, tree_fn_
*** 4882,4889 ****
     if (visited)
       pfd.visited = visited;
     else
!     pfd.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer,
! 			       NULL);
     result = walk_tree (&t,
   		      for_each_template_parm_r,
   		      &pfd,
--- 4885,4891 ----
     if (visited)
       pfd.visited = visited;
     else
!     pfd.visited = pointer_set_create ();
     result = walk_tree (&t,
   		      for_each_template_parm_r,
   		      &pfd,
*************** for_each_template_parm (tree t, tree_fn_
*** 4891,4897 ****

     /* Clean up.  */
     if (!visited)
!     htab_delete (pfd.visited);

     return result;
   }
--- 4893,4902 ----

     /* Clean up.  */
     if (!visited)
!     {
!       pointer_set_destroy (pfd.visited);
!       pfd.visited = 0;
!     }

     return result;
   }
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.416
diff -p -r1.416 tree.c
*** cp/tree.c	11 Oct 2004 15:38:23 -0000	1.416
--- cp/tree.c	14 Oct 2004 23:06:08 -0000
*************** cp_build_type_attribute_variant (tree ty
*** 1929,1935 ****

   tree
   cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
! 		  void *data, void *htab)
   {
     enum tree_code code = TREE_CODE (*tp);
     location_t save_locus;
--- 1929,1935 ----

   tree
   cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
! 		  void *data, struct pointer_set_t *pset)
   {
     enum tree_code code = TREE_CODE (*tp);
     location_t save_locus;
*************** cp_walk_subtrees (tree *tp, int *walk_su
*** 1938,1944 ****
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, htab);	\
         if (result) goto out;				\
       }							\
     while (0)
--- 1938,1944 ----
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, pset);	\
         if (result) goto out;				\
       }							\
     while (0)
Index: java/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/ChangeLog,v
retrieving revision 1.1483
diff -p -r1.1483 ChangeLog
*** java/ChangeLog	13 Oct 2004 17:04:55 -0000	1.1483
--- java/ChangeLog	14 Oct 2004 23:06:09 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2004-10-14  Matt Austern  <austern@apple.com>
+
+ 	* lang.c (java_tree_inlining_walk_subtrees): Last arg is struct
+ 	pointer_set_t* now.
+ 	
   2004-10-13  Tom Tromey  <tromey@redhat.com>

   	PR java/15578:
Index: java/lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.160
diff -p -r1.160 lang.c
*** java/lang.c	30 Sep 2004 02:16:46 -0000	1.160
--- java/lang.c	14 Oct 2004 23:06:09 -0000
*************** static void put_decl_string (const char
*** 58,64 ****
   static void put_decl_node (tree);
   static void java_print_error_function (diagnostic_context *, const 
char *);
   static tree java_tree_inlining_walk_subtrees (tree *, int *, 
walk_tree_fn,
! 					      void *, void *);
   static int merge_init_test_initialization (void * *, void *);
   static int inline_init_test_initialization (void * *, void *);
   static bool java_can_use_bit_fields_p (void);
--- 58,64 ----
   static void put_decl_node (tree);
   static void java_print_error_function (diagnostic_context *, const 
char *);
   static tree java_tree_inlining_walk_subtrees (tree *, int *, 
walk_tree_fn,
! 					      void *, struct pointer_set_t *);
   static int merge_init_test_initialization (void * *, void *);
   static int inline_init_test_initialization (void * *, void *);
   static bool java_can_use_bit_fields_p (void);
*************** java_tree_inlining_walk_subtrees (tree *
*** 706,712 ****
   				  int *subtrees ATTRIBUTE_UNUSED,
   				  walk_tree_fn func ATTRIBUTE_UNUSED,
   				  void *data ATTRIBUTE_UNUSED,
! 				  void *htab ATTRIBUTE_UNUSED)
   {
     enum tree_code code;
     tree result;
--- 706,712 ----
   				  int *subtrees ATTRIBUTE_UNUSED,
   				  walk_tree_fn func ATTRIBUTE_UNUSED,
   				  void *data ATTRIBUTE_UNUSED,
! 				  struct pointer_set_t *pset ATTRIBUTE_UNUSED)
   {
     enum tree_code code;
     tree result;
*************** java_tree_inlining_walk_subtrees (tree *
*** 714,720 ****
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, htab);	\
         if (result)					\
   	return result;					\
       }							\
--- 714,720 ----
   #define WALK_SUBTREE(NODE)				\
     do							\
       {							\
!       result = walk_tree (&(NODE), func, data, pset);	\
         if (result)					\
   	return result;					\
       }							\

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-14 23:22 [Committed] Use special-purpose hash table to speed up walk_tree Matt Austern
@ 2004-10-14 23:24 ` Phil Edwards
  2004-10-15  0:04   ` Matt Austern
  2004-10-16 10:17 ` Jakub Jelinek
  1 sibling, 1 reply; 20+ messages in thread
From: Phil Edwards @ 2004-10-14 23:24 UTC (permalink / raw)
  To: Matt Austern; +Cc: gcc-patches

On Thu, Oct 14, 2004 at 04:15:44PM -0700, Matt Austern wrote:
> + /* A pointer sets is represented as a simple open-addressing hash

Grammar typo, s/sets/set/, surely?

-- 
Behind everything some further thing is found, forever; thus the tree behind
the bird, stone beneath soil, the sun behind Urth.  Behind our efforts, let
there be found our efforts.
              - Ascian saying, as related by Loyal to the Group of Seventeen

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-14 23:24 ` Phil Edwards
@ 2004-10-15  0:04   ` Matt Austern
  0 siblings, 0 replies; 20+ messages in thread
From: Matt Austern @ 2004-10-15  0:04 UTC (permalink / raw)
  To: Phil Edwards; +Cc: gcc-patches

On Oct 14, 2004, at 4:21 PM, Phil Edwards wrote:

> On Thu, Oct 14, 2004 at 04:15:44PM -0700, Matt Austern wrote:
>> + /* A pointer sets is represented as a simple open-addressing hash
>
> Grammar typo, s/sets/set/, surely?

Oops.

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-14 23:22 [Committed] Use special-purpose hash table to speed up walk_tree Matt Austern
  2004-10-14 23:24 ` Phil Edwards
@ 2004-10-16 10:17 ` Jakub Jelinek
  2004-10-16 10:37   ` Steven Bosscher
                     ` (2 more replies)
  1 sibling, 3 replies; 20+ messages in thread
From: Jakub Jelinek @ 2004-10-16 10:17 UTC (permalink / raw)
  To: Matt Austern; +Cc: GCC Patches

On Thu, Oct 14, 2004 at 04:15:44PM -0700, Matt Austern wrote:
> This patch isn't really as big as it looks.  walk_tree allows you to 
> provide a hash table to keep track of which nodes have already been 
> seen.  We were using htab_t, a general-purpose hash table with lots of 
> knobs for the client to tweak.  This patch replaces it with a 
> special-purpose hash table that has no more functionality than 
> walk_tree needs.  In particular, this special-purpose hash table 
> doesn't support deletion, doesn't give its client control over resizing 
> policy, and doesn't allow its client to specify the hash function or 
> equality function.  (It just uses the values of the pointers 
> themselves.)
> 
> Bootstrapped and tested (C, C++, Java) on powerpc-apple-darwin.  This 
> gives a 2% speedup on building QT.

But on x86-64-redhat-linux essentially makes even bootstrap impossible
(well, I have killed it after it spent more than 10 minutes compiling
insn-recog or insn-attrtab by stage1/cc1).
hash1's distribution is less than perfect.

I have gathered statistics taken from the hash table at a random time
I Ctrl-C cc1 compiling insn-recog.c.

{log_slots = 16, n_slots = 65536, n_elements = 16385, slots = 0x2a9b261010}
average chain length 7991
hash 21703 count 887
hash 21705 count 882
hash 21704 count 856
hash 21706 count 817
hash 21702 count 780
hash 21696 count 726
hash 21686 count 722
hash 21693 count 709
hash 21689 count 695
hash 21690 count 692
hash 21695 count 686
hash 21697 count 680
hash 21691 count 666
hash 21684 count 653
hash 21687 count 650
hash 21685 count 633
hash 21694 count 607
hash 21692 count 588
hash 21688 count 571
hash 21698 count 541
hash 21683 count 539
hash 21681 count 522
hash 21682 count 520
hash 21680 count 324
hash 21701 count 183
hash 21699 count 41
hash 21343 count 31
hash 21342 count 24
hash 21707 count 22
hash 21346 count 16
hash 21249 count 16
hash 21344 count 14
hash 21315 count 11
all others count 81

The hash table contains 21249 NULLs, then full slots (with a couple
of NULLs near the beginning, but only a few), and from slot 37875
onwards till the end of the hash table there are NULLs again.

Shouldn't we multiply by 2^64 / phi instead of 2^32 / phi when
long is 64-bit?

	Jakub

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:17 ` Jakub Jelinek
@ 2004-10-16 10:37   ` Steven Bosscher
  2004-10-17  8:30     ` Mark Mitchell
  2004-10-16 10:42   ` Jakub Jelinek
  2004-10-16 18:14   ` Matt Austern
  2 siblings, 1 reply; 20+ messages in thread
From: Steven Bosscher @ 2004-10-16 10:37 UTC (permalink / raw)
  To: Jakub Jelinek, Matt Austern, mark; +Cc: GCC Patches

On Saturday 16 October 2004 11:47, Jakub Jelinek wrote:
> On Thu, Oct 14, 2004 at 04:15:44PM -0700, Matt Austern wrote:
> > This patch isn't really as big as it looks.  walk_tree allows you to
> > provide a hash table to keep track of which nodes have already been
> > seen.  We were using htab_t, a general-purpose hash table with lots of
> > knobs for the client to tweak.  This patch replaces it with a
> > special-purpose hash table that has no more functionality than
> > walk_tree needs.  In particular, this special-purpose hash table
> > doesn't support deletion, doesn't give its client control over resizing
> > policy, and doesn't allow its client to specify the hash function or
> > equality function.  (It just uses the values of the pointers
> > themselves.)
> >
> > Bootstrapped and tested (C, C++, Java) on powerpc-apple-darwin.  This
> > gives a 2% speedup on building QT.
>
> But on x86-64-redhat-linux essentially makes even bootstrap impossible
> (well, I have killed it after it spent more than 10 minutes compiling
> insn-recog or insn-attrtab by stage1/cc1).
> hash1's distribution is less than perfect.

Ah, I was wondering why my bootstrap was so slow recently :-)

It would have been nice if this patch had been tested better.  Good
for you, 2% on QT, but what are the effects on other code?  And are
we in stage3 now or not?  I did not see this idea on Mark's list of
things that would be allowed in.

And why did Mark approve this offline, isn't it the policy that a
patch is posted to gcc-patches and reviewed in public?

Gr.
Steven



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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:17 ` Jakub Jelinek
  2004-10-16 10:37   ` Steven Bosscher
@ 2004-10-16 10:42   ` Jakub Jelinek
  2004-10-16 11:49     ` Jakub Jelinek
                       ` (2 more replies)
  2004-10-16 18:14   ` Matt Austern
  2 siblings, 3 replies; 20+ messages in thread
From: Jakub Jelinek @ 2004-10-16 10:42 UTC (permalink / raw)
  To: Matt Austern; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 444 bytes --]

On Sat, Oct 16, 2004 at 05:47:08AM -0400, Jakub Jelinek wrote:
> But on x86-64-redhat-linux essentially makes even bootstrap impossible
> (well, I have killed it after it spent more than 10 minutes compiling
> insn-recog or insn-attrtab by stage1/cc1).
> hash1's distribution is less than perfect.

For the hash function I'm trying these patches now:

(both do the same, not sure if the first one is ok regarding absolute
portability).

	Jakub

[-- Attachment #2: P --]
[-- Type: text/plain, Size: 1235 bytes --]

2004-10-16  Jakub Jelinek  <jakub@redhat.com>

	* pointer-set.c (hash1): Use integer part of 2^64 / phi
	instead 2^32 / phi if long is 64-bit.

--- gcc/pointer-set.c.jj	2004-10-15 16:36:32.000000000 +0200
+++ gcc/pointer-set.c	2004-10-16 12:06:50.420664237 +0200
@@ -46,8 +46,8 @@ struct pointer_set_t
    relatively prime to 2^sizeof(size_t).  The result is two words.
    Discard the most significant word, and return the most significant
    N bits of the least significant word.  As suggested by Knuth, our
-   choice for A is the integer part of 2^32 / phi, where phi is the
-   golden ratio.
+   choice for A is the integer part of (ULONG_MAX + 1.0) / phi, where phi
+   is the golden ratio.
 
    We don't need to do anything special for full-width multiplication
    because we're only interested in the least significant word of the
@@ -56,7 +56,11 @@ struct pointer_set_t
 static inline size_t
 hash1 (const void *p, unsigned long max, unsigned long logmax)
 {
+#if ULONG_MAX > UINT_MAX
+  const unsigned long A = 0x9e3779b97f4a7c16ul;
+#else
   const unsigned long A = 0x9e3779b9u;
+#endif
   const unsigned long shift = sizeof(unsigned long) * CHAR_BIT - logmax;
 
   return ((A * (unsigned long) p) >> shift) & (max - 1);

[-- Attachment #3: P2 --]
[-- Type: text/plain, Size: 1428 bytes --]

2004-10-16  Jakub Jelinek  <jakub@redhat.com>

	* pointer-set.c (hash1): Use integer part of 2^64 / phi
	instead 2^32 / phi if long is 64-bit.

--- gcc/pointer-set.c.jj	2004-10-15 16:36:32.000000000 +0200
+++ gcc/pointer-set.c	2004-10-16 12:23:49.722200909 +0200
@@ -46,8 +46,8 @@ struct pointer_set_t
    relatively prime to 2^sizeof(size_t).  The result is two words.
    Discard the most significant word, and return the most significant
    N bits of the least significant word.  As suggested by Knuth, our
-   choice for A is the integer part of 2^32 / phi, where phi is the
-   golden ratio.
+   choice for A is the integer part of (ULONG_MAX + 1.0) / phi, where phi
+   is the golden ratio.
 
    We don't need to do anything special for full-width multiplication
    because we're only interested in the least significant word of the
@@ -57,9 +57,14 @@ static inline size_t
 hash1 (const void *p, unsigned long max, unsigned long logmax)
 {
   const unsigned long A = 0x9e3779b9u;
-  const unsigned long shift = sizeof(unsigned long) * CHAR_BIT - logmax;
+  unsigned long B;
+  const unsigned long shift = sizeof (unsigned long) * CHAR_BIT - logmax;
 
-  return ((A * (unsigned long) p) >> shift) & (max - 1);
+  if (sizeof (unsigned long) * CHAR_BIT > 32)
+    B = ((A << 16) << 16) | 0x7f4a7c16u;
+  else
+    B = A;
+  return ((B * (unsigned long) p) >> shift) & (max - 1);
 }
 
 /* Allocate an empty pointer set. */

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:42   ` Jakub Jelinek
@ 2004-10-16 11:49     ` Jakub Jelinek
  2004-10-16 18:29     ` Matt Austern
  2004-10-16 18:35     ` Richard Henderson
  2 siblings, 0 replies; 20+ messages in thread
From: Jakub Jelinek @ 2004-10-16 11:49 UTC (permalink / raw)
  To: Matt Austern; +Cc: GCC Patches

On Sat, Oct 16, 2004 at 06:37:12AM -0400, Jakub Jelinek wrote:
> On Sat, Oct 16, 2004 at 05:47:08AM -0400, Jakub Jelinek wrote:
> > But on x86-64-redhat-linux essentially makes even bootstrap impossible
> > (well, I have killed it after it spent more than 10 minutes compiling
> > insn-recog or insn-attrtab by stage1/cc1).
> > hash1's distribution is less than perfect.
> 
> For the hash function I'm trying these patches now:
> 
> (both do the same, not sure if the first one is ok regarding absolute
> portability).

With either of these patches the average chain length on the same
table (16384 pointers, 65536 slots) is 1.1, there is one occurence of 4 pointers
hashed into the same slot and 44 times 3 pointers hashed into the same
slot, but never more.

Ok to commit?  Is the #if ULONG_MAX > UINT_MAX ok, or should I commit the
one without #ifs?

	Jakub

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:17 ` Jakub Jelinek
  2004-10-16 10:37   ` Steven Bosscher
  2004-10-16 10:42   ` Jakub Jelinek
@ 2004-10-16 18:14   ` Matt Austern
  2 siblings, 0 replies; 20+ messages in thread
From: Matt Austern @ 2004-10-16 18:14 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Patches

On Oct 16, 2004, at 2:47 AM, Jakub Jelinek wrote:

> The hash table contains 21249 NULLs, then full slots (with a couple
> of NULLs near the beginning, but only a few), and from slot 37875
> onwards till the end of the hash table there are NULLs again.
>
> Shouldn't we multiply by 2^64 / phi instead of 2^32 / phi when
> long is 64-bit?

Oops, you're right.  Sorry; I didn't test on a 64-bit platform.

			--Matt

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:42   ` Jakub Jelinek
  2004-10-16 11:49     ` Jakub Jelinek
@ 2004-10-16 18:29     ` Matt Austern
  2004-10-16 18:35     ` Richard Henderson
  2 siblings, 0 replies; 20+ messages in thread
From: Matt Austern @ 2004-10-16 18:29 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Patches

On Oct 16, 2004, at 3:37 AM, Jakub Jelinek wrote:

> On Sat, Oct 16, 2004 at 05:47:08AM -0400, Jakub Jelinek wrote:
>> But on x86-64-redhat-linux essentially makes even bootstrap impossible
>> (well, I have killed it after it spent more than 10 minutes compiling
>> insn-recog or insn-attrtab by stage1/cc1).
>> hash1's distribution is less than perfect.
>
> For the hash function I'm trying these patches now:
>
> (both do the same, not sure if the first one is ok regarding absolute
> portability).

If it were me I'd probably use the first patch, to make absolutely sure 
we're
doing nothing but multiplication by a compile-time constant.  Probably 
the
optimizer is smart enough to optimize all away the extra stuff in the 
second
version of the patch, but I'd rather not count on that in code that 
really is
time critical.

			--Matt

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:42   ` Jakub Jelinek
  2004-10-16 11:49     ` Jakub Jelinek
  2004-10-16 18:29     ` Matt Austern
@ 2004-10-16 18:35     ` Richard Henderson
  2004-10-16 18:37       ` Jakub Jelinek
  2 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2004-10-16 18:35 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Matt Austern, GCC Patches

On Sat, Oct 16, 2004 at 06:37:12AM -0400, Jakub Jelinek wrote:
> +   choice for A is the integer part of (ULONG_MAX + 1.0) / phi, where phi
> +   is the golden ratio.

Any reason not to use the computation actually described here?

Otherwise, the ifdef one's fine if you use HOST_BITS_PER_LONG
to choose one of the alternatives exactly:

#if HOST_BITS_PER_LONG == 32
  const unsigned long A = 0x9e3779b9u;
#elif HOST_BITS_PER_LONG == 64
  const unsigned long A = 0x9e3779b97f4a7c16ul;
#endif

Which will handily not compile if we ever find something else.


r~

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 18:35     ` Richard Henderson
@ 2004-10-16 18:37       ` Jakub Jelinek
  2004-10-16 18:51         ` Richard Henderson
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2004-10-16 18:37 UTC (permalink / raw)
  To: Richard Henderson, Matt Austern, GCC Patches

On Sat, Oct 16, 2004 at 11:29:52AM -0700, Richard Henderson wrote:
> On Sat, Oct 16, 2004 at 06:37:12AM -0400, Jakub Jelinek wrote:
> > +   choice for A is the integer part of (ULONG_MAX + 1.0) / phi, where phi
> > +   is the golden ratio.
> 
> Any reason not to use the computation actually described here?

You mean doing the computation in FPU?

> Otherwise, the ifdef one's fine if you use HOST_BITS_PER_LONG
> to choose one of the alternatives exactly:
> 
> #if HOST_BITS_PER_LONG == 32
>   const unsigned long A = 0x9e3779b9u;
> #elif HOST_BITS_PER_LONG == 64
>   const unsigned long A = 0x9e3779b97f4a7c16ul;
> #endif
> 
> Which will handily not compile if we ever find something else.

Yeah, that looks better.

	Jakub

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 18:37       ` Jakub Jelinek
@ 2004-10-16 18:51         ` Richard Henderson
  2004-10-16 19:15           ` Jakub Jelinek
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2004-10-16 18:51 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Matt Austern, GCC Patches

On Sat, Oct 16, 2004 at 02:34:24PM -0400, Jakub Jelinek wrote:
> You mean doing the computation in FPU?

Well, it's all constants, so why wouldn't it be folded at compile time?


r~

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 18:51         ` Richard Henderson
@ 2004-10-16 19:15           ` Jakub Jelinek
  2004-10-17  1:11             ` Richard Henderson
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2004-10-16 19:15 UTC (permalink / raw)
  To: Richard Henderson, Matt Austern, GCC Patches

On Sat, Oct 16, 2004 at 11:37:41AM -0700, Richard Henderson wrote:
> On Sat, Oct 16, 2004 at 02:34:24PM -0400, Jakub Jelinek wrote:
> > You mean doing the computation in FPU?
> 
> Well, it's all constants, so why wouldn't it be folded at compile time?

Because not all hosts have long double that has big enough mantissa
to compute the exact result (nor I think we can portably use math *l
functions)?

Perhaps we can do it as a fallback:

#if HOST_BITS_PER_LONG == 32
  const unsigned long A = 0x9e3779b9u;
#elif HOST_BITS_PER_LONG == 64
  const unsigned long A = 0x9e3779b97f4a7c16ul;
#else
  const double M = (ULONG_MAX + 1.0);
  const double B = M / ((sqrt (5) - 1) / 2.0);
  const unsigned long A = B - (floor (B / M) * M);
#endif

The last one results in const unsigned long A = 0x9e3779b97f4a7000;
on x86-64, while if done with long double it gives correct
const unsigned long A = 0x9e3779b97f4a7c16; result.

	Jakub

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 19:15           ` Jakub Jelinek
@ 2004-10-17  1:11             ` Richard Henderson
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2004-10-17  1:11 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Matt Austern, GCC Patches

On Sat, Oct 16, 2004 at 02:51:16PM -0400, Jakub Jelinek wrote:
> Because not all hosts have long double that has big enough mantissa
> to compute the exact result (nor I think we can portably use math *l
> functions)?

Ah yeah.  Well, nevermind.


r~

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-16 10:37   ` Steven Bosscher
@ 2004-10-17  8:30     ` Mark Mitchell
  2004-10-17 10:59       ` Steven Bosscher
  0 siblings, 1 reply; 20+ messages in thread
From: Mark Mitchell @ 2004-10-17  8:30 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: Jakub Jelinek, Matt Austern, GCC Patches

Steven Bosscher wrote:
> On Saturday 16 October 2004 11:47, Jakub Jelinek wrote:
> 
>>But on x86-64-redhat-linux essentially makes even bootstrap impossible
>>(well, I have killed it after it spent more than 10 minutes compiling
>>insn-recog or insn-attrtab by stage1/cc1).
>>hash1's distribution is less than perfect.

In that case, go ahed and revert the patch.  I know that we normally 
require a 48-hour period, but I know Matt, and I am confident that he 
will not complain.

Then, Matt will work out how to fix it.

> It would have been nice if this patch had been tested better.  Good
> for you, 2% on QT, but what are the effects on other code?  And are
> we in stage3 now or not?  I did not see this idea on Mark's list of
> things that would be allowed in.

There is an item for improving compile-time performance; this falls 
under that.

> And why did Mark approve this offline, isn't it the policy that a
> patch is posted to gcc-patches and reviewed in public?

I don't think there is any such policy one way or the other.  Certainly, 
there is precedent for patches being approved offline.  Matt sent me the 
patch, and it looked good to me.  I didn't see any reason to test it on 
other architectures.

-- 
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-17  8:30     ` Mark Mitchell
@ 2004-10-17 10:59       ` Steven Bosscher
  2004-10-17 18:45         ` Matt Austern
                           ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Steven Bosscher @ 2004-10-17 10:59 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Jakub Jelinek, Matt Austern, GCC Patches

On Sunday 17 October 2004 07:51, Mark Mitchell wrote:
> I don't think there is any such policy one way or the other.  Certainly,
> there is precedent for patches being approved offline.

I know there is, and I think it's wrong.  More eyes see more
things.


>  Matt sent me the
> patch, and it looked good to me.  I didn't see any reason to test it on
> other architectures.

Well, we've have some pretty serious breakage a few times in the
past few weeks.  Already three times the cause of this breakage
was that some patch wasn't tested on some architecture.  So I
see lots of reasons to require better testing for patches when
the mainlne is in stage3.

Can we make it a requirement that larger patches like this should
be tested on three platforms when the mainline is in stage3?

Gr.
Steven


Index: develop.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/develop.html,v
retrieving revision 1.52
diff -c -3 -p -r1.52 develop.html
*** develop.html	11 Sep 2004 14:55:46 -0000	1.52
--- develop.html	17 Oct 2004 09:53:45 -0000
*************** back-end.</p>
*** 123,140 ****
  <p>During this period, the only (non-documentation) changes that may be
  made are changes that fix bugs or new ports which do not require changes
  to other parts of the compiler.
! New functionality may not be introduced during this period.</p>
  
  <p><strong>Rationale</strong></p>
  
  <p>In order to produce releases on a regular schedule, we must ensure
  that the mainline is reasonably stable some time before we make the
! release.  Therefore, more radical changes must be made earlier in the
! cycle, so that we have time to fix any problems that result.</p>
  
  <p>In order to reach higher standards of quality, we must focus on
! fixing bugs; by working exclusively on bug-fixing through Stage 3, we
! will have a higher quality source base as we prepare for a release.</p>
  
  <p>Although maintaining a development branch, including merging new
  changes from the mainline, is somewhat burdensome, the absolute worst
--- 123,147 ----
  <p>During this period, the only (non-documentation) changes that may be
  made are changes that fix bugs or new ports which do not require changes
  to other parts of the compiler.
! 
! In principle, new functionality may not be introduced during this period.
! However, the release manager may still allow patches in that add new
! functionality.  Such patches should be validated on three different
! targets, each targeting a different microprocessor family, before the
! patch can be commited.</p>
  
  <p><strong>Rationale</strong></p>
  
  <p>In order to produce releases on a regular schedule, we must ensure
  that the mainline is reasonably stable some time before we make the
! release.  Therefore, more radical changes must either be made earlier
! in the cycle, so that we have time to fix any problems that result, or
! very thoroughly tested, to reduce the risk of destabilizing the mainline
! as much as possible.</p>
  
  <p>In order to reach higher standards of quality, we must focus on
! fixing bugs; by working almost exclusively on bug-fixing through Stage 3,
! we will have a higher quality source base as we prepare for a release.</p>
  
  <p>Although maintaining a development branch, including merging new
  changes from the mainline, is somewhat burdensome, the absolute worst

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-17 10:59       ` Steven Bosscher
@ 2004-10-17 18:45         ` Matt Austern
  2004-10-18  4:19         ` Mark Mitchell
  2004-10-21 21:25         ` Gerald Pfeifer
  2 siblings, 0 replies; 20+ messages in thread
From: Matt Austern @ 2004-10-17 18:45 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: Mark Mitchell, Jakub Jelinek, GCC Patches

On Oct 17, 2004, at 2:58 AM, Steven Bosscher wrote:

> On Sunday 17 October 2004 07:51, Mark Mitchell wrote:
>> I don't think there is any such policy one way or the other.  
>> Certainly,
>> there is precedent for patches being approved offline.
>
> I know there is, and I think it's wrong.  More eyes see more
> things.
>
>
>>  Matt sent me the
>> patch, and it looked good to me.  I didn't see any reason to test it 
>> on
>> other architectures.
>
> Well, we've have some pretty serious breakage a few times in the
> past few weeks.  Already three times the cause of this breakage
> was that some patch wasn't tested on some architecture.  So I
> see lots of reasons to require better testing for patches when
> the mainlne is in stage3.
>
> Can we make it a requirement that larger patches like this should
> be tested on three platforms when the mainline is in stage3?

That may be a good idea, but bear in mind that it probably would
not have caught this problem.  I don't regularly use a platform
where pointers are 64-bit, so if I were testing this on three
platforms it probably would have been three 32-bit platforms.
If we're looking for diversity, it had probably better be
something like this: at least one non-Linux platform, at least
one non-ELF platform, at least one non-x86 platform, at least
two different word sizes.

			--Matt 

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-17 10:59       ` Steven Bosscher
  2004-10-17 18:45         ` Matt Austern
@ 2004-10-18  4:19         ` Mark Mitchell
  2004-10-21 21:25         ` Gerald Pfeifer
  2 siblings, 0 replies; 20+ messages in thread
From: Mark Mitchell @ 2004-10-18  4:19 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: Jakub Jelinek, Matt Austern, GCC Patches

Steven Bosscher wrote:

>On Sunday 17 October 2004 07:51, Mark Mitchell wrote:
>  
>
>>I don't think there is any such policy one way or the other.  Certainly,
>>there is precedent for patches being approved offline.
>>    
>>
>
>I know there is, and I think it's wrong.  More eyes see more
>things.
>  
>
Yes, but I do have the authority to approve patches.  If we had a 
no-offline-approval policy, what would have happenned is that Matt would 
have posted the patch, and I would have immediately approved it.  That's 
no different that me approving the patch offline; we would still have 
had a broken patch committed to the tree.

To make things more substantive, we could require that all patches be 
posted for a period of time (24 hrs?) before being approved.  That seems 
silly though; some patches are very obvious.  So, we'd have to make 
judgement calls about what's appropriate in what situations.  If I'd 
anticipated problems, I would have just asked for further testing in the 
first place.

In short, I don't see that there's a policy problem.  If there's a 
problem, it's just that I didn't anticipate the 64-bit mode issues, but, 
hey, we all make mistakes.

>Can we make it a requirement that larger patches like this should
>be tested on three platforms when the mainline is in stage3?
>  
>
I don't think this is a large patch.  I actually thought it was pretty 
straightforward.  It did have a bug, but that happens sometime.  I don't 
think that requiring testing on three platforms for this kind of patch 
would be profitable, overall.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
  2004-10-17 10:59       ` Steven Bosscher
  2004-10-17 18:45         ` Matt Austern
  2004-10-18  4:19         ` Mark Mitchell
@ 2004-10-21 21:25         ` Gerald Pfeifer
  2 siblings, 0 replies; 20+ messages in thread
From: Gerald Pfeifer @ 2004-10-21 21:25 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: Mark Mitchell, Jakub Jelinek, Matt Austern, GCC Patches

On Sun, 17 Oct 2004, Steven Bosscher wrote:
> Index: develop.html
> ===================================================================
>  <p>In order to reach higher standards of quality, we must focus on
> ! fixing bugs; by working almost exclusively on bug-fixing through Stage 3,
> ! we will have a higher quality source base as we prepare for a release.</p>

This part is okay; I don't think the other two hunks are sufficiently
undisputed, though.

Gerald

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

* Re: [Committed] Use special-purpose hash table to speed up walk_tree
@ 2004-10-18 14:48 Richard Kenner
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Kenner @ 2004-10-18 14:48 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    Yes, but I do have the authority to approve patches.  If we had a 
    no-offline-approval policy, what would have happenned is that Matt would 
    have posted the patch, and I would have immediately approved it.  That's 
    no different that me approving the patch offline; we would still have 
    had a broken patch committed to the tree.

I agree.  The purpose of posting patches to gcc-patches is indeed to have
many sets of eyes look at it, but many of those are after the patch is
checked in.  That's the case whether the patch is one written by somebody
with global write privs, approved on-list, or approved off-list.

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

end of thread, other threads:[~2004-10-21 20:14 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-14 23:22 [Committed] Use special-purpose hash table to speed up walk_tree Matt Austern
2004-10-14 23:24 ` Phil Edwards
2004-10-15  0:04   ` Matt Austern
2004-10-16 10:17 ` Jakub Jelinek
2004-10-16 10:37   ` Steven Bosscher
2004-10-17  8:30     ` Mark Mitchell
2004-10-17 10:59       ` Steven Bosscher
2004-10-17 18:45         ` Matt Austern
2004-10-18  4:19         ` Mark Mitchell
2004-10-21 21:25         ` Gerald Pfeifer
2004-10-16 10:42   ` Jakub Jelinek
2004-10-16 11:49     ` Jakub Jelinek
2004-10-16 18:29     ` Matt Austern
2004-10-16 18:35     ` Richard Henderson
2004-10-16 18:37       ` Jakub Jelinek
2004-10-16 18:51         ` Richard Henderson
2004-10-16 19:15           ` Jakub Jelinek
2004-10-17  1:11             ` Richard Henderson
2004-10-16 18:14   ` Matt Austern
2004-10-18 14:48 Richard Kenner

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