> On 08/14/2013 02:14 AM, Jan Hubicka wrote: > >As a temporary hack I suppose I can rely on assembler name of virtual table > >to be unique for each templated class? > > Actually, that seems like a fine solution for devirtualization; just > compare the mangled name of the vtable to establish type identity. OK, does this seem to make sense? I checked that it gets rid of my false ODR violation warnings (I disabled the code for types not having virtual tables).
So if it looks OK, I would like to go ahead with this patch. (I am testing it now in isolation at x86_64-linux). Honza Index: tree.c =================================================================== --- tree.c (revision 201764) +++ tree.c (working copy) @@ -11833,15 +11833,15 @@ types_same_for_odr (tree type1, tree typ 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; - + /* Without LTO main variants of types are unique. */ #ifndef ENABLE_CHECKING if (!in_lto_p) return false; #endif + /* 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; /* Check for anonymous namespaces. Those have !TREE_PUBLIC on the corresponding TYPE_STUB_DECL. */ @@ -11852,6 +11852,34 @@ types_same_for_odr (tree type1, tree typ || !TREE_PUBLIC (TYPE_STUB_DECL (type2)))) return false; + /* When assembler name of virtual table is available, it is + easy to compare types for equivalence. + FIXME: the code bellow consider all instantiations of the same + template to have same name. This is because we have no access + to template parameters. + To avoid false positives that may lead to wrong devirtualizations, + compoare also representative virtual tables. + We can still return false positive positives for types without + virtual tables, but for the moment we do not care. */ + 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); + } + return DECL_ASSEMBLER_NAME (v1) == DECL_ASSEMBLER_NAME (v2); + } + if (!TYPE_NAME (type1)) return false; if (!decls_same_for_odr (TYPE_NAME (type1), TYPE_NAME (type2)))