From: Richard Guenther Date: Wed, 4 Jan 2012 11:54:18 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.5.4~289 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c01400819dea3f07a421977dfe5914ea67ee02c4;p=thirdparty%2Fgcc.git backport: [multiple changes] 2012-01-04 Richard Guenther Backport from mainline 2012-01-04 Richard Guenther PR tree-optimization/49651 * tree-ssa-structalias.c (type_can_have_subvars): New function. (var_can_have_subvars): Use it. (get_constraint_for_1): Only consider subfields if there can be any. 2011-07-14 Richard Guenther PR tree-optimization/49651 * tree-ssa-structalias.c (get_constraint_for_1): Properly handle dereferences with subvariables. * gcc.dg/torture/pr49651.c: New testcase. From-SVN: r182870 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 148276d819f6..4a1a3e04f2f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2012-01-04 Richard Guenther + + Backport from mainline + 2012-01-04 Richard Guenther + + PR tree-optimization/49651 + * tree-ssa-structalias.c (type_can_have_subvars): New function. + (var_can_have_subvars): Use it. + (get_constraint_for_1): Only consider subfields if there + can be any. + + 2011-07-14 Richard Guenther + + PR tree-optimization/49651 + * tree-ssa-structalias.c (get_constraint_for_1): Properly + handle dereferences with subvariables. + 2012-01-03 Richard Guenther Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52d9121408ca..137f5af8adbf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2012-01-04 Richard Guenther + + Backport from mainline + 2011-07-14 Richard Guenther + + PR tree-optimization/49651 + * gcc.dg/torture/pr49651.c: New testcase. + 2012-01-03 Richard Guenther Backport from mainline diff --git a/gcc/testsuite/gcc.dg/torture/pr49651.c b/gcc/testsuite/gcc.dg/torture/pr49651.c new file mode 100644 index 000000000000..c58fe943c831 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr49651.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct X { + int *p; + int *q; +}; + +void __attribute__((noinline, noclone)) +foo (struct X x) { *x.q = 0; } + +volatile int what; +struct X y; + +int main() +{ + int i, j; + struct X x, *p; + x.p = &i; + x.q = &j; + if (what) + p = &y; + else + p = &x; + j = 1; + foo (*p); + if (j != 0) + abort (); + return 0; +} diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index b2ba385be0a7..0d39a3e90762 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -266,6 +266,7 @@ static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); static varinfo_t first_or_preceding_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); static varinfo_t lookup_vi_for_tree (tree); +static inline bool type_can_have_subvars (const_tree); /* Pool of variable info structures. */ static alloc_pool variable_info_pool; @@ -3187,10 +3188,51 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p, { case INDIRECT_REF: { + struct constraint_expr cs; + varinfo_t vi, curr; get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p, lhs_p); do_deref (results); - return; + + /* If we are not taking the address then make sure to process + all subvariables we might access. */ + if (address_p) + return; + + cs = *VEC_last (ce_s, *results); + if (cs.type == DEREF + && type_can_have_subvars (TREE_TYPE (t))) + { + /* For dereferences this means we have to defer it + to solving time. */ + VEC_last (ce_s, *results)->offset = UNKNOWN_OFFSET; + return; + } + if (cs.type != SCALAR) + return; + + vi = get_varinfo (cs.var); + curr = vi->next; + if (!vi->is_full_var + && curr) + { + unsigned HOST_WIDE_INT size; + if (host_integerp (TYPE_SIZE (TREE_TYPE (t)), 1)) + size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (t))); + else + size = -1; + for (; curr; curr = curr->next) + { + if (curr->offset - vi->offset < size) + { + cs.var = curr->id; + VEC_safe_push (ce_s, heap, *results, &cs); + } + else + break; + } + } + return; } case ARRAY_REF: case ARRAY_RANGE_REF: @@ -4201,6 +4243,15 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack) fieldoff_compare); } +/* Return true if T is a type that can have subvars. */ + +static inline bool +type_can_have_subvars (const_tree t) +{ + /* Aggregates without overlapping fields can have subvars. */ + return TREE_CODE (t) == RECORD_TYPE; +} + /* Return true if V is a tree that we can have subvars for. Normally, this is any aggregate type. Also complex types which are not gimple registers can have subvars. */ @@ -4216,11 +4267,7 @@ var_can_have_subvars (const_tree v) if (!DECL_P (v)) return false; - /* Aggregates without overlapping fields can have subvars. */ - if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE) - return true; - - return false; + return type_can_have_subvars (TREE_TYPE (v)); } /* Return true if T is a type that does contain pointers. */