> On 03/30/2015 01:23 PM, Jan Hubicka wrote: > >Jason probably knows better, but I think only real C++ types comply the One > >Defintion > >Type and should be merged. Anything we create artifically in compiler is > >probably > >not covered by this. > > Agreed, compiler internals are outside the scope of the language. :)
:) Hi, this patch adds the ARTIFICIAL flag check to avoid ODR merging to these. I oriignally tested DECL_ARTIFICIAL (decl) (that is TYPE_NAME) that randomly dropped type names on some classes but not all. Jason, please do you know what is meaning of DECL_ARTIFICIAL on class type names? Perhaps we can drop them to 0 in free lang data? With this bug I triggered wrong devirtualization because we no longer insert non-odr types into a type inheritance graph. This is fixed by the lto_read_decls change and finally I triggered an ICE in ipa-devirt that due to the bug output a warning late and ICEd on streamer cache being NULL. I guess it is better to guard it even though all wanrings should be output early. Bootsrapped/regtested x86_64-linux, will commit it after chromium rebuild. Honza * tree.c (need_assembler_name_p): Artificial types have no ODR names. * ipa-devirt.c (warn_odr): Do not try to apply ODR cache when no caching is done. * lto.c (lto_read_decls): Move code registering odr types out of TYPE_CANONICAL conditional and also register polymorphic types. Index: tree.c =================================================================== --- tree.c (revision 221777) @@ -5139,6 +5145,7 @@ need_assembler_name_p (tree decl) && decl == TYPE_NAME (TREE_TYPE (decl)) && !is_lang_specific (TREE_TYPE (decl)) && AGGREGATE_TYPE_P (TREE_TYPE (decl)) + && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE) && !type_in_anonymous_namespace_p (TREE_TYPE (decl))) return !DECL_ASSEMBLER_NAME_SET_P (decl); Index: lto/lto.c =================================================================== --- lto/lto.c (revision 221777) +++ lto/lto.c (working copy) @@ -1944,13 +1944,24 @@ lto_read_decls (struct lto_file_decl_dat lto_fixup_prevailing_type (t); } /* Compute the canonical type of all types. - ??? Should be able to assert that !TYPE_CANONICAL. */ + + Inside a strongly connected component + gimple_register_canonical_type may recurse and insert + main variant ahead of time. Thus the need to check + TYPE_CANONICAL. */ if (TYPE_P (t) && !TYPE_CANONICAL (t)) - { - gimple_register_canonical_type (t); - if (odr_type_p (t)) - register_odr_type (t); - } + gimple_register_canonical_type (t); + + /* Reigster types to ODR hash. If we compile unit w/o + -fno-lto-odr-type-merging, also insert types with virtual + tables to keep type inheritance graph complete on + polymorphic types. */ + if (TYPE_P (t) + && (odr_type_p (t) + || (TYPE_MAIN_VARIANT (t) == t + && TREE_CODE (t) == RECORD_TYPE + && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t))))) + register_odr_type (t); /* Link shared INTEGER_CSTs into TYPE_CACHED_VALUEs of its type which is also member of this SCC. */ if (TREE_CODE (t) == INTEGER_CST Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 221777) +++ ipa-devirt.c (working copy) @@ -939,7 +939,8 @@ warn_odr (tree t1, tree t2, tree st1, tr /* ODR warnings are output druing LTO streaming; we must apply location cache for potential warnings to be output correctly. */ - lto_location_cache::current_cache->apply_location_cache (); + if (lto_location_cache::current_cache) + lto_location_cache::current_cache->apply_location_cache (); if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (t1)), OPT_Wodr, "type %qT violates one definition rule",