Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:agentdero:ada
gcc45
pr45967.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr45967.diff of Package gcc45
2011-03-02 Richard Guenther <rguenther@suse.de> Backport from mainline 2011-02-10 Richard Guenther <rguenther@suse.de> * tree-ssa-structalias.c (bitpos_of_field): Use BITS_PER_UNIT, not 8. 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/torture/pr45967-2.c: Likewise. * gcc.dg/torture/pr45967-3.c: Likewise. * gcc.dg/torture/pr39074-2.c: Adjust. * 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-12 Richard Guenther <rguenther@suse.de> * tree-ssa-structalias.c (get_constraint_for_1): Constants only point to nonlocal, not anything. Index: gcc/testsuite/gcc.dg/torture/pr39074-2.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr39074-2.c.orig 2010-10-13 13:31:31.000000000 +0200 --- gcc/testsuite/gcc.dg/torture/pr39074-2.c 2010-10-18 16:04:29.000000000 +0200 *************** int main() *** 30,34 **** return 0; } ! /* { dg-final { scan-tree-dump "y.._., points-to non-local, points-to escaped, points-to vars: { i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 30,34 ---- return 0; } ! /* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/torture/pr45967.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- gcc/testsuite/gcc.dg/torture/pr45967.c 2010-10-18 13:33:30.000000000 +0200 *************** *** 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: gcc/testsuite/gcc.dg/torture/pta-escape-1.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pta-escape-1.c.orig 2010-05-06 10:51:58.000000000 +0200 --- gcc/testsuite/gcc.dg/torture/pta-escape-1.c 2010-10-18 16:07:15.000000000 +0200 *************** main() *** 30,34 **** return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 30,34 ---- return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* i \[^\n\}\]*}" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c.orig 2008-07-07 17:46:49.000000000 +0200 --- gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c 2010-10-18 16:12:21.000000000 +0200 *************** int main() *** 29,33 **** return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL f .* i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 29,33 ---- return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED = {\[^\n\}\]* i f \[^\n\}\]*}" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c.orig 2010-10-13 13:31:31.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c 2010-10-18 15:21:31.000000000 +0200 *************** int bar (int b) *** 22,27 **** return *foo (&q); } ! /* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 22,27 ---- return *foo (&q); } ! /* { dg-final { scan-tree-dump "CALLUSED = { ESCAPED NONLOCAL f.* i q }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c.orig 2010-05-06 10:51:58.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c 2010-10-18 15:24:01.000000000 +0200 *************** int main() *** 33,37 **** return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 33,37 ---- return 0; } ! /* { 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: gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c.orig 2010-05-06 10:51:58.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c 2010-10-18 15:24:33.000000000 +0200 *************** int main() *** 34,38 **** return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 34,38 ---- return 0; } ! /* { 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: gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c.orig 2010-05-06 10:51:58.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c 2010-10-18 15:25:14.000000000 +0200 *************** int main() *** 38,42 **** return 0; } ! /* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 38,42 ---- return 0; } ! /* { 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: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c.orig 2008-10-13 10:57:54.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c 2010-10-18 15:27:24.000000000 +0200 *************** NumSift (long *array, unsigned long k) *** 11,15 **** /* There should be only two loads left. */ ! /* { dg-final { scan-tree-dump-times "= \\\*D" 2 "pre" } } */ /* { dg-final { cleanup-tree-dump "pre" } } */ --- 11,15 ---- /* There should be only two loads left. */ ! /* { dg-final { scan-tree-dump-times "= \\\*D\[^\n;\]*;" 2 "pre" } } */ /* { dg-final { cleanup-tree-dump "pre" } } */ Index: gcc/testsuite/gcc.dg/torture/pr45967-2.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr45967-2.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr45967-2.c (revision 0) *************** *** 0 **** --- 1,24 ---- + /* { dg-do run } */ + + extern void abort (void); + int b; + void + foo (void *p_, int *q) + { + int *p; + int i; + for (i = 0; i < sizeof(int *); ++i) + ((char *)&p)[i] = ((char *)p_)[i]; + if (b) + p = q; + *p = 1; + } + int main() + { + int i = 0, j; + int *p = &i; + foo (&p, &j); + if (i != 1) + abort (); + return 0; + } Index: gcc/testsuite/gcc.dg/torture/pr45967-3.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr45967-3.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr45967-3.c (revision 0) *************** *** 0 **** --- 1,21 ---- + /* { dg-do run } */ + + extern void abort (void); + void + 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: gcc/tree-ssa-structalias.c =================================================================== *** gcc/tree-ssa-structalias.c (revision 170613) --- gcc/tree-ssa-structalias.c (working copy) *************** process_constraint (constraint_t t) *** 2788,2820 **** } } - /* 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)); - - 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. */ --- 2788,2793 ---- *************** bitpos_of_field (const tree fdecl) *** 2826,2832 **** || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0)) return -1; ! return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * 8 + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl))); } --- 2799,2805 ---- || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0)) return -1; ! return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl))); } *************** get_constraint_for_1 (tree t, VEC (ce_s, *** 3167,3180 **** in that case *NULL does not fail, so it _should_ alias *anything. It is not worth adding a new option or renaming the existing one, since this case is relatively obscure. */ ! if (flag_delete_null_pointer_checks ! && ((TREE_CODE (t) == INTEGER_CST ! && integer_zerop (t)) ! /* The only valid CONSTRUCTORs in gimple with pointer typed ! elements are zero-initializer. */ ! || TREE_CODE (t) == CONSTRUCTOR)) { ! temp.var = nothing_id; temp.type = ADDRESSOF; temp.offset = 0; VEC_safe_push (ce_s, heap, *results, &temp); --- 3140,3157 ---- in that case *NULL does not fail, so it _should_ alias *anything. It is not worth adding a new option or renaming the existing one, since this case is relatively obscure. */ ! if ((TREE_CODE (t) == INTEGER_CST ! && integer_zerop (t)) ! /* The only valid CONSTRUCTORs in gimple with pointer typed ! elements are zero-initializer. But in IPA mode we also ! process global initializers, so verify at least. */ ! || (TREE_CODE (t) == CONSTRUCTOR ! && CONSTRUCTOR_NELTS (t) == 0)) { ! if (flag_delete_null_pointer_checks) ! temp.var = nothing_id; ! else ! temp.var = nonlocal_id; temp.type = ADDRESSOF; temp.offset = 0; VEC_safe_push (ce_s, heap, *results, &temp); *************** get_constraint_for_1 (tree t, VEC (ce_s, *** 3247,3252 **** --- 3224,3238 ---- get_constraint_for_ssa_var (t, results, address_p); return; } + case tcc_constant: + { + /* We cannot refer to automatic variables through constants. */ + temp.type = ADDRESSOF; + temp.var = nonlocal_id; + temp.offset = 0; + VEC_safe_push (ce_s, heap, *results, &temp); + return; + } default:; } *************** handle_rhs_call (gimple stmt, VEC(ce_s, *** 3502,3509 **** /* Find those pointers being passed, and make sure they end up pointing to anything. */ ! if (could_have_pointers (arg)) ! make_escape_constraint (arg); } /* The static chain escapes as well. */ --- 3488,3494 ---- /* Find those pointers being passed, and make sure they end up pointing to anything. */ ! make_escape_constraint (arg); } /* The static chain escapes as well. */ *************** handle_const_call (gimple stmt, VEC(ce_s *** 3603,3619 **** 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 (i = 0; VEC_iterate (ce_s, argc, i, argp); ++i) ! VEC_safe_push (ce_s, heap, *results, argp); ! VEC_free(ce_s, heap, argc); ! } } /* May return addresses of globals. */ --- 3588,3600 ---- for (k = 0; k < gimple_call_num_args (stmt); ++k) { tree arg = gimple_call_arg (stmt, k); ! VEC(ce_s, heap) *argc = NULL; ! unsigned i; ! struct constraint_expr *argp; ! get_constraint_for_rhs (arg, &argc); ! for (i = 0; VEC_iterate (ce_s, argc, i, argp); ++i) ! VEC_safe_push (ce_s, heap, *results, argp); ! VEC_free(ce_s, heap, argc); } /* May return addresses of globals. */ *************** handle_pure_call (gimple stmt, VEC(ce_s, *** 3637,3648 **** for (i = 0; i < gimple_call_num_args (stmt); ++i) { tree arg = gimple_call_arg (stmt, i); ! ! if (could_have_pointers (arg)) ! { ! make_constraint_to (callused_id, arg); ! need_callused = true; ! } } /* The static chain is used as well. */ --- 3618,3625 ---- for (i = 0; i < gimple_call_num_args (stmt); ++i) { tree arg = gimple_call_arg (stmt, i); ! make_constraint_to (callused_id, arg); ! need_callused = true; } /* The static chain is used as well. */ *************** find_func_aliases (gimple origt) *** 3682,3715 **** /* Now build constraints expressions. */ if (gimple_code (t) == GIMPLE_PHI) { ! gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (gimple_phi_result (t)))); ! /* Only care about pointers and structures containing ! pointers. */ ! if (could_have_pointers (gimple_phi_result (t))) ! { ! 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); ! STRIP_NOPS (strippedrhs); ! get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); ! for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++) { ! 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); ! } } } } --- 3659,3685 ---- /* Now build constraints expressions. */ if (gimple_code (t) == GIMPLE_PHI) { ! 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); ! STRIP_NOPS (strippedrhs); ! get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); ! for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++) ! { ! 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); } } } *************** find_func_aliases (gimple origt) *** 3858,3873 **** else handle_rhs_call (t, &rhsc); if (gimple_call_lhs (t)) ! { ! if (could_have_pointers (gimple_call_lhs (t))) ! handle_lhs_call (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); ! } VEC_free (ce_s, heap, rhsc); } else --- 3828,3834 ---- else handle_rhs_call (t, &rhsc); if (gimple_call_lhs (t)) ! handle_lhs_call (gimple_call_lhs (t), flags, rhsc, fndecl); VEC_free (ce_s, heap, rhsc); } else *************** find_func_aliases (gimple origt) *** 3950,3957 **** /* 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)))) { /* Otherwise, just a regular assignment statement. */ tree lhsop = gimple_assign_lhs (t); --- 3911,3917 ---- /* 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)) { /* Otherwise, just a regular assignment statement. */ tree lhsop = gimple_assign_lhs (t); *************** find_func_aliases (gimple origt) *** 3961,3983 **** do_structure_copy (lhsop, rhsop); else { ! struct constraint_expr temp; get_constraint_for (lhsop, &lhsc); ! if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), gimple_assign_rhs2 (t), &rhsc); ! else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t)) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) || gimple_assign_single_p (t)) 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); } process_all_all_constraints (lhsc, rhsc); } --- 3921,3965 ---- do_structure_copy (lhsop, rhsop); else { ! enum tree_code code = gimple_assign_rhs_code (t); ! get_constraint_for (lhsop, &lhsc); ! if (code == POINTER_PLUS_EXPR) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), gimple_assign_rhs2 (t), &rhsc); ! else if (code == BIT_AND_EXPR ! && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) ! { ! /* Aligning a pointer via a BIT_AND_EXPR is offsetting ! the pointer. Handle it by offsetting it by UNKNOWN. */ ! get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), ! NULL_TREE, &rhsc); ! } ! else if ((CONVERT_EXPR_CODE_P (code) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) || gimple_assign_single_p (t)) get_constraint_for_rhs (rhsop, &rhsc); + else if (truth_value_p (code)) + /* Truth value results are not pointer (parts). Or at least + very very unreasonable obfuscation of a part. */ + ; else { ! /* 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 (j = 0; VEC_iterate (ce_s, tmp, j, rhsp); ++j) ! 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); } *************** find_func_aliases (gimple origt) *** 3996,4012 **** 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))) { make_escape_constraint (gimple_return_retval (t)); } --- 3978,3986 ---- make_constraint_from_restrict (get_vi_for_tree (lhsop), "CAST_RESTRICT"); } /* Handle escapes through return. */ else if (gimple_code (t) == GIMPLE_RETURN ! && gimple_return_retval (t) != NULL_TREE) { make_escape_constraint (gimple_return_retval (t)); } *************** find_func_aliases (gimple origt) *** 4037,4043 **** /* The asm may read global memory, so outputs may point to any global memory. */ ! if (op && could_have_pointers (op)) { VEC(ce_s, heap) *lhsc = NULL; struct constraint_expr rhsc, *lhsp; --- 4011,4017 ---- /* The asm may read global memory, so outputs may point to any global memory. */ ! if (op) { VEC(ce_s, heap) *lhsc = NULL; struct constraint_expr rhsc, *lhsp; *************** find_func_aliases (gimple origt) *** 4067,4073 **** /* Strictly we'd only need the constraint to ESCAPED if the asm clobbers memory, otherwise using CALLUSED would be enough. */ ! else if (op && could_have_pointers (op)) make_escape_constraint (op); } } --- 4041,4047 ---- /* Strictly we'd only need the constraint to ESCAPED if the asm clobbers memory, otherwise using CALLUSED would be enough. */ ! else if (op) make_escape_constraint (op); } } *************** struct fieldoff *** 4192,4197 **** --- 4166,4173 ---- unsigned has_unknown_size : 1; + unsigned must_have_pointers : 1; + unsigned may_have_pointers : 1; unsigned only_restrict_pointers : 1; *************** var_can_have_subvars (const_tree v) *** 4256,4261 **** --- 4232,4264 ---- 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. *************** var_can_have_subvars (const_tree v) *** 4266,4272 **** static int push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ! HOST_WIDE_INT offset, bool must_have_pointers_p) { tree field; int count = 0; --- 4269,4275 ---- static int push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, ! HOST_WIDE_INT offset) { tree field; int count = 0; *************** push_fields_onto_fieldstack (tree type, *** 4292,4299 **** || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) push = true; else if (!(pushed = push_fields_onto_fieldstack ! (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 --- 4295,4301 ---- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) push = true; else if (!(pushed = push_fields_onto_fieldstack ! (TREE_TYPE (field), fieldstack, offset + foff)) && (DECL_SIZE (field) && !integer_zerop (DECL_SIZE (field)))) /* Empty structures may have actual size, like in C++. So *************** push_fields_onto_fieldstack (tree type, *** 4305,4310 **** --- 4307,4313 ---- { 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); *************** push_fields_onto_fieldstack (tree type, *** 4325,4339 **** has_unknown_size = true; /* If adjacent fields do not contain pointers merge them. */ 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 = VEC_last (fieldoff_s, *fieldstack); pair->size += TREE_INT_CST_LOW (DECL_SIZE (field)); } else --- 4328,4341 ---- has_unknown_size = true; /* If adjacent fields do not contain pointers merge them. */ + must_have_pointers_p = field_must_have_pointers (field); if (pair && !has_unknown_size && !must_have_pointers_p ! && !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)); } else *************** push_fields_onto_fieldstack (tree type, *** 4345,4352 **** 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->only_restrict_pointers = (!has_unknown_size && POINTER_TYPE_P (TREE_TYPE (field)) --- 4347,4354 ---- pair->size = TREE_INT_CST_LOW (DECL_SIZE (field)); else pair->size = -1; ! 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)) *************** create_variable_info_for (tree decl, con *** 4512,4528 **** VEC (fieldoff_s,heap) *fieldstack = NULL; if (var_can_have_subvars (decl) && use_field_sensitive) ! push_fields_onto_fieldstack (decl_type, &fieldstack, 0, ! TREE_PUBLIC (decl) ! || DECL_EXTERNAL (decl) ! || TREE_ADDRESSABLE (decl)); /* If the variable doesn't have subvars, we may end up needing to sort the field list and create fake variables for all the fields. */ vi = new_var_info (decl, name); vi->offset = 0; ! vi->may_have_pointers = could_have_pointers (decl); if (!declsize || !host_integerp (declsize, 1)) { --- 4514,4527 ---- VEC (fieldoff_s,heap) *fieldstack = NULL; if (var_can_have_subvars (decl) && use_field_sensitive) ! push_fields_onto_fieldstack (decl_type, &fieldstack, 0); /* If the variable doesn't have subvars, we may end up needing to sort the field list and create fake variables for all the fields. */ vi = new_var_info (decl, name); vi->offset = 0; ! vi->may_have_pointers = true; if (!declsize || !host_integerp (declsize, 1)) { *************** intra_create_variable_infos (void) *** 4695,4703 **** { 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) --- 4694,4699 ----
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor