OSDN Git Service

2008-11-25 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Nov 2008 10:34:11 +0000 (10:34 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Nov 2008 10:34:11 +0000 (10:34 +0000)
PR middle-end/38151
PR middle-end/38236
* tree-ssa-alias.c (struct alias_info): Remove written_vars.
Remove dereferenced_ptrs_store and dereferenced_ptrs_load
in favor of dereferenced_ptrs.
(init_alias_info): Adjust.
(delete_alias_info): Likewise.
(compute_flow_insensitive_aliasing): Properly
include all aliased variables.
(update_alias_info_1): Use dereferenced_ptrs.
(setup_pointers_and_addressables): Likewise.
(get_smt_for): Honor ref-all pointers and pointers with known alias
set properly.
* config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers.

* gcc.c-torture/execute/pr38151.c: New testcase.
* gcc.c-torture/execute/pr38236.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142189 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr38151.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr38236.c [new file with mode: 0644]
gcc/tree-ssa-alias.c

index dc991b7..148e7b2 100644 (file)
@@ -1,3 +1,20 @@
+2008-11-25  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/38151
+       PR middle-end/38236
+       * tree-ssa-alias.c (struct alias_info): Remove written_vars.
+       Remove dereferenced_ptrs_store and dereferenced_ptrs_load
+       in favor of dereferenced_ptrs.
+       (init_alias_info): Adjust.
+       (delete_alias_info): Likewise.
+       (compute_flow_insensitive_aliasing): Properly
+       include all aliased variables.
+       (update_alias_info_1): Use dereferenced_ptrs.
+       (setup_pointers_and_addressables): Likewise.
+       (get_smt_for): Honor ref-all pointers and pointers with known alias
+       set properly.
+       * config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers.
+
 2008-11-25  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/38254
index e6f00d7..8f4680d 100644 (file)
@@ -6753,6 +6753,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
              enum machine_mode mode = GET_MODE (reg);
              tree piece_type = lang_hooks.types.type_for_mode (mode, 1);
              tree addr_type = build_pointer_type (piece_type);
+             tree daddr_type = build_pointer_type_for_mode (piece_type,
+                                                            ptr_mode, true);
              tree src_addr, src;
              int src_offset;
              tree dest_addr, dest;
@@ -6772,8 +6774,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
                                      size_int (src_offset));
              src = build_va_arg_indirect_ref (src_addr);
 
-             dest_addr = fold_convert (addr_type, addr);
-             dest_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, dest_addr,
+             dest_addr = fold_convert (daddr_type, addr);
+             dest_addr = fold_build2 (POINTER_PLUS_EXPR, daddr_type, dest_addr,
                                       size_int (INTVAL (XEXP (slot, 1))));
              dest = build_va_arg_indirect_ref (dest_addr);
 
index c6e9ed8..860fa8c 100644 (file)
@@ -1,3 +1,10 @@
+2008-11-25  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/38151
+       PR middle-end/38236
+       * gcc.c-torture/execute/pr38151.c: New testcase.
+       * gcc.c-torture/execute/pr38236.c: Likewise.
+
 2008-11-24  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * g++.dg/eh/weak1.C: Don't xfail hppa*64*-*-*.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38151.c b/gcc/testsuite/gcc.c-torture/execute/pr38151.c
