summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-05-06 08:53:19 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-05-06 08:53:19 +0000
commit7a3ffe9974993112c5262808d7c7b5a52ee69304 (patch)
treefb40fc61a7dd82108d5aaff3589d2f98c91881e5 /gcc/tree-ssa-structalias.c
parent8d8103295d80e9ef11e5eee58cb3e29e1709f299 (diff)
downloadgcc-7a3ffe9974993112c5262808d7c7b5a52ee69304.tar.gz
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. * 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
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index f688d9bcae5..19aa5db5f34 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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