This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR40964
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 6 Aug 2009 13:26:56 +0200 (CEST)
- Subject: [PATCH] Fix PR40964
This fixes the ICE with multiple restrict pointers in structs.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/tree.c
===================================================================
*** gcc/tree.c (revision 150514)
--- gcc/tree.c (working copy)
*************** iterative_hash_hashval_t (hashval_t val,
*** 3988,3994 ****
}
/* Produce good hash value combining VAL and VAL2. */
! static inline hashval_t
iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
{
if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
--- 3988,3994 ----
}
/* Produce good hash value combining VAL and VAL2. */
! hashval_t
iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
{
if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
Index: gcc/tree.h
===================================================================
*** gcc/tree.h (revision 150514)
--- gcc/tree.h (working copy)
*************** extern int simple_cst_equal (const_tree,
*** 4879,4884 ****
--- 4879,4885 ----
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);
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c (revision 150514)
--- gcc/tree-ssa-structalias.c (working copy)
*************** enum { nothing_id = 0, anything_id = 1,
*** 290,307 ****
escaped_id = 3, nonlocal_id = 4, callused_id = 5,
storedanything_id = 6, integer_id = 7 };
/* Lookup a heap var for FROM, and return it if we find one. */
static tree
! heapvar_lookup (tree from)
{
! 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));
if (h)
! return h->to;
return NULL_TREE;
}
--- 290,328 ----
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, unsigned HOST_WIDE_INT offset)
{
! 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->map.to;
return NULL_TREE;
}
*************** heapvar_lookup (tree from)
*** 309,325 ****
hashtable. */
static void
! heapvar_insert (tree from, tree to)
{
! struct tree_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;
}
/* Return a new variable info structure consisting for a variable
--- 330,348 ----
hashtable. */
static void
! heapvar_insert (tree from, unsigned HOST_WIDE_INT offset, tree to)
{
! struct heapvar_map *h;
void **loc;
! 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
*************** static varinfo_t
*** 3365,3371 ****
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
{
varinfo_t vi;
! tree heapvar = heapvar_lookup (lhs->decl);
if (heapvar == NULL_TREE)
{
--- 3388,3394 ----
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
{
varinfo_t vi;
! tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
if (heapvar == NULL_TREE)
{
*************** make_constraint_from_heapvar (varinfo_t
*** 3373,3379 ****
heapvar = create_tmp_var_raw (ptr_type_node, name);
DECL_EXTERNAL (heapvar) = 1;
! heapvar_insert (lhs->decl, heapvar);
ann = get_var_ann (heapvar);
ann->is_heapvar = 1;
--- 3396,3402 ----
heapvar = create_tmp_var_raw (ptr_type_node, name);
DECL_EXTERNAL (heapvar) = 1;
! heapvar_insert (lhs->decl, lhs->offset, heapvar);
ann = get_var_ann (heapvar);
ann->is_heapvar = 1;
*************** static void
*** 5363,5369 ****
init_alias_heapvars (void)
{
if (!heapvar_for_stmt)
! heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
NULL);
}
--- 5386,5392 ----
init_alias_heapvars (void)
{
if (!heapvar_for_stmt)
! heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
NULL);
}
Index: gcc/testsuite/gcc.c-torture/compile/pr40964.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr40964.c (revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr40964.c (revision 0)
***************
*** 0 ****
--- 1,10 ----
+ struct alloc2 {
+ int bla;
+ char * __restrict data;
+ char * __restrict data2;
+ };
+ struct alloc2 b;
+ void * f (void)
+ {
+ return b.data;
+ }