aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenth@gcc.gnu.org>2009-08-06 11:29:13 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-08-06 11:29:13 +0000
commit8bc88f256740083bb9ef77a4a3bd1a440928c5ea (patch)
tree085a13acd988eaaa68c80427926f4636e45f17a5
parent6e319d7beb01b774b7b535e021f48c9a94567e3c (diff)
downloadgcc-8bc88f256740083bb9ef77a4a3bd1a440928c5ea.zip
gcc-8bc88f256740083bb9ef77a4a3bd1a440928c5ea.tar.gz
gcc-8bc88f256740083bb9ef77a4a3bd1a440928c5ea.tar.bz2
re PR middle-end/40964 (ICE in insert_vi_for_tree)
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
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40964.c10
-rw-r--r--gcc/tree-ssa-structalias.c59
-rw-r--r--gcc/tree.c2
-rw-r--r--gcc/tree.h1
4 files changed, 53 insertions, 19 deletions
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40964.c b/gcc/testsuite/gcc.c-torture/compile/pr40964.c
new file mode 100644
index 0000000..5163994
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40964.c
@@ -0,0 +1,10 @@
+struct alloc2 {
+ int bla;
+ char * __restrict data;
+ char * __restrict data2;
+};
+struct alloc2 b;
+void * f (void)
+{
+ return b.data;
+}
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a9eef0b..50ef0b6 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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);
}
diff --git a/gcc/tree.c b/gcc/tree.c
index 58994b1..60416d3 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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))
diff --git a/gcc/tree.h b/gcc/tree.h
index a1370fa..2791830 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);