]> gcc.gnu.org Git - gcc.git/commitdiff
re PR tree-optimization/45967 (gcc-4.5.x optimizes code with side-effects away)
authorRichard Guenther <rguenther@suse.de>
Mon, 18 Oct 2010 15:32:00 +0000 (15:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 18 Oct 2010 15:32:00 +0000 (15:32 +0000)
2010-10-18  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/45967
* tree-ssa-structalias.c (type_could_have_pointers): Remove.
(could_have_pointers): Likewise.
(handle_rhs_call, handle_const_call, handle_pure_call,
find_func_aliases, intra_create_variable_infos): Remove calls to them.
(struct fieldoff): Add must_have_pointers field.
(type_must_have_pointers): New function.
(field_must_have_pointers): Likewise.
(push_fields_onto_fieldstack): Remove must_have_pointers_p argument.
Adjust field merging.
(create_function_info_for): May-have-pointers of varinfo is
almost always true.
(create_variable_info_for_1): Likewise.

* gcc.dg/torture/pr45967.c: New testcase.
* gcc.dg/ipa/ipa-pta-10.c: Adjust.
* gcc.dg/ipa/ipa-pta-13.c: Likewise
* gcc.dg/torture/pr39074-2.c: Likewise
* gcc.dg/torture/pta-escape-1.c: Likewise
* gcc.dg/torture/pta-ptrarith-1.c: Likewise
* gcc.dg/tree-ssa/pta-callused.c: Likewise
* 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/tree-ssa/ssa-pre-21.c: Likewise

From-SVN: r165641

14 files changed:
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
gcc/testsuite/gcc.dg/torture/pr39074-2.c
gcc/testsuite/gcc.dg/torture/pr45967.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pta-escape-1.c
gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
gcc/testsuite/gcc.dg/tree-ssa/pta-callused.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/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c
gcc/tree-ssa-structalias.c

index d581c56bfd56f9ddfc78041ff521617ea9bd9786..55303f252203a5a33959606595e555d316e75399 100644 (file)
@@ -1,3 +1,19 @@
+2010-10-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/45967
+       * tree-ssa-structalias.c (type_could_have_pointers): Remove.
+       (could_have_pointers): Likewise.
+       (handle_rhs_call, handle_const_call, handle_pure_call,
+       find_func_aliases, intra_create_variable_infos): Remove calls to them.
+       (struct fieldoff): Add must_have_pointers field.
+       (type_must_have_pointers): New function.
+       (field_must_have_pointers): Likewise.
+       (push_fields_onto_fieldstack): Remove must_have_pointers_p argument.
+       Adjust field merging.
+       (create_function_info_for): May-have-pointers of varinfo is
+       almost always true.
+       (create_variable_info_for_1): Likewise.
+
 2010-10-18  Tejas Belagod  <tejas.belagod@arm.com>
 
        * config/arm/neon.md (neon_move_hi_quad_<mode>): Fix the order
index 4295e4e5a92465ae106477e539d5c6503564c336..6a2738f6aa00c680d4c80e7845f347cac294b2ea 100644 (file)
@@ -1,3 +1,18 @@
+2010-10-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/45967
+       * gcc.dg/torture/pr45967.c: New testcase.
+       * gcc.dg/ipa/ipa-pta-10.c: Adjust.
+       * gcc.dg/ipa/ipa-pta-13.c: Likewise
+       * gcc.dg/torture/pr39074-2.c: Likewise
+       * gcc.dg/torture/pta-escape-1.c: Likewise
+       * gcc.dg/torture/pta-ptrarith-1.c: Likewise
+       * gcc.dg/tree-ssa/pta-callused.c: Likewise
+       * 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/tree-ssa/ssa-pre-21.c: Likewise
+
 2010-10-18  Kai Tietz  <kai.tietz@onevision.com>
 
        * gfortran.dg/bessel_7.f90: Set xfail for mingw targets.
index 2dc6eae25d25c60eb15d4031324c435b46c9a032..6e4c3c512f6dcc6ba8de3b213441cdb3a1152a37 100644 (file)
@@ -26,5 +26,5 @@ int main()
 /* Verify we properly handle variadic arguments and do not let escape
    stuff through it.  */
 
-/* { dg-final { scan-ipa-dump "ESCAPED = { }" "pta" } } */
+/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL }" "pta" } } */
 /* { dg-final { cleanup-ipa-dump "pta" } } */
