From 8ee8afa3a569ff6f8d54516f1e9b9ed01e8c7a31 Mon Sep 17 00:00:00 2001
From: Jan Hubicka <jh@suse.cz>
Date: Sat, 21 Nov 2020 17:41:10 +0100
Subject: [PATCH] Improve hasing of anonymous namespace types

	* ipa-icf.c (sem_function::equals_wpa): Do not compare ODR type with
	-fno-devirtualize.
	(sem_item_optimizer::update_hash_by_addr_refs): Hash anonymous ODR
	types by TYPE_UID of their main variant.
---
 gcc/ipa-icf.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 6ae842766e6e..5bbbec6c806f 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 +2537,24 @@ 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 (class_type));
+		    hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
+		  }
 
 		m_items[i]->set_hash (hstate.end ());
 	     }
-- 
GitLab