diff options
author | Jan Hubicka <jh@suse.cz> | 2013-09-04 16:14:28 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-09-04 14:14:28 +0000 |
commit | 61a74079b01d0229d95f14d160bcbe6c4f88147f (patch) | |
tree | 37a2f18b9ddc64a6fda6a6cc4c075c72734d0ce7 /gcc/tree.c | |
parent | 24ba81955d92ff8c29f814867b887446f5c0be05 (diff) | |
download | gcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.zip gcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.tar.gz gcc-61a74079b01d0229d95f14d160bcbe6c4f88147f.tar.bz2 |
Makefile.in (ipa-devirt.o): Add dependency on diagnostic.h
* Makefile.in (ipa-devirt.o): Add dependency on diagnostic.h
* ipa-devirt.c: Include diganostic.h
(odr_type_d): Add types and types_set.
(hash_type_name): Work for types with vtables during LTO.
(odr_hasher::remove): Fix comment; destroy types_set.
(add_type_duplicate): New function,
(get_odr_type): Use it.
(dump_type_inheritance_graph): Dump type duplicates.
* ipa.c (symtab_remove_unreachable_nodes): Build type inheritance
graph.
* tree.c (types_same_for_odr): Give exact answers on types with
virtual tables.
From-SVN: r202258
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 44 |
1 files changed, 39 insertions, 5 deletions
@@ -11853,11 +11853,6 @@ types_same_for_odr (tree type1, tree type2) if (type1 == type2) return true; - /* If types are not structuraly same, do not bother to contnue. - Match in the remainder of code would mean ODR violation. */ - if (!types_compatible_p (type1, type2)) - return false; - #ifndef ENABLE_CHECKING if (!in_lto_p) return false; @@ -11868,7 +11863,46 @@ types_same_for_odr (tree type1, tree type2) if (type_in_anonymous_namespace_p (type1) || type_in_anonymous_namespace_p (type2)) return false; + /* When assembler name of virtual table is available, it is + easy to compare types for equivalence. */ + if (TYPE_BINFO (type1) && TYPE_BINFO (type2) + && BINFO_VTABLE (TYPE_BINFO (type1)) + && BINFO_VTABLE (TYPE_BINFO (type2))) + { + tree v1 = BINFO_VTABLE (TYPE_BINFO (type1)); + tree v2 = BINFO_VTABLE (TYPE_BINFO (type2)); + if (TREE_CODE (v1) == POINTER_PLUS_EXPR) + { + if (TREE_CODE (v2) != POINTER_PLUS_EXPR + || !operand_equal_p (TREE_OPERAND (v1, 1), + TREE_OPERAND (v2, 1), 0)) + return false; + v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0); + v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0); + } + v1 = DECL_ASSEMBLER_NAME (v1); + v2 = DECL_ASSEMBLER_NAME (v2); + /* If we ever start adding random .blah suffixes after + assembler names, we need to compare for match ignoring + these (and update odr_type_hash, too). */ +#ifdef ENABLE_CHECKING + gcc_assert (!strchr (IDENTIFIER_POINTER (v1), '.') + && !strchr (IDENTIFIER_POINTER (v2), '.')); +#endif + return (v1 == v2); + } + + /* FIXME: the code comparing type names consider all instantiations of the + same template to have same name. This is because we have no access + to template parameters. For types with no virtual method tables + we thus can return false positives. At the moment we do not need + to compare types in other scenarios than devirtualization. */ + + /* If types are not structuraly same, do not bother to contnue. + Match in the remainder of code would mean ODR violation. */ + if (!types_compatible_p (type1, type2)) + return false; if (!TYPE_NAME (type1)) return false; if (!decls_same_for_odr (TYPE_NAME (type1), TYPE_NAME (type2))) |