index 8c2c8b6183f2a59f635ac5ebf9d0eb57f4b9eb44..1e04bfc21186b04fbd369b5a1b01de437d56ae7a 100644 (file)
@@ -15,6 +15,8 @@ local_address_taken (int *p)
   *p = 1;
 }
 
+void *anyfn_global;
+
 /* Even though not referenced in this TU we should have added constraints
    for the initializer.  */
 /* { dg-final { scan-ipa-dump "ex = &local_address_taken" "pta" } } */
@@ -24,7 +26,7 @@ extern void link_error (void);
 
 int main()
 {
-  void (*anyfn)(int *) = (void (*)(int *))(__SIZE_TYPE__)x;
+  void (*anyfn)(int *) = (void (*)(int *))(__SIZE_TYPE__)anyfn_global;
   /* The following should cause local_address_taken to get &x
      as argument, but not local.  We shouldn't get &x added to
      arbitrary special sub-vars of local_address_taken though,
@@ -34,9 +36,13 @@ int main()
      We shouldn't get the functions sub-vars in the ESCAPED solution
      though, another missed-optimization.  This also causes the functions
      uses to be messed up even further.  */
-  /* { dg-final { scan-ipa-dump "local_address_taken.arg0 = { ESCAPED NONLOCAL y x }" "pta" } } */
-  /* { dg-final { scan-ipa-dump "local_address_taken.clobber = { ESCAPED NONLOCAL y x }" "pta" } } */
+  /* ???  As we don't expand the ESCAPED solution we either get x printed here
+     or not based on the phase of the moon.  */
+  /* { dg-final { scan-ipa-dump "local_address_taken.arg0 = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
+  /* { dg-final { scan-ipa-dump "local_address_taken.clobber = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
   /* { dg-final { scan-ipa-dump "local_address_taken.use = { }" "pta" { xfail *-*-* } } } */
+  /* ??? But make sure x really escaped.  */
+  /* { dg-final { scan-ipa-dump "ESCAPED = {\[^\n\}\]* x \[^\n\}\]*}" "pta" } } */
   (*anyfn) (&x);
   x = 0;
   local (&y);
index 0ca83120118e7e1f4740c069b4019c43e3f5e020..a90c5643dca55d9332a01110e3a2e8e250ed86b1 100644 (file)
@@ -30,5 +30,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "y.._., points-to non-local, points-to escaped, points-to vars: { i }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr45967.c b/gcc/testsuite/gcc.dg/torture/pr45967.c
new file mode 100644 (file)
index 0000000..0a5b206
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+extern void abort (void);
+void __attribute__((noinline,noclone))
+foo (void *p_)
+{
+  int *p;
+  int i;
+  for (i = 0; i < sizeof(int *); ++i)
+    ((char *)&p)[i] = ((char *)p_)[i];
+  *p = 1;
+}
+int main()
+{
+  int i = 0;
+  int *p = &i;
+  foo (&p);
+  if (i != 1)
+    abort ();
+  return 0;
+}
index 3929d97f2947e5bd965956f3dcd69b92c8fe6916..2aafe80b38f903cd744a8f97230fa3d333f38a17 100644 (file)
@@ -30,5 +30,5 @@ main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL i }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* i \[^\n\}\]*}" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index 2a8dc9e3037d32e051adb419c9e46b8b8bd0019c..d41868eb453b0a859b8a37c1d2ae7eb36e363c5b 100644 (file)
@@ -29,5 +29,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL f .* i }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* i f \[^\n\}\]*}" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index add5c87615297b30399ce64e175b558ec4dd7834..9c8ec3034f368dddddbb92d8b6dfc1bec182a6f8 100644 (file)
@@ -22,6 +22,6 @@ int bar (int b)
   return *foo (&q);
 }
 
