Remove nonoverlapping_component_refs_of_decl_p
Jan Hubicka
hubicka@ucw.cz
Fri Jun 14 20:16:00 GMT 2019
>
> I think this is still error-prone since we look past
> VIEW_CONVERT_EXPRs in the path so we happily disambiguate,
> say,
>
> struct X { int e; int d; };
> struct Y { int d; int e; };
>
> VIEW_CONVERT<X>(p->b).d
> VIEW_CONVERT<Y>(q->b).e
>
> where in reality only the access paths from the base up to
> the first view-conversion are relevant for path-based
> analysis.
>
> So upon seeing a VIEW_CONVERT (or BIT_FIELD_REF which
> has the same issue) simply truncate the vector.
>
> As said, it's a pre-existing issue but you are extending
> things to possibly handle more stuff...
>
> Otherwise looks good.
OK, i added the check and also managed to construct testcase that we do
not optimize otherwise.
I think same view convert bug ought to exist also in
aliasing_component_refs_p and IMO ao_ref_alias set should also look
for VCEs otherwise I can't make sense of
/* First defer to TBAA if possible. */
if (tbaa_p
&& flag_strict_aliasing
&& !alias_sets_conflict_p (ao_ref_alias_set (ref1),
ao_ref_alias_set (ref2)))
return false;
Honza
* 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.
Index: testsuite/gcc.dg/tree-ssa/alias-access-path-2.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/alias-access-path-2.c (nonexistent)
+++ testsuite/gcc.dg/tree-ssa/alias-access-path-2.c (working copy)
@@ -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"} } */
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c (revision 272283)
+++ tree-ssa-alias.c (working copy)
@@ -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
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
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
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
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
/* 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
/* 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
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_t
{
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<const_tree, 16> 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<const_tree, 16> 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_t
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_t
}
while (1);
+ ++alias_stats.nonoverlapping_component_refs_p_may_alias;
return false;
}
More information about the Gcc-patches
mailing list