summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-11 18:01:54 +0000
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-11 18:01:54 +0000
commitc5d44e2fbe97b15dc79f213a19223f75c22bcf8e (patch)
tree0f32dcc7135957b2a24b097ca12ea0850be9f8be
parent6adfb8f86caa33f61d6ff2aa1aa81f3768beabbf (diff)
downloadgcc-c5d44e2fbe97b15dc79f213a19223f75c22bcf8e.tar.gz
2002-03-06 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. * 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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/alias.c11
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-lang.c58
4 files changed, 79 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f72ad4f55fa..9a9478bfa32 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/alias.c b/gcc/alias.c
index 5d017eb73c9..9b46fe1be52 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -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)));
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5c707eade5e..d2f15802dc7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 072550ad678..da0718e14a0 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -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);