diff options
author | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-11 18:01:54 +0000 |
---|---|---|
committer | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-11 18:01:54 +0000 |
commit | c5d44e2fbe97b15dc79f213a19223f75c22bcf8e (patch) | |
tree | 0f32dcc7135957b2a24b097ca12ea0850be9f8be | |
parent | 6adfb8f86caa33f61d6ff2aa1aa81f3768beabbf (diff) | |
download | gcc-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/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 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); |