OSDN Git Service

2002-03-06 Dan Nicolaescu <dann@ics.uci.edu>
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Mar 2002 18:01:54 +0000 (18:01 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Mar 2002 18:01:54 +0000 (18:01 +0000)
            Daniel Berlin  <dan@dberlin.org>

        C++ alias analysis improvement.
* alias.c (record_component_aliases): Record aliases for base
        classes too.
* cp/cp-lang.c (ok_to_generate_alias_set_for_type): New function.
(cxx_get_alias_set): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50587 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/alias.c
gcc/cp/ChangeLog
gcc/cp/cp-lang.c

index f72ad4f..9a9478b 100644 (file)
@@ -1,3 +1,10 @@
+2002-03-11  Dan Nicolaescu  <dann@ics.uci.edu>
+           Daniel Berlin  <dan@dberlin.org>
+
+       C++ alias analysis improvement.
+       * alias.c (record_component_aliases): Record aliases for base 
+       classes too.
+
 2002-03-11  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * config/s390/s390.h (REG_ALLOC_ORDER): Add missing register.
index 5d017eb..9b46fe1 100644 (file)
@@ -679,6 +679,17 @@ record_component_aliases (type)
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
+      /* Recursively record aliases for the base classes, if there are any */
+      if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
+        {
+          int i;
+          for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); i++)
+            {
+              tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
+              record_alias_subset (superset,
+                                  get_alias_set (BINFO_TYPE (binfo)));
+            }
+        }
       for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
        if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
          record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
index 5c707ea..d2f1580 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-11  Dan Nicolaescu  <dann@ics.uci.edu>
+           Daniel Berlin  <dan@dberlin.org>
+
+       * cp-lang.c (ok_to_generate_alias_set_for_type): New function.
+       (cxx_get_alias_set): Use it.
+
 2002-03-10  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * cp-tree.h (stabilize_expr): Prototype.
index 072550a..da0718e 100644 (file)
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks-def.h"
 
 static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
+static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
 
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU C++"
@@ -99,15 +100,66 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
 /* Each front end provides its own hooks, for toplev.c.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
+/* Check if a C++ type is safe for aliasing.
+   Return TRUE if T safe for aliasing FALSE otherwise.  */
+
+static bool
+ok_to_generate_alias_set_for_type (t)
+     tree t;
+{
+  if (TYPE_PTRMEMFUNC_P (t))
+    return true;
+  if (AGGREGATE_TYPE_P (t))
+    {
+      if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE))
+       {
+         tree fields;
+         /* PODs are safe.  */
+         if (! CLASSTYPE_NON_POD_P(t))
+           return true;
+         /* Classes with virtual baseclasses are not.  */
+         if (TYPE_USES_VIRTUAL_BASECLASSES (t))
+           return false;
+         /* Recursively check the base classes.  */
+         if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL)
+           {
+             int i;
+             for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++)
+               {
+                 tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
+                 if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo)))
+                   return false;
+               }
+           }
+         /* Check all the fields.  */
+         for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields))
+           {
+             if (TREE_CODE (fields) != FIELD_DECL)
+               continue;
+             if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields)))
+               return false;
+           }
+         return true;
+       }
+      else if (TREE_CODE (t) == ARRAY_TYPE)
+       return ok_to_generate_alias_set_for_type (TREE_TYPE (t));
+      else
+       /* This should never happen, we dealt with all the aggregate
+          types that can appear in C++ above.  */
+       abort ();
+    }
+  else
+    return true;
+}
+
 /* Special routine to get the alias set for C++.  */
 
 static HOST_WIDE_INT
 cxx_get_alias_set (t)
      tree t;
 {
-  /* It's not yet safe to use alias sets for classes in C++ because
-     the TYPE_FIELDs list for a class doesn't mention base classes.  */
-  if (AGGREGATE_TYPE_P (t))
+  /* It's not yet safe to use alias sets for classes in C++.  */
+  if (!ok_to_generate_alias_set_for_type(t))
     return 0;
 
   return c_common_get_alias_set (t);