-/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
+/* { dg-final { scan-tree-dump "CALLUSED = { ESCAPED NONLOCAL f.* i q }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
 
index 50d7357ef2536f59f710075673da4bf970bf5c19..7cc19be6c49c5ba773ebf8d982d0e817025c2b28 100644 (file)
@@ -33,5 +33,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to NULL, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index 226105e856edc7c2937e3d20c50896c02a519019..878352d269ca015eba904b5df7f3c8f0f98f397e 100644 (file)
@@ -34,5 +34,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to NULL, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index 15b06af12be0846eb867b5c262bae74ff0d85c35..8e779d8461e267f0c07b16c9a50278069dbf5a91 100644 (file)
@@ -38,5 +38,5 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to NULL, points-to vars: { x }" "alias" } } */
 /* { dg-final { cleanup-tree-dump "alias" } } */
index 65a73d2a0f3edd33e93fb0518754f1c3327a30cb..10efb12b4abecf2ac0168cff087cd6e8454838ad 100644 (file)
@@ -11,5 +11,5 @@ NumSift (long *array, unsigned long k)
 
 /* There should be only two loads left.  */
 
-/* { dg-final { scan-tree-dump-times "= \\\*D" 2 "pre" } } */
+/* { dg-final { scan-tree-dump-times "= \\\*D\[^\n;\]*;" 2 "pre" } } */
 /* { dg-final { cleanup-tree-dump "pre" } } */
index 707e31ca579ef43f2e50cf9063729703f33aed09..ed05178c23d47e70b779b3a943109693c1543a38 100644 (file)
@@ -2931,38 +2931,6 @@ process_constraint (constraint_t t)
     }
 }
 
-/* Return true if T is a type that could contain pointers.  */
-
-static bool
-type_could_have_pointers (tree type)
-{
-  if (POINTER_TYPE_P (type))
-    return true;
-
-  if (TREE_CODE (type) == ARRAY_TYPE)
-    return type_could_have_pointers (TREE_TYPE (type));
-
-  /* A function or method can consume pointers.
-     ???  We could be more precise here.  */
-  if (TREE_CODE (type) == FUNCTION_TYPE
-      || TREE_CODE (type) == METHOD_TYPE)
-    return true;
-
-  return AGGREGATE_TYPE_P (type);
-}
-
-/* Return true if T is a variable of a type that could contain
-   pointers.  */
-
-static bool
-could_have_pointers (tree 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
    structure.  */
@@ -3786,10 +3754,8 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
       tree arg = gimple_call_arg (stmt, i);
       int flags = gimple_call_arg_flags (stmt, i);
 
-      /* If the argument is not used or it does not contain pointers
-        we can ignore it.  */
-      if ((flags & EAF_UNUSED)
-         || !could_have_pointers (arg))
+      /* If the argument is not used we can ignore it.  */
+      if (flags & EAF_UNUSED)
        continue;
 
       /* As we compute ESCAPED context-insensitive we do not gain
@@ -3952,17 +3918,13 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
   for (k = 0; k < gimple_call_num_args (stmt); ++k)
     {
       tree arg = gimple_call_arg (stmt, k);
-
-      if (could_have_pointers (arg))
-       {
-         VEC(ce_s, heap) *argc = NULL;
-         unsigned i;
-         struct constraint_expr *argp;
-         get_constraint_for_rhs (arg, &argc);
-         FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
-           VEC_safe_push (ce_s, heap, *results, argp);
-         VEC_free(ce_s, heap, argc);
-       }
+      VEC(ce_s, heap) *argc = NULL;
+      unsigned i;
+      struct constraint_expr *argp;
+      get_constraint_for_rhs (arg, &argc);
+      FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
+       VEC_safe_push (ce_s, heap, *results, argp);
+      VEC_free(ce_s, heap, argc);
     }
 
   /* May return addresses of globals.  */
@@ -3986,16 +3948,12 @@ handle_pure_call (gimple stmt, VEC(ce_s, heap) **results)
   for (i = 0; i < gimple_call_num_args (stmt); ++i)
     {
       tree arg = gimple_call_arg (stmt, i);
-
-      if (could_have_pointers (arg))
+      if (!uses)
        {
-         if (!uses)
-           {
-             uses = get_call_use_vi (stmt);
-             make_transitive_closure_constraints (uses);
-           }
-         make_constraint_to (uses->id, arg);
+         uses = get_call_use_vi (stmt);
+         make_transitive_closure_constraints (uses);
        }
+      make_constraint_to (uses->id, arg);
     }
 
   /* The static chain is used as well.  */
@@ -4075,34 +4033,27 @@ find_func_aliases (gimple origt)
   /* Now build constraints expressions.  */
   if (gimple_code (t) == GIMPLE_PHI)
     {
-      gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (gimple_phi_result (t))));
+      size_t i;
+      unsigned int j;
 
