re PR middle-end/40964 (ICE in insert_vi_for_tree)
authorRichard Biener <rguenth@gcc.gnu.org>
Thu, 6 Aug 2009 11:29:13 +0000 (11:29 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 6 Aug 2009 11:29:13 +0000 (11:29 +0000)
2009-08-06  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/40964
* tree.c (iterative_hash_host_wide_int): Export.
* tree.h (iterative_hash_host_wide_int): Declare.
* tree-ssa-structalias.c (heapvar_map): New struct.
(heapvar_map_eq): New function.
(heapvar_map_hash): Likewise.
(heapvar_lookup): Adjust.
(heapvar_insert): Likewise.
(make_constraint_from_heapvar): Allow multiple heap variables
per decl at different offsets.
(init_alias_heapvars): Adjust.

* gcc.c-torture/compile/pr40964.c: New testcase.

From-SVN: r150517

gcc/testsuite/gcc.c-torture/compile/pr40964.c [new file with mode: 0644]
gcc/tree-ssa-structalias.c
gcc/tree.c
gcc/tree.h

diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40964.c b/gcc/testsuite/gcc.c-torture/compile/pr40964.c
new file mode 100644 (file)
index 0000000..5163994
--- /dev/null
@@ -0,0 +1,10 @@
+struct alloc2 {
+    int bla;
+    char * __restrict data;
+    char * __restrict data2;
+};
+struct alloc2 b;
+void * f (void)
+{
+  return b.data;
+}
index a9eef0b..50ef0b6 100644 (file)
@@ -290,18 +290,39 @@ enum { nothing_id = 0, anything_id = 1, readonly_id = 2,
        escaped_id = 3, nonlocal_id = 4, callused_id = 5,
        storedanything_id = 6, integer_id = 7 };
 
+struct GTY(()) heapvar_map {
+  struct tree_map map;
+  unsigned HOST_WIDE_INT offset;
+};
+
+static int
+heapvar_map_eq (const void *p1, const void *p2)
+{
+  const struct heapvar_map *h1 = (const struct heapvar_map *)p1;
+  const struct heapvar_map *h2 = (const struct heapvar_map *)p2;
+  return (h1->map.base.from == h2->map.base.from
+         && h1->offset == h2->offset);
+}
+
+static unsigned int
+heapvar_map_hash (struct heapvar_map *h)
+{
+  return iterative_hash_host_wide_int (h->offset,
+                                      htab_hash_pointer (h->map.base.from));
+}
+
 /* Lookup a heap var for FROM, and return it if we find one.  */
 
 static tree
-heapvar_lookup (tree from)
+heapvar_lookup (tree from, unsigned HOST_WIDE_INT offset)
 {
-  struct tree_map *h, in;
-  in.base.from = from;
-
-  h = (struct tree_map *) htab_find_with_hash (heapvar_for_stmt, &in,
-                                              htab_hash_pointer (from));
+  struct heapvar_map *h, in;
+  in.map.base.from = from;
+  in.offset = offset;
+  h = (struct heapvar_map *) htab_find_with_hash (heapvar_for_stmt, &in,
+                                                 heapvar_map_hash (&in));
   if (h)
-    return h->to;
+    return h->map.to;
   return NULL_TREE;
 }
 
@@ -309,17 +330,19 @@ heapvar_lookup (tree from)
    hashtable.  */
 
 static void
-heapvar_insert (tree from, tree to)
+heapvar_insert (tree from, unsigned HOST_WIDE_INT offset, tree to)
 {
-  struct tree_map *h;
+  struct heapvar_map *h;
   void **loc;
 
-  h = GGC_NEW (struct tree_map);
-  h->hash = htab_hash_pointer (from);
-  h->base.from = from;
-  h->to = to;
-  loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->hash, INSERT);
-  *(struct tree_map **) loc = h;
+  h = GGC_NEW (struct heapvar_map);
+  h->map.base.from = from;
+  h->offset = offset;
+  h->map.hash = heapvar_map_hash (h);
+  h->map.to = to;
+  loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->map.hash, INSERT);
+  gcc_assert (*loc == NULL);
+  *(struct heapvar_map **) loc = h;
 }
 
 /* Return a new variable info structure consisting for a variable
@@ -3365,7 +3388,7 @@ static varinfo_t
 make_constraint_from_heapvar (varinfo_t lhs, const char *name)
 {
   varinfo_t vi;
-  tree heapvar = heapvar_lookup (lhs->decl);
+  tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
 
   if (heapvar == NULL_TREE)
     {
@@ -3373,7 +3396,7 @@ make_constraint_from_heapvar (varinfo_t lhs, const char *name)
       heapvar = create_tmp_var_raw (ptr_type_node, name);
       DECL_EXTERNAL (heapvar) = 1;
 
-      heapvar_insert (lhs->decl, heapvar);
+      heapvar_insert (lhs->decl, lhs->offset, heapvar);
 
       ann = get_var_ann (heapvar);
       ann->is_heapvar = 1;
@@ -5363,7 +5386,7 @@ static void
 init_alias_heapvars (void)
 {
   if (!heapvar_for_stmt)
-    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
+    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
                                        NULL);
 }
 
index 58994b1..60416d3 100644 (file)
@@ -3988,7 +3988,7 @@ iterative_hash_hashval_t (hashval_t val, hashval_t val2)
 }
 
 /* Produce good hash value combining VAL and VAL2.  */
-static inline hashval_t
+hashval_t
 iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
 {
   if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
index a1370fa..2791830 100644 (file)
@@ -4879,6 +4879,7 @@ extern int simple_cst_equal (const_tree, const_tree);
 extern hashval_t iterative_hash_expr (const_tree, hashval_t);
 extern hashval_t iterative_hash_exprs_commutative (const_tree,
                                                    const_tree, hashval_t);
+extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
 extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
 extern int compare_tree_int (const_tree, unsigned HOST_WIDE_INT);
 extern int type_list_equal (const_tree, const_tree);