OSDN Git Service

2010-05-06 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 May 2010 08:53:19 +0000 (08:53 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 May 2010 08:53:19 +0000 (08:53 +0000)
PR tree-optimization/43987
* tree-ssa-structalias.c (could_have_pointers): For possibly
address-taken variables force pointers to be recorded.
(create_variable_info_for_1): Likewise.
(push_fields_onto_fieldstack): Pass in wheter all fields
must have pointers.
(find_func_aliases): Query types instead of vars whether
they contain pointers where appropriate.

* gcc.c-torture/execute/pr43987.c: New testcase.
* gcc.dg/torture/pta-escape-1.c: Adjust.
* gcc.dg/tree-ssa/pta-escape-1.c: Likewise.
* gcc.dg/tree-ssa/pta-escape-2.c: Likewise.
* gcc.dg/tree-ssa/pta-escape-3.c: Likewise.
* gcc.dg/ipa/ipa-pta-11.c: Likewise.

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

gcc/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr43987.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
gcc/testsuite/gcc.dg/torture/pta-escape-1.c
gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
gcc/tree-ssa-structalias.c

index 3994866..4d0c54a 100644 (file)
@@ -1,3 +1,14 @@
+2010-05-06  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43987
+       * tree-ssa-structalias.c (could_have_pointers): For possibly
+       address-taken variables force pointers to be recorded.
+       (create_variable_info_for_1): Likewise.
+       (push_fields_onto_fieldstack): Pass in wheter all fields
+       must have pointers.
+       (find_func_aliases): Query types instead of vars whether
+       they contain pointers where appropriate.
+
 2010-05-06  Jan Hubicka  <jh@suse.cz>
 
        * cgraphbuild.c (record_reference_ctx): Add varpool_node.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr43987.c b/gcc/testsuite/gcc.c-torture/execute/pr43987.c
new file mode 100644 (file)
index 0000000..ee41bdf
--- /dev/null
@@ -0,0 +1,20 @@
+char B[256 * sizeof(void *)];
+typedef void *FILE;
+typedef struct globals {
+    int c;
+    FILE *l;
+} __attribute__((may_alias)) T;
+void add_input_file(FILE *file)
+{
+  (*(T*)&B).l[0] = file;
+}
+extern void abort (void);
+int main()
+{
+  FILE x;
+  (*(T*)&B).l = &x;
+  add_input_file ((void *)-1);
+  if ((*(T*)&B).l[0] != (void *)-1)
+    abort ();
+  return 0;
+}
index 6ef7438..947ab81 100644 (file)
@@ -29,5 +29,5 @@ int main()
 /* It isn't clear if the escape if l is strictly necessary, if it were
    we should have i, r and s in ESCAPED as well.  */
 
-/* { dg-final { scan-ipa-dump "ESCAPED = { l k }" "pta" } } */
+/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta" } } */
 /* { dg-final { cleanup-ipa-dump "pta" } } */
index 39aefb5..3929d97 100644 (file)
@@ -30,5 +30,5 @@ main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED = { i }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL i }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index ee8a84b..50d7357 100644 (file)
@@ -33,5 +33,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index ad5ed2e..226105e 100644 (file)
@@ -34,5 +34,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index ea11c8a..15b06af 100644 (file)
@@ -38,5 +38,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index f688d9b..19aa5db 100644 (file)
@@ -2959,7 +2959,11 @@ type_could_have_pointers (tree type)
 static bool
 could_have_pointers (tree t)
 {
-  return type_could_have_pointers (TREE_TYPE (t));
+  return (((TREE_CODE (t) == VAR_DECL
+           || TREE_CODE (t) == PARM_DECL
+           || TREE_CODE (t) == RESULT_DECL)
+          && (TREE_PUBLIC (t) || DECL_EXTERNAL (t) || TREE_ADDRESSABLE (t)))
+         || type_could_have_pointers (TREE_TYPE (t)));
 }
 
 /* Return the position, in bits, of FIELD_DECL from the beginning of its
@@ -4232,7 +4236,7 @@ find_func_aliases (gimple origt)
          /* If we are returning a value, assign it to the result.  */
          lhsop = gimple_call_lhs (t);
          if (lhsop
-             && could_have_pointers (lhsop))
+             && type_could_have_pointers (TREE_TYPE (lhsop)))
            {
              struct constraint_expr rhs;
              struct constraint_expr *lhsp;
@@ -4286,7 +4290,7 @@ find_func_aliases (gimple origt)
      operations with pointer result, others are dealt with as escape
      points if they have pointer operands.  */
   else if (is_gimple_assign (t)
-          && could_have_pointers (gimple_assign_lhs (t)))
+          && type_could_have_pointers (TREE_TYPE (gimple_assign_lhs (t))))
     {
       /* Otherwise, just a regular assignment statement.  */
       tree lhsop = gimple_assign_lhs (t);
@@ -4855,7 +4859,7 @@ var_can_have_subvars (const_tree v)
 
 static bool
 push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
-                            HOST_WIDE_INT offset)
+                            HOST_WIDE_INT offset, bool must_have_pointers_p)
 {
   tree field;
   bool empty_p = true;
@@ -4880,7 +4884,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
            || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
          push = true;
        else if (!push_fields_onto_fieldstack
-                   (TREE_TYPE (field), fieldstack, offset + foff)
+                   (TREE_TYPE (field), fieldstack, offset + foff,
+                    must_have_pointers_p)
                 && (DECL_SIZE (field)
                     && !integer_zerop (DECL_SIZE (field))))
          /* Empty structures may have actual size, like in C++.  So
@@ -4906,6 +4911,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
                && !pair->has_unknown_size
                && !has_unknown_size
                && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff
+               && !must_have_pointers_p
                && !could_have_pointers (field))
              {
                pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
@@ -4919,7 +4925,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
                  pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
                else
                  pair->size = -1;
-               pair->may_have_pointers = could_have_pointers (field);
+               pair->may_have_pointers
+                 = must_have_pointers_p || could_have_pointers (field);
                pair->only_restrict_pointers
                  = (!has_unknown_size
                     && POINTER_TYPE_P (TREE_TYPE (field))
@@ -5196,7 +5203,10 @@ create_variable_info_for_1 (tree decl, const char *name)
       bool notokay = false;
       unsigned int i;
 
-      push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
+      push_fields_onto_fieldstack (decl_type, &fieldstack, 0,
+                                  TREE_PUBLIC (decl)
+                                  || DECL_EXTERNAL (decl)
+                                  || TREE_ADDRESSABLE (decl));
 
       for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
        if (fo->has_unknown_size