While working on PR51698, I've noticed the LTO/TM rabbit hole goes much
deeper.
The compiler is dropping transactional clones with -flto because the
externally_visible bit is unset for clones. This is so because
cgraph_copy_node_for_versioning unconditionally zaps it. I have fixed
the TM infrastructure to set the bit on the clones if the original
version had it set.
This patch will be needed to get PR51698 and LTO working with TM.
OK?
* trans-mem.c (ipa_tm_create_version): Set externally_visible.
(ipa_tm_create_version_alias): Same.
Index: testsuite/gcc.dg/tm/lto-1.c
===================================================================
--- testsuite/gcc.dg/tm/lto-1.c (revision 0)
+++ testsuite/gcc.dg/tm/lto-1.c (revision 0)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -flto" } */
+
+__attribute__((transaction_safe))
+void foo()
+{
+}
+
+/* { dg-final { scan-assembler "ZGTt3foo" } } */
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 183244)
+++ trans-mem.c (working copy)
@@ -4221,7 +4221,7 @@ struct create_version_alias_info
tree new_decl;
};
-/* A subrontine of ipa_tm_create_version, called via
+/* A subroutine of ipa_tm_create_version, called via
cgraph_for_node_and_aliases. Create new tm clones for each of
the existing aliases. */
static bool
@@ -4261,6 +4261,7 @@ ipa_tm_create_version_alias (struct cgra
new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true;
+ new_node->local.externally_visible =
info->old_node->local.externally_visible;
/* ?? Do not traverse aliases here. */
get_cg_data (&node, false)->clone = new_node;
@@ -4296,6 +4297,7 @@ ipa_tm_create_version (struct cgraph_nod
DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
+ new_node->local.externally_visible = old_node->local.externally_visible;
new_node->lowered = true;
new_node->tm_clone = 1;
get_cg_data (&old_node, true)->clone = new_node;