This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]