From 8ee09896ce9212e1506256adeb41bf12877dc9d6 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 15 Jun 2019 20:33:26 +0200 Subject: [PATCH] alias-access-path-2.c: New testcase. * gcc.dg/tree-ssa/alias-access-path-2.c: New testcase. * tree-ssa-alias.c (alias_stats): Add nonoverlapping_component_refs_p_may_alias, nonoverlapping_component_refs_p_no_alias, nonoverlapping_component_refs_of_decl_p_may_alias, nonoverlapping_component_refs_of_decl_p_no_alias. (dump_alias_stats): Dump them. (nonoverlapping_component_refs_of_decl_p): Add stats. (nonoverlapping_component_refs_p): Add stats; do not stop on first ARRAY_REF. From-SVN: r272329 --- gcc/ChangeLog | 12 ++ gcc/testsuite/ChangeLog | 4 + .../gcc.dg/tree-ssa/alias-access-path-2.c | 22 +++ gcc/tree-ssa-alias.c | 135 ++++++++++++++---- 4 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 921e899f534..e3799aec817 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-06-15 Jan Hubicka + + * tree-ssa-alias.c (alias_stats): Add + nonoverlapping_component_refs_p_may_alias, + nonoverlapping_component_refs_p_no_alias, + nonoverlapping_component_refs_of_decl_p_may_alias, + nonoverlapping_component_refs_of_decl_p_no_alias. + (dump_alias_stats): Dump them. + (nonoverlapping_component_refs_of_decl_p): Add stats. + (nonoverlapping_component_refs_p): Add stats; do not stop on first + ARRAY_REF. + 2019-06-15 Uroš Bizjak * config/i386/i386.md (and3): Generate zero-extends for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 56ab3ec0b49..411d4966765 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-06-15 Jan Hubicka + + * gcc.dg/tree-ssa/alias-access-path-2.c: New testcase. + 2019-06-15 Steven G. Kargl * gfortran.dg/ieee/ieee_4.f90: Un-xfail on i?86-*-freebsd. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c new file mode 100644 index 00000000000..974cdb0ee00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre3" } */ +struct a { + int val; +}; +struct b { + struct a a[10],a2[10]; +}; +struct c { + struct b b[10]; +} *cptr; + +struct d {struct c c;} *dptr; + +int +test (int i, int j, int k, int l) +{ + cptr->b[i].a[j].val=123; + dptr->c.b[k].a2[l].val=2; + return cptr->b[i].a[j].val; +} +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 8209b0dd34f..42f02765824 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -100,6 +100,10 @@ static struct { unsigned HOST_WIDE_INT call_may_clobber_ref_p_no_alias; unsigned HOST_WIDE_INT aliasing_component_refs_p_may_alias; unsigned HOST_WIDE_INT aliasing_component_refs_p_no_alias; + unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_may_alias; + unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_no_alias; + unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_may_alias; + unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_no_alias; } alias_stats; void @@ -124,7 +128,19 @@ dump_alias_stats (FILE *s) alias_stats.call_may_clobber_ref_p_no_alias, alias_stats.call_may_clobber_ref_p_no_alias + alias_stats.call_may_clobber_ref_p_may_alias); - fprintf (s, " aliasing_component_ref_p: " + fprintf (s, " nonoverlapping_component_refs_p: " + HOST_WIDE_INT_PRINT_DEC" disambiguations, " + HOST_WIDE_INT_PRINT_DEC" queries\n", + alias_stats.nonoverlapping_component_refs_p_no_alias, + alias_stats.nonoverlapping_component_refs_p_no_alias + + alias_stats.nonoverlapping_component_refs_p_may_alias); + fprintf (s, " nonoverlapping_component_refs_of_decl_p: " + HOST_WIDE_INT_PRINT_DEC" disambiguations, " + HOST_WIDE_INT_PRINT_DEC" queries\n", + alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias, + alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias + + alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias); + fprintf (s, " aliasing_component_refs_p: " HOST_WIDE_INT_PRINT_DEC" disambiguations, " HOST_WIDE_INT_PRINT_DEC" queries\n", alias_stats.aliasing_component_refs_p_no_alias, @@ -1047,7 +1063,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) if (TREE_CODE (ref1) == MEM_REF) { if (!integer_zerop (TREE_OPERAND (ref1, 1))) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } ref1 = TREE_OPERAND (TREE_OPERAND (ref1, 0), 0); } @@ -1060,7 +1079,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) if (TREE_CODE (ref2) == MEM_REF) { if (!integer_zerop (TREE_OPERAND (ref2, 1))) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } ref2 = TREE_OPERAND (TREE_OPERAND (ref2, 0), 0); } @@ -1080,7 +1102,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) do { if (component_refs1.is_empty ()) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } ref1 = component_refs1.pop (); } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0)))); @@ -1088,7 +1113,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) do { if (component_refs2.is_empty ()) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } ref2 = component_refs2.pop (); } while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0)))); @@ -1096,7 +1124,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) /* Beware of BIT_FIELD_REF. */ if (TREE_CODE (ref1) != COMPONENT_REF || TREE_CODE (ref2) != COMPONENT_REF) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } tree field1 = TREE_OPERAND (ref1, 1); tree field2 = TREE_OPERAND (ref2, 1); @@ -1109,7 +1140,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) /* We cannot disambiguate fields in a union or qualified union. */ if (type1 != type2 || TREE_CODE (type1) != RECORD_TYPE) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } if (field1 != field2) { @@ -1117,15 +1151,23 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2) same. */ if (DECL_BIT_FIELD_REPRESENTATIVE (field1) == field2 || DECL_BIT_FIELD_REPRESENTATIVE (field2) == field1) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } /* Different fields of the same record type cannot overlap. ??? Bitfields can overlap at RTL level so punt on them. */ if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2)) - return false; + { + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; + return false; + } + ++alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias; return true; } } + ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias; return false; } @@ -1154,40 +1196,67 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y) { if (!flag_strict_aliasing || !x || !y - || TREE_CODE (x) != COMPONENT_REF - || TREE_CODE (y) != COMPONENT_REF) - return false; + || !handled_component_p (x) + || !handled_component_p (y)) + { + ++alias_stats.nonoverlapping_component_refs_p_may_alias; + return false; + } auto_vec fieldsx; - while (TREE_CODE (x) == COMPONENT_REF) + while (handled_component_p (x)) { - tree field = TREE_OPERAND (x, 1); - tree type = DECL_FIELD_CONTEXT (field); - if (TREE_CODE (type) == RECORD_TYPE) - fieldsx.safe_push (field); + if (TREE_CODE (x) == COMPONENT_REF) + { + tree field = TREE_OPERAND (x, 1); + tree type = DECL_FIELD_CONTEXT (field); + if (TREE_CODE (type) == RECORD_TYPE) + fieldsx.safe_push (field); + } + else if (TREE_CODE (x) == VIEW_CONVERT_EXPR) + fieldsx.truncate (0); x = TREE_OPERAND (x, 0); } if (fieldsx.length () == 0) return false; auto_vec fieldsy; - while (TREE_CODE (y) == COMPONENT_REF) + while (handled_component_p (y)) { - tree field = TREE_OPERAND (y, 1); - tree type = DECL_FIELD_CONTEXT (field); - if (TREE_CODE (type) == RECORD_TYPE) - fieldsy.safe_push (TREE_OPERAND (y, 1)); + if (TREE_CODE (y) == COMPONENT_REF) + { + tree field = TREE_OPERAND (y, 1); + tree type = DECL_FIELD_CONTEXT (field); + if (TREE_CODE (type) == RECORD_TYPE) + fieldsy.safe_push (TREE_OPERAND (y, 1)); + } + else if (TREE_CODE (y) == VIEW_CONVERT_EXPR) + fieldsx.truncate (0); y = TREE_OPERAND (y, 0); } if (fieldsy.length () == 0) - return false; + { + ++alias_stats.nonoverlapping_component_refs_p_may_alias; + return false; + } /* Most common case first. */ if (fieldsx.length () == 1 && fieldsy.length () == 1) - return ((DECL_FIELD_CONTEXT (fieldsx[0]) - == DECL_FIELD_CONTEXT (fieldsy[0])) - && fieldsx[0] != fieldsy[0] - && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))); + { + if ((DECL_FIELD_CONTEXT (fieldsx[0]) + == DECL_FIELD_CONTEXT (fieldsy[0])) + && fieldsx[0] != fieldsy[0] + && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))) + { + ++alias_stats.nonoverlapping_component_refs_p_no_alias; + return true; + } + else + { + ++alias_stats.nonoverlapping_component_refs_p_may_alias; + return false; + } + } if (fieldsx.length () == 2) { @@ -1222,11 +1291,18 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y) same. */ if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx) - return false; + { + ++alias_stats.nonoverlapping_component_refs_p_may_alias; + return false; + } /* Different fields of the same record type cannot overlap. ??? Bitfields can overlap at RTL level so punt on them. */ if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)) - return false; + { + ++alias_stats.nonoverlapping_component_refs_p_may_alias; + return false; + } + ++alias_stats.nonoverlapping_component_refs_p_no_alias; return true; } } @@ -1245,6 +1321,7 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y) } while (1); + ++alias_stats.nonoverlapping_component_refs_p_may_alias; return false; }