From 27fa4044f10f2a28e3e33b8b126462276f8fdc4f Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Fri, 23 Nov 2007 14:28:59 +0000
Subject: [PATCH] re PR tree-optimization/34176 (SCCVN breaks gettext)

2007-11-23  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.

Co-Authored-By: Michael Matz <matz@suse.de>

From-SVN: r130379
---
 gcc/ChangeLog                                 | 13 ++++
 gcc/alloc-pool.c                              | 18 ++++-
 gcc/alloc-pool.h                              |  1 +
 gcc/testsuite/ChangeLog                       |  6 ++
 gcc/testsuite/gcc.c-torture/execute/pr34176.c | 68 +++++++++++++++++++
 gcc/tree-ssa-sccvn.c                          | 20 ++++++
 6 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr34176.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c78ca628ab78..687c8b63dec2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2007-11-23  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.
+
 2007-11-23  Richard Guenther  <rguenther@suse.de>
 
 	* tree-ssa-copy.c (may_propagate_copy): Remove redundant
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index 1b3dc9155098..d5d1fab79afc 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -183,7 +183,7 @@ create_alloc_pool (const char *name, size_t size, size_t num)
 
 /* Free all memory allocated for the given memory pool.  */
 void
-free_alloc_pool (alloc_pool pool)
+empty_alloc_pool (alloc_pool pool)
 {
   alloc_pool_list block, next_block;
 #ifdef GATHER_STATISTICS
@@ -201,6 +201,22 @@ free_alloc_pool (alloc_pool pool)
       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
diff --git a/gcc/alloc-pool.h b/gcc/alloc-pool.h
index 772d9a01fc44..1fc3c5750937 100644
--- a/gcc/alloc-pool.h
+++ b/gcc/alloc-pool.h
@@ -59,6 +59,7 @@ typedef struct alloc_pool_def
 
 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 *);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7f0c52bcc22a..9f893c390964 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2007-11-23  Richard Guenther  <rguenther@suse.de>
+	Michael Matz  <matz@suse.de>
+
+	PR tree-optimization/34176
+	* gcc.c-torture/execute/pr34176.c: New testcase.
+
 2007-11-23  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c++/34198
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34176.c b/gcc/testsuite/gcc.c-torture/execute/pr34176.c
new file mode 100644
index 000000000000..3bbdb22c74cd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr34176.c
@@ -0,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;
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b4fb014b76dd..8edd03b9ad7c 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -655,6 +655,9 @@ vn_reference_lookup (tree op, VEC (tree, gc) *vuses)
   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;
 
@@ -742,6 +745,9 @@ vn_unary_op_lookup (tree op)
   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;
@@ -834,6 +840,9 @@ vn_binary_op_lookup (tree op)
   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;
@@ -960,6 +969,9 @@ vn_phi_lookup (tree phi)
   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;
@@ -1799,6 +1811,14 @@ process_scc (VEC (tree, heap) *scc)
 	{
 	  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);
 	}
-- 
GitLab