-      /* Only care about pointers and structures containing
-        pointers.  */
-      if (could_have_pointers (gimple_phi_result (t)))
+      /* For a phi node, assign all the arguments to
+        the result.  */
+      get_constraint_for (gimple_phi_result (t), &lhsc);
+      for (i = 0; i < gimple_phi_num_args (t); i++)
        {
-         size_t i;
-         unsigned int j;
-
-         /* For a phi node, assign all the arguments to
-            the result.  */
-         get_constraint_for (gimple_phi_result (t), &lhsc);
-         for (i = 0; i < gimple_phi_num_args (t); i++)
-           {
-             tree strippedrhs = PHI_ARG_DEF (t, i);
+         tree strippedrhs = PHI_ARG_DEF (t, i);
 
-             STRIP_NOPS (strippedrhs);
-             get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
+         STRIP_NOPS (strippedrhs);
+         get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
 
-             FOR_EACH_VEC_ELT (ce_s, lhsc, j, c)
+         FOR_EACH_VEC_ELT (ce_s, lhsc, j, c)
+           {
+             struct constraint_expr *c2;
+             while (VEC_length (ce_s, rhsc) > 0)
                {
-                 struct constraint_expr *c2;
-                 while (VEC_length (ce_s, rhsc) > 0)
-                   {
-                     c2 = VEC_last (ce_s, rhsc);
-                     process_constraint (new_constraint (*c, *c2));
-                     VEC_pop (ce_s, rhsc);
-                   }
+                 c2 = VEC_last (ce_s, rhsc);
+                 process_constraint (new_constraint (*c, *c2));
+                 VEC_pop (ce_s, rhsc);
                }
            }
        }
@@ -4353,16 +4304,7 @@ find_func_aliases (gimple origt)
          else
            handle_rhs_call (t, &rhsc);
          if (gimple_call_lhs (t))
-           {
-             if (could_have_pointers (gimple_call_lhs (t)))
-               handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
-             /* Similar to conversions a result that is not a pointer
-                is an escape point for any pointer the function might
-                return.  */
-             else if (flags & (ECF_CONST|ECF_PURE
-                               |ECF_NOVOPS|ECF_LOOPING_CONST_OR_PURE))
-               make_constraints_to (escaped_id, rhsc);
-           }
+           handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
          VEC_free (ce_s, heap, rhsc);
        }
       else
@@ -4380,9 +4322,6 @@ find_func_aliases (gimple origt)
              struct constraint_expr *rhsp;
              tree arg = gimple_call_arg (t, j);
 
-             if (!could_have_pointers (arg))
-               continue;
-
              get_constraint_for_rhs (arg, &rhsc);
              lhs = get_function_part_constraint (fi, fi_parm_base + j);
              while (VEC_length (ce_s, rhsc) != 0)
@@ -4395,8 +4334,7 @@ find_func_aliases (gimple origt)
 
          /* If we are returning a value, assign it to the result.  */
          lhsop = gimple_call_lhs (t);
