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