new file mode 100644 (file)
index 0000000..113a255
--- /dev/null
@@ -0,0 +1,46 @@
+void abort (void);
+
+struct S2848
+{
+  unsigned int a;
+  _Complex int b;
+  struct
+  {
+  } __attribute__ ((aligned)) c;
+};
+
+struct S2848 s2848;
+
+int fails;
+
+void  __attribute__((noinline))
+check2848va (int z, ...)
+{
+  struct S2848 arg;
+  __builtin_va_list ap;
+
+  __builtin_va_start (ap, z);
+
+  arg = __builtin_va_arg (ap, struct S2848);
+
+  if (s2848.a != arg.a)
+    ++fails;
+  if (s2848.b != arg.b)
+    ++fails;
+
+  __builtin_va_end (ap);
+}
+
+int main (void)
+{
+  s2848.a = 4027477739U;
+  s2848.b = (723419448 + -218144346 * __extension__ 1i);
+
+  check2848va (1, s2848);
+
+  if (fails)
+    abort ();
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr38236.c b/gcc/testsuite/gcc.c-torture/execute/pr38236.c
new file mode 100644 (file)
index 0000000..d781542
--- /dev/null
@@ -0,0 +1,22 @@
+struct X { int i; };
+
+int __attribute__((noinline))
+foo (struct X *p, int *q, int a, int b)
+{
+  struct X x, y;
+  if (a)
+    p = &x;
+  if (b)
+    q = &x.i;
+  else
+    q = &y.i;
+  *q = 1;
+  return p->i; 
+}
+extern void abort (void);
+int main()
+{
+  if (foo((void *)0, (void *)0, 1, 1) != 1)
+    abort ();
+  return 0;
+}
index 83800ed..6155809 100644 (file)
@@ -188,15 +188,8 @@ struct alias_info
   struct alias_map_d **pointers;
   size_t num_pointers;
 
-  /* Variables that have been written to directly (i.e., not through a
-     pointer dereference).  */
-  struct pointer_set_t *written_vars;
-
-  /* Pointers that have been used in an indirect store operation.  */
-  struct pointer_set_t *dereferenced_ptrs_store;
-
-  /* Pointers that have been used in an indirect load operation.  */
-  struct pointer_set_t *dereferenced_ptrs_load;
+  /* Pointers that have been used in an indirect load/store operation.  */
+  struct pointer_set_t *dereferenced_ptrs;
 };
 
 
@@ -2073,9 +2066,7 @@ init_alias_info (void)
   ai->ssa_names_visited = sbitmap_alloc (num_ssa_names);
   sbitmap_zero (ai->ssa_names_visited);
   ai->processed_ptrs = VEC_alloc (tree, heap, 50);
-  ai->written_vars = pointer_set_create ();
-  ai->dereferenced_ptrs_store = pointer_set_create ();
-  ai->dereferenced_ptrs_load = pointer_set_create ();
+  ai->dereferenced_ptrs = pointer_set_create ();
 
   /* Clear out all memory reference stats.  */
   init_mem_ref_stats ();
@@ -2123,9 +2114,7 @@ delete_alias_info (struct alias_info *ai)
     free (ai->pointers[i]);
   free (ai->pointers);
 
-  pointer_set_destroy (ai->written_vars);
-  pointer_set_destroy (ai->dereferenced_ptrs_store);
-  pointer_set_destroy (ai->dereferenced_ptrs_load);
+  pointer_set_destroy (ai->dereferenced_ptrs);
   free (ai);
 
   delete_mem_ref_stats (cfun);
