RFC: add inheritance support to nonoverlapping_component_refs_p

Richard Henderson rth@redhat.com
Fri May 24 17:53:00 GMT 2002


On Wed, Apr 03, 2002 at 02:14:11PM -0800, Dan Nicolaescu wrote:
> 	* alias.c (nonoverlapping_component_refs_p): Look for fields in
> 	BINFOs too. 

The patch is incomplete.  You need to recursively search base
classes.  For example, your patch will fail the attached test.

Incidentally, this is the sort of test cases you should be
writing to accompany your aliasing patches.  If the aliasing
works as designed, the compiler can prove some property and
simplify a conditional at compile-time.

I think the attached patch will do what you want.  I've only
tested it on the given test case.  It needs something more
thorough before being checked in.  Since you have an interest,
would you mind doing that?  You might also see if you can 
re-factor it a bit to ensure tail-recursion elimination in
some cases, and/or hoist controling expressions into callers.


r~
-------------- next part --------------
/* { dg-do link } */

class first
{
public:
  double d;
  int f1;
};

class middle : public first
{
};

class second : public middle
{
public:
  int f2;
  short a;
};

extern void link_error ();

void
foo (first *s1, second *s2)
{
  s1->f1 = 0;
  s2->f2 = 0;
  s1->f1++;
  s2->f2++;
  s1->f1++;
  s2->f2++;
  if (s1->f1 != 2)
    link_error ();
}

int main()
{
  first a;
  second b;
  foo(&a, &b);
  return 0;
}
-------------- next part --------------
Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.170
diff -c -p -d -r1.170 alias.c
*** alias.c	22 Apr 2002 18:17:06 -0000	1.170
--- alias.c	25 May 2002 00:20:11 -0000
*************** static alias_set_entry get_alias_set_ent
*** 103,108 ****
--- 103,111 ----
  static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
  						      int (*) (rtx, int)));
  static int aliases_everything_p         PARAMS ((rtx));
+ static bool find_base_class_match	PARAMS ((tree, tree));
+ static tree nonoverlapping_component_refs_search_y PARAMS ((tree, tree));
+ static tree nonoverlapping_component_refs_search_x PARAMS ((tree, tree, tree*));
  static bool nonoverlapping_component_refs_p PARAMS ((tree, tree));
  static tree decl_for_component_ref	PARAMS ((tree));
  static rtx adjust_offset_for_component_ref PARAMS ((tree, rtx));
*************** aliases_everything_p (mem)
*** 1807,1812 ****
--- 1810,1904 ----
    return 0;
  }
  
+ /* Subroutine of nonoverlapping_component_refs_p.  Return true if
+    TYPEY has TYPEX as a base class.  */
+ 
+ static bool
+ find_base_class_match (typex, typey)
+      tree typex, typey;
+ {
+   tree basetypes = TYPE_BINFO_BASETYPES (typey);
+   int i, n = TREE_VEC_LENGTH (basetypes);
+ 
+   for (i = 0; i < n; i++)
+     {
+       tree btype = BINFO_TYPE (TREE_VEC_ELT (basetypes, i));
+       if (typex == btype)
+ 	return true;
+     }
+ 
+   for (i = 0; i < n; i++)
+     {
+       tree btype = BINFO_TYPE (TREE_VEC_ELT (basetypes, i));
+       if (TYPE_BINFO (btype) && TYPE_BINFO_BASETYPES (btype))
+ 	if (find_base_class_match (typex, btype))
+ 	  return true;
+     }
+ 
+   return false;
+ }
+ 
+ /* Subroutine of nonoverlapping_component_refs_p.  Y is a chain of
+    COMPONENT_REFs.  If Y contains a reference to a field that is
+    in TYPEX, or in a type that is a derived type of TYPEX, return it.  */
+ 
+ static inline tree
+ nonoverlapping_component_refs_search_y (typex, y)
+      tree typex, y;
+ {
+   do
+     {
+       tree fieldy = TREE_OPERAND (y, 1);
+       tree typey = DECL_FIELD_CONTEXT (fieldy);
+ 
+       if (typex == typey)
+ 	return fieldy;
+ 
+       /* If TYPEY is a derived type, look through the base types too.  */
+       if (TYPE_BINFO (typey) && TYPE_BINFO_BASETYPES (typey))
+ 	if (find_base_class_match (typex, typey))
+ 	  return fieldy;
+ 
+       y = TREE_OPERAND (y, 0);
+     }
+   while (y && TREE_CODE (y) == COMPONENT_REF);
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Subroutine of nonoverlapping_component_refs_p.  Invoke
+    nonoverlapping_component_refs_search_y on TYPEX and every base class
+    of TYPEX.  Return the type in which we eventually found a match.
+    Pass back the return value of n_c_r_s_y in PFIELDY.  */
+ 
+ static tree
+ nonoverlapping_component_refs_search_x (typex, y, pfieldy)
+      tree typex, y, *pfieldy;
+ {
+   tree fieldy = nonoverlapping_component_refs_search_y (typex, y);
+   if (fieldy)
+     {
+       *pfieldy = fieldy;
+       return typex;
+     }
+ 
+   /* If TYPEX is a derived type, look through the base types too.  */
+   if (TYPE_BINFO (typex) && TYPE_BINFO_BASETYPES (typex))
+     {
+       tree basetypes = TYPE_BINFO_BASETYPES (typex);
+       int i, n = TREE_VEC_LENGTH (basetypes);
+       for (i = 0; i < n; i++)
+ 	{
+ 	  tree btype = BINFO_TYPE (TREE_VEC_ELT (basetypes, i));
+ 	  typex = nonoverlapping_component_refs_search_x (btype, y, pfieldy);
+ 	  if (typex)
+ 	    return typex;
+ 	}
+     }
+ 
+   return NULL_TREE;
+ }
+ 
  /* Return true if we can determine that the fields referenced cannot
     overlap for any pair of objects.  */
  
*************** static bool
*** 1814,1843 ****
  nonoverlapping_component_refs_p (x, y)
       tree x, y;
  {
-   tree fieldx, fieldy, typex, typey, orig_y;
- 
    do
      {
!       /* The comparison has to be done at a common type, since we don't
! 	 know how the inheritance hierarchy works.  */
!       orig_y = y;
        do
  	{
  	  fieldx = TREE_OPERAND (x, 1);
  	  typex = DECL_FIELD_CONTEXT (fieldx);
  
! 	  y = orig_y;
! 	  do
! 	    {
! 	      fieldy = TREE_OPERAND (y, 1);
! 	      typey = DECL_FIELD_CONTEXT (fieldy);
! 
! 	      if (typex == typey)
! 		goto found;
! 
! 	      y = TREE_OPERAND (y, 0);
! 	    }
! 	  while (y && TREE_CODE (y) == COMPONENT_REF);
  
  	  x = TREE_OPERAND (x, 0);
  	}
--- 1906,1925 ----
  nonoverlapping_component_refs_p (x, y)
       tree x, y;
  {
    do
      {
!       tree fieldx, fieldy, typex;
! 
        do
  	{
  	  fieldx = TREE_OPERAND (x, 1);
  	  typex = DECL_FIELD_CONTEXT (fieldx);
  
! 	  /* The field comparison is only valid with a common type.  Search
! 	     the inheritance hierarchy for a match.  */
! 	  typex = nonoverlapping_component_refs_search_x (typex, y, &fieldy);
! 	  if (typex)
! 	    goto found;
  
  	  x = TREE_OPERAND (x, 0);
  	}


More information about the Gcc-patches mailing list