diff options
author | Richard Biener <rguenth@gcc.gnu.org> | 2009-08-06 11:29:13 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-08-06 11:29:13 +0000 |
commit | 8bc88f256740083bb9ef77a4a3bd1a440928c5ea (patch) | |
tree | 085a13acd988eaaa68c80427926f4636e45f17a5 | |
parent | 6e319d7beb01b774b7b535e021f48c9a94567e3c (diff) | |
download | gcc-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.c | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 59 | ||||
-rw-r--r-- | gcc/tree.c | 2 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
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); } @@ -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)) @@ -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); |