-         if (lhsop
-             && type_could_have_pointers (TREE_TYPE (lhsop)))
+         if (lhsop)
            {
              struct constraint_expr rhs;
              struct constraint_expr *lhsp;
@@ -4449,8 +4387,7 @@ find_func_aliases (gimple origt)
   /* Otherwise, just a regular assignment statement.  Only care about
      operations with pointer result, others are dealt with as escape
      points if they have pointer operands.  */
-  else if (is_gimple_assign (t)
-          && type_could_have_pointers (TREE_TYPE (gimple_assign_lhs (t))))
+  else if (is_gimple_assign (t))
     {
       /* Otherwise, just a regular assignment statement.  */
       tree lhsop = gimple_assign_lhs (t);
@@ -4460,7 +4397,6 @@ find_func_aliases (gimple origt)
        do_structure_copy (lhsop, rhsop);
       else
        {
-         struct constraint_expr temp;
          get_constraint_for (lhsop, &lhsc);
 
          if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
@@ -4481,10 +4417,19 @@ find_func_aliases (gimple origt)
            get_constraint_for_rhs (rhsop, &rhsc);
          else
            {
-             temp.type = ADDRESSOF;
-             temp.var = anything_id;
-             temp.offset = 0;
-             VEC_safe_push (ce_s, heap, rhsc, &temp);
+             /* All other operations are merges.  */
+             VEC (ce_s, heap) *tmp = NULL;
+             struct constraint_expr *rhsp;
+             unsigned i, j;
+             get_constraint_for_rhs (gimple_assign_rhs1 (t), &rhsc);
+             for (i = 2; i < gimple_num_ops (t); ++i)
+               {
+                 get_constraint_for_rhs (gimple_op (t, i), &tmp);
+                 FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
+                   VEC_safe_push (ce_s, heap, rhsc, rhsp);
+                 VEC_truncate (ce_s, tmp, 0);
+               }
+             VEC_free (ce_s, heap, tmp);
            }
          process_all_all_constraints (lhsc, rhsc);
        }
@@ -4505,17 +4450,9 @@ find_func_aliases (gimple origt)
        make_constraint_from_restrict (get_vi_for_tree (lhsop),
                                       "CAST_RESTRICT");
     }
-  /* For conversions of pointers to non-pointers the pointer escapes.  */
-  else if (gimple_assign_cast_p (t)
-          && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (t)))
-          && !POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (t))))
-    {
-      make_escape_constraint (gimple_assign_rhs1 (t));
-    }
   /* Handle escapes through return.  */
   else if (gimple_code (t) == GIMPLE_RETURN
-          && gimple_return_retval (t) != NULL_TREE
-          && could_have_pointers (gimple_return_retval (t)))
+          && gimple_return_retval (t) != NULL_TREE)
     {
       fi = NULL;
       if (!in_ipa_mode
@@ -4561,7 +4498,7 @@ find_func_aliases (gimple origt)
 
          /* The asm may read global memory, so outputs may point to
             any global memory.  */
-         if (op && could_have_pointers (op))
+         if (op)
            {
              VEC(ce_s, heap) *lhsc = NULL;
              struct constraint_expr rhsc, *lhsp;
@@ -4591,7 +4528,7 @@ find_func_aliases (gimple origt)
          /* Strictly we'd only need the constraint to ESCAPED if
             the asm clobbers memory, otherwise using something
             along the lines of per-call clobbers/uses would be enough.  */
-         else if (op && could_have_pointers (op))
+         else if (op)
            make_escape_constraint (op);
        }
     }
@@ -4960,6 +4897,8 @@ struct fieldoff
 
   unsigned has_unknown_size : 1;
 
+  unsigned must_have_pointers : 1;
+
   unsigned may_have_pointers : 1;
 
   unsigned only_restrict_pointers : 1;
@@ -5021,6 +4960,32 @@ var_can_have_subvars (const_tree v)
   return false;
 }
 
+/* Return true if T is a type that does contain pointers.  */
+
+static bool
+type_must_have_pointers (tree type)
+{
+  if (POINTER_TYPE_P (type))
+    return true;
+
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    return type_must_have_pointers (TREE_TYPE (type));
+
+  /* A function or method can have pointers as arguments, so track
+     those separately.  */
+  if (TREE_CODE (type) == FUNCTION_TYPE
+      || TREE_CODE (type) == METHOD_TYPE)
+    return true;
+
+  return false;
+}
+
+static bool
+field_must_have_pointers (tree t)
+{
+  return type_must_have_pointers (TREE_TYPE (t));
+}
+
 /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
    the fields of TYPE onto fieldstack, recording their offsets along
    the way.
