Hi,
Building libxul 400k mismerges are due to THIS parameters of member functions
of polymorphic types that are in anonymous namespaces.  We already hash ODR
names of the types, but all anonymous type have name "<anon>". These can
be distinguished by TYPE_MAIN_VARIANT that is implemented by this patch.

I also noticed that even with !flag_devirtualize we compare tpes of ctors
but not types of normal method, so fixed this.

It would be possible to keep track of merges and disable the late
devirtualization use of this parameter type becuase late devirtualization
is not very useful.  I will look into that.

Bootstrapped/regtested x86_64-linux, will commit it later today if there
are no complains.

Honza

        * ipa-icf.c (sem_function::equals_wpa): Only compare ODR types with
        flag_devirtualize.
        (sem_item_optimizer::update_hash_by_addr_refs): Improve hasing of
        anonymous ODR names.
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 6ae842766e6..0ed5dd92a1b 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -575,6 +575,7 @@ sem_function::equals_wpa (sem_item *item,
      type memory location for ipa-polymorphic-call and we do not want
      it to get confused by wrong type.  */
   if (DECL_CXX_CONSTRUCTOR_P (decl)
+      && opt_for_fn (decl, flag_devirtualize)
       && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
     {
       if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
@@ -2536,11 +2545,25 @@ sem_item_optimizer::update_hash_by_addr_refs ()
                  = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
                inchash::hash hstate (m_items[i]->get_hash ());
 
+               /* Hash ODR types by mangled name if it is defined.
+                  If not we know that type is anonymous of free_lang_data
+                  was not run and in that case type main variants are
+                  unique.  */
                if (TYPE_NAME (class_type)
-                    && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
+                    && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))
+                    && !type_in_anonymous_namespace_p
+                                (class_type))
                  hstate.add_hwi
                    (IDENTIFIER_HASH_VALUE
                       (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
+               else
+                 {
+                   gcc_checking_assert
+                        (!in_lto_p
+                         || type_in_anonymous_namespace_p
+                                (TYPE_NAME (class_type)));
+                   hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
+                 }
 
                m_items[i]->set_hash (hstate.end ());
             }

Reply via email to