diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr39074-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr45967.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pta-escape-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 221 |
14 files changed, 160 insertions, 143 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d581c56..55303f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4295e4e..6a2738f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c index 2dc6eae..6e4c3c5 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c index 8c2c8b6..1e04bfc 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c @@ -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); diff --git a/gcc/testsuite/gcc.dg/torture/pr39074-2.c b/gcc/testsuite/gcc.dg/torture/pr39074-2.c index 0ca8312..a90c564 100644 --- a/gcc/testsuite/gcc.dg/torture/pr39074-2.c +++ b/gcc/testsuite/gcc.dg/torture/pr39074-2.c @@ -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 index 0000000..0a5b206 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr45967.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/torture/pta-escape-1.c b/gcc/testsuite/gcc.dg/torture/pta-escape-1.c index 3929d97..2aafe80 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-escape-1.c +++ b/gcc/testsuite/gcc.dg/torture/pta-escape-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c index 2a8dc9e..d41868e 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c +++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c index add5c87..9c8ec30 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c index 50d7357..7cc19be 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c index 226105e..878352d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c index 15b06af..8e779d8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c index 65a73d2..10efb12 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c @@ -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" } } */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 707e31c..ed05178 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -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) |