@@ -5032,7 +4997,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, bool must_have_pointers_p)
+                            HOST_WIDE_INT offset)
 {
   tree field;
   bool empty_p = true;
@@ -5057,8 +5022,7 @@ 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,
-                    must_have_pointers_p)
+                   (TREE_TYPE (field), fieldstack, offset + foff)
                 && (DECL_SIZE (field)
                     && !integer_zerop (DECL_SIZE (field))))
          /* Empty structures may have actual size, like in C++.  So
@@ -5070,6 +5034,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
          {
            fieldoff_s *pair = NULL;
            bool has_unknown_size = false;
+           bool must_have_pointers_p;
 
            if (!VEC_empty (fieldoff_s, *fieldstack))
              pair = VEC_last (fieldoff_s, *fieldstack);
@@ -5079,13 +5044,13 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
              has_unknown_size = true;
 
            /* If adjacent fields do not contain pointers merge them.  */
+           must_have_pointers_p = field_must_have_pointers (field);
            if (pair
-               && !pair->may_have_pointers
-               && !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->must_have_pointers
+               && !pair->has_unknown_size
+               && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
              {
                pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
              }
@@ -5098,8 +5063,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
-                 = must_have_pointers_p || could_have_pointers (field);
+               pair->must_have_pointers = must_have_pointers_p;
+               pair->may_have_pointers = true;
                pair->only_restrict_pointers
                  = (!has_unknown_size
                     && POINTER_TYPE_P (TREE_TYPE (field))
@@ -5245,7 +5210,7 @@ create_function_info_for (tree decl, const char *name)
       resultvi->fullsize = vi->fullsize;
       resultvi->is_full_var = true;
       if (DECL_RESULT (decl))
-       resultvi->may_have_pointers = could_have_pointers (DECL_RESULT (decl));
+       resultvi->may_have_pointers = true;
       gcc_assert (prev_vi->offset < resultvi->offset);
       prev_vi->next = resultvi;
       prev_vi = resultvi;
@@ -5275,7 +5240,7 @@ create_function_info_for (tree decl, const char *name)
       argvi->is_full_var = true;
       argvi->fullsize = vi->fullsize;
       if (arg)
-       argvi->may_have_pointers = could_have_pointers (arg);
+       argvi->may_have_pointers = true;
       gcc_assert (prev_vi->offset < argvi->offset);
       prev_vi->next = argvi;
       prev_vi = argvi;
@@ -5359,7 +5324,7 @@ create_variable_info_for_1 (tree decl, const char *name)
       vi->fullsize = ~0;
       vi->is_unknown_size_var = true;
       vi->is_full_var = true;
-      vi->may_have_pointers = could_have_pointers (decl);
+      vi->may_have_pointers = true;
       return vi;
     }
 
@@ -5376,10 +5341,7 @@ create_variable_info_for_1 (tree decl, const char *name)
       bool notokay = false;
       unsigned int i;
 
-      push_fields_onto_fieldstack (decl_type, &fieldstack, 0,
-                                  TREE_PUBLIC (decl)
-                                  || DECL_EXTERNAL (decl)
-                                  || TREE_ADDRESSABLE (decl));
+      push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
 
       for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
        if (fo->has_unknown_size
@@ -5414,7 +5376,7 @@ create_variable_info_for_1 (tree decl, const char *name)
     {
       vi = new_var_info (decl, name);
       vi->offset = 0;
-      vi->may_have_pointers = could_have_pointers (decl);
+      vi->may_have_pointers = true;
       vi->fullsize = TREE_INT_CST_LOW (declsize);
       vi->size = vi->fullsize;
       vi->is_full_var = true;
@@ -5558,9 +5520,6 @@ intra_create_variable_infos (void)
     {
       varinfo_t p;
 
-      if (!could_have_pointers (t))
-       continue;
-
       /* For restrict qualified pointers to objects passed by
          reference build a real representative for the pointed-to object.  */
       if (DECL_BY_REFERENCE (t)
This page took 0.146301 seconds and 5 git commands to generate.