diff options
author | Dan Nicolaescu <dann@ics.uci.edu> | 2002-03-11 18:01:54 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2002-03-11 13:01:54 -0500 |
commit | 61eece67a6b6c97edec67b6ecb8c1144149ff228 (patch) | |
tree | 0f32dcc7135957b2a24b097ca12ea0850be9f8be | |
parent | ff080abaf5df0d726139dcc5ac2d4233e14b4b76 (diff) | |
download | gcc-61eece67a6b6c97edec67b6ecb8c1144149ff228.zip gcc-61eece67a6b6c97edec67b6ecb8c1144149ff228.tar.gz gcc-61eece67a6b6c97edec67b6ecb8c1144149ff228.tar.bz2 |
C++ alias analysis improvement.
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.
Co-Authored-By: Daniel Berlin <dberlin@dberlin.org>
From-SVN: r50587
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/alias.c | 11 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 58 |
4 files changed, 79 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f72ad4f..9a9478b 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 5d017eb..9b46fe1 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 5c707ea..d2f1580 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 072550a..da0718e 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); |