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


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

[PATCH] Fix PR34176, SCCVN miscompile of gettext


This fixes aforementioned PR by clearing the optimistic tables before
each iteration.  I tested a version that didn't empty the alloc pools
on C++ and SPEC with no visible changes in compile-time, memory-usage
or runtime performance.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for mainline?

Thanks,
Richard.

2007-11-22  Richard Guenther  <rguenther@suse.de>
	Michael Matz  <matz@suse.de>

	PR tree-optimization/34176
	* alloc-pool.h (empty_alloc_pool): Declare.
	* alloc-pool.c (empty_alloc_pool): New function.
	* tree-ssa-sccvn.c (vn_reference_lookup): Also lookup from the
	valid table if a lookup from the optimistic table failed.
	(vn_unary_op_lookup): Likewise.
	(vn_binary_op_lookup): Likewise.
	(vn_phi_lookup): Likewise.
	(process_scc): Clear optimistic tables before every iteration.

	* gcc.c-torture/execute/pr34176.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c.orig	2007-11-23 11:08:02.000000000 +0100
--- gcc/tree-ssa-sccvn.c	2007-11-23 11:12:31.000000000 +0100
*************** vn_reference_lookup (tree op, VEC (tree,
*** 655,660 ****
--- 655,663 ----
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    slot = htab_find_slot_with_hash (current_info->references, &vr1, vr1.hashcode,
  				   NO_INSERT);
+   if (!slot && current_info == optimistic_info)
+     slot = htab_find_slot_with_hash (valid_info->references, &vr1, vr1.hashcode,
+ 				     NO_INSERT);
    if (!slot)
      return NULL_TREE;
  
*************** vn_unary_op_lookup (tree op)
*** 742,747 ****
--- 745,753 ----
    vuo1.hashcode = vn_unary_op_compute_hash (&vuo1);
    slot = htab_find_slot_with_hash (current_info->unary, &vuo1, vuo1.hashcode,
  				   NO_INSERT);
+   if (!slot && current_info == optimistic_info)
+     slot = htab_find_slot_with_hash (valid_info->unary, &vuo1, vuo1.hashcode,
+ 				     NO_INSERT);
    if (!slot)
      return NULL_TREE;
    return ((vn_unary_op_t)*slot)->result;
*************** vn_binary_op_lookup (tree op)
*** 834,839 ****
--- 840,848 ----
    vbo1.hashcode = vn_binary_op_compute_hash (&vbo1);
    slot = htab_find_slot_with_hash (current_info->binary, &vbo1, vbo1.hashcode,
  				   NO_INSERT);
+   if (!slot && current_info == optimistic_info)
+     slot = htab_find_slot_with_hash (valid_info->binary, &vbo1, vbo1.hashcode,
+ 				     NO_INSERT);
    if (!slot)
      return NULL_TREE;
    return ((vn_binary_op_t)*slot)->result;
*************** vn_phi_lookup (tree phi)
*** 960,965 ****
--- 969,977 ----
    vp1.hashcode = vn_phi_compute_hash (&vp1);
    slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode,
  				   NO_INSERT);
+   if (!slot && current_info == optimistic_info)
+     slot = htab_find_slot_with_hash (valid_info->phis, &vp1, vp1.hashcode,
+ 				     NO_INSERT);
    if (!slot)
      return NULL_TREE;
    return ((vn_phi_t)*slot)->result;
*************** process_scc (VEC (tree, heap) *scc)
*** 1799,1804 ****
--- 1811,1824 ----
  	{
  	  changed = false;
  	  iterations++;
+ 	  htab_empty (optimistic_info->unary);
+ 	  htab_empty (optimistic_info->binary);
+ 	  htab_empty (optimistic_info->phis);
+ 	  htab_empty (optimistic_info->references);
+ 	  empty_alloc_pool (optimistic_info->unary_op_pool);
+ 	  empty_alloc_pool (optimistic_info->binary_op_pool);
+ 	  empty_alloc_pool (optimistic_info->phis_pool);
+ 	  empty_alloc_pool (optimistic_info->references_pool);
  	  for (i = 0; VEC_iterate (tree, scc, i, var); i++)
  	    changed |= visit_use (var);
  	}
Index: gcc/testsuite/gcc.c-torture/execute/pr34176.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.c-torture/execute/pr34176.c	2007-11-23 11:09:05.000000000 +0100
***************
*** 0 ****
--- 1,68 ----
+ 
+ typedef __SIZE_TYPE__ size_t;
+ typedef unsigned int index_ty;
+ typedef index_ty *index_list_ty;
+ 
+ struct mult_index
+ {
+   index_ty index;
+   unsigned int count;
+ };
+ 
+ struct mult_index_list
+ {
+   struct mult_index *item;
+   size_t nitems;
+   size_t nitems_max;
+ 
+   struct mult_index *item2;
+   size_t nitems2_max;
+ };
+ 
+ int __attribute__((noinline))
+ hash_find_entry (size_t *result)
+ {
+     *result = 2;
+     return 0;
+ }
+ 
+ extern void abort (void);
+ struct mult_index * __attribute__((noinline))
+ foo (size_t n)
+ {
+   static count = 0;
+   if (count++ > 0)
+     abort ();
+   return 0;
+ }
+ 
+ int
+ main (void)
+ {
+     size_t nitems = 0;
+ 
+     for (;;)
+     {
+         size_t list;
+ 
+         hash_find_entry (&list);
+         {
+             size_t len2 = list;
+             struct mult_index *destptr;
+             struct mult_index *dest;
+             size_t new_max  = nitems + len2;
+ 
+             if (new_max != len2)
+                 break;
+             dest = foo (new_max);
+ 
+             destptr = dest;
+             while (len2--)
+                 destptr++;
+ 
+             nitems = destptr - dest;
+         }
+     }
+ 
+     return 0;
+ }
Index: gcc/alloc-pool.c
===================================================================
*** gcc/alloc-pool.c.orig	2007-07-26 14:13:38.000000000 +0200
--- gcc/alloc-pool.c	2007-11-23 11:22:37.000000000 +0100
*************** create_alloc_pool (const char *name, siz
*** 183,189 ****
  
  /* Free all memory allocated for the given memory pool.  */
  void
! free_alloc_pool (alloc_pool pool)
  {
    alloc_pool_list block, next_block;
  #ifdef GATHER_STATISTICS
--- 183,189 ----
  
  /* Free all memory allocated for the given memory pool.  */
  void
! empty_alloc_pool (alloc_pool pool)
  {
    alloc_pool_list block, next_block;
  #ifdef GATHER_STATISTICS
*************** free_alloc_pool (alloc_pool pool)
*** 201,206 ****
--- 201,222 ----
        desc->current -= pool->block_size;
  #endif
      }
+ 
+   pool->returned_free_list = NULL;
+   pool->virgin_free_list = NULL;
+   pool->virgin_elts_remaining = 0;
+   pool->elts_allocated = 0;
+   pool->elts_free = 0;
+   pool->blocks_allocated = 0;
+   pool->block_list = NULL;
+ }
+ 
+ /* Free all memory allocated for the given memory pool and the pool itself.  */
+ void
+ free_alloc_pool (alloc_pool pool)
+ {
+   /* First empty the pool.  */
+   empty_alloc_pool (pool);
  #ifdef ENABLE_CHECKING
    memset (pool, 0xaf, sizeof (*pool));
  #endif
Index: gcc/alloc-pool.h
===================================================================
*** gcc/alloc-pool.h.orig	2007-07-26 14:13:38.000000000 +0200
--- gcc/alloc-pool.h	2007-11-23 11:09:59.000000000 +0100
*************** typedef struct alloc_pool_def
*** 59,64 ****
--- 59,65 ----
  
  extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
  extern void free_alloc_pool (alloc_pool);
+ extern void empty_alloc_pool (alloc_pool);
  extern void free_alloc_pool_if_empty (alloc_pool *);
  extern void *pool_alloc (alloc_pool);
  extern void pool_free (alloc_pool, void *);


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