@@ -2361,23 +2350,18 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
        {
          struct alias_map_d *v_map;
          var_ann_t v_ann;
-         bool tag_stored_p, var_stored_p;
          
          v_map = ai->addressable_vars[j];
          var = v_map->var;
          v_ann = var_ann (var);
 
-         /* Skip memory tags and variables that have never been
-            written to.  We also need to check if the variables are
-            call-clobbered because they may be overwritten by
-            function calls.  */
-         tag_stored_p = pointer_set_contains (ai->written_vars, tag)
-                        || is_call_clobbered (tag);
-         var_stored_p = pointer_set_contains (ai->written_vars, var)
-                        || is_call_clobbered (var);
-         if (!tag_stored_p && !var_stored_p)
-           continue;
-            
+         /* We used to skip variables that have never been written to
+            if the memory tag has been never written to directly (or
+            either of them were call clobbered).  This is not enough
+            though, as this misses writes through the tags aliases.
+            So, for correctness we need to include any aliased
+            variable here.  */
+
          if (may_alias_p (p_map->var, p_map->set, var, v_map->set, false))
            {
              /* Add VAR to TAG's may-aliases set.  */
@@ -2618,13 +2602,8 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
          /* ???  For always executed direct dereferences we can
             apply TBAA-pruning to their escape set.  */
 
-         /* If this is a store operation, mark OP as being
-            dereferenced to store, otherwise mark it as being
-            dereferenced to load.  */
-         if (num_stores > 0)
-           pointer_set_insert (ai->dereferenced_ptrs_store, var);
-         else
-           pointer_set_insert (ai->dereferenced_ptrs_load, var);
+         /* Mark OP as being dereferenced.  */
+         pointer_set_insert (ai->dereferenced_ptrs, var);
 
          /* Update the frequency estimate for all the dereferences of
             pointer OP.  */
@@ -2649,7 +2628,7 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
          if (is_gimple_call (stmt)
              || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
            {
-             pointer_set_insert (ai->dereferenced_ptrs_store, var);
+             pointer_set_insert (ai->dereferenced_ptrs, var);
              pi->memory_tag_needed = 1;
            }
        }
@@ -2667,17 +2646,6 @@ update_alias_info_1 (gimple stmt, struct alias_info *ai)
 
       mem_ref_stats->num_mem_stmts++;
 
-      /* Add all decls written to to the list of written variables.  */
-      if (gimple_has_lhs (stmt)
-         && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME)
-       {
-         tree lhs = gimple_get_lhs (stmt);
-         while (handled_component_p (lhs))
-           lhs = TREE_OPERAND (lhs, 0);
-         if (DECL_P (lhs))
-           pointer_set_insert (ai->written_vars, lhs);
-       }
-
       /* Notice that we only update memory reference stats for symbols
         loaded and stored by the statement if the statement does not
         contain pointer dereferences and it is not a call/asm site.
@@ -2770,7 +2738,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
          /* Since we don't keep track of volatile variables, assume that
             these pointers are used in indirect store operations.  */
          if (TREE_THIS_VOLATILE (var))
-           pointer_set_insert (ai->dereferenced_ptrs_store, var);
+           pointer_set_insert (ai->dereferenced_ptrs, var);
 
          num_pointers++;
        }
@@ -2845,8 +2813,7 @@ setup_pointers_and_addressables (struct alias_info *ai)
          array and create a symbol memory tag for them.  */
       if (POINTER_TYPE_P (TREE_TYPE (var)))
        {
-         if ((pointer_set_contains (ai->dereferenced_ptrs_store, var)
-              || pointer_set_contains (ai->dereferenced_ptrs_load, var)))
+         if (pointer_set_contains (ai->dereferenced_ptrs, var))
            {
              tree tag, old_tag;
              var_ann_t t_ann;
@@ -2872,11 +2839,6 @@ setup_pointers_and_addressables (struct alias_info *ai)
 
              /* Associate the tag with pointer VAR.  */
              set_symbol_mem_tag (var, tag);
-
-             /* If pointer VAR has been used in a store operation,
-                then its memory tag must be marked as written-to.  */
-             if (pointer_set_contains (ai->dereferenced_ptrs_store, var))
-               pointer_set_insert (ai->written_vars, tag);
            }
          else
            {
@@ -3298,7 +3260,22 @@ get_smt_for (tree ptr, struct alias_info *ai)
   size_t i;
   tree tag;
   tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
-  alias_set_type tag_set = get_alias_set (tag_type);
+  alias_set_type tag_set;
+
+  /* Get the alias set to be used for the pointed-to memory.  If that
+     differs from what we would get from looking at the type adjust
+     the tag_type to void to make sure we get a proper alias set from
+     just looking at the SMT we create.  */
+  tag_set = get_alias_set (tag_type);
+  if (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr))
+      /* This is overly conservative but we do not want to assign
+         restrict alias sets here (which if they are not assigned
+         are -2 but still "known").  */
+      || DECL_POINTER_ALIAS_SET_KNOWN_P (ptr))
+    {
+      tag_set = 0;
+      tag_type = void_type_node;
+    }
 
   /* To avoid creating unnecessary memory tags, only create one memory tag
      per alias set class.  Note that it may be tempting to group
@@ -3329,7 +3306,8 @@ get_smt_for (tree ptr, struct alias_info *ai)
         artificial variable representing the memory location
         pointed-to by PTR.  */
       tag = symbol_mem_tag (ptr);
-      if (tag == NULL_TREE)
+      if (tag == NULL_TREE
+         || tag_set != get_alias_set (tag))
        tag = create_memory_tag (tag_type, true);
 
       /* Add PTR to the POINTERS array.  Note that we are not interested in