===================================================================
@@ -5393,6 +5393,7 @@ extern tree build_tm_abort_call (locatio
extern bool is_tm_safe (const_tree);
extern bool is_tm_pure (const_tree);
extern bool is_tm_may_cancel_outer (tree);
+extern bool is_tm_ending_fndecl (tree);
extern void record_tm_replacement (tree, tree);
extern void tm_malloc_replacement (tree);
===================================================================
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int george;
+
+void q1()
+{
+ __transaction [[atomic]] {
+ george=999;
+ }
+ q1();
+}
+
+/* { dg-final { scan-assembler-not "ZGTt2q1" } } */
===================================================================
@@ -292,7 +292,7 @@ is_transactional_stmt (const_gimple stmt
/* Return true for built in functions that "end" a transaction. */
-static bool
+bool
is_tm_ending_fndecl (tree fndecl)
{
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
@@ -4500,7 +4500,7 @@ ipa_tm_execute (void)
bitmap_obstack_initialize (&tm_obstack);
bb_in_TM_region = BITMAP_ALLOC (&tm_obstack);
- /* Build a bitmap of all BB"s inside transaction regions. */
+ /* Build a bitmap of all BB's inside transaction regions. */
for (node = cgraph_nodes; node; node = node->next)
if (node->reachable && node->lowered
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
@@ -4509,7 +4509,9 @@ ipa_tm_execute (void)
regions = ipa_tm_region_init (node);
for ( ; regions; regions = regions->next)
{
- get_tm_region_blocks (regions->entry_block, NULL, NULL,
+ get_tm_region_blocks (regions->entry_block,
+ regions->exit_blocks,
+ NULL,
bb_in_TM_region, false);
}
}
===================================================================
@@ -2253,6 +2253,13 @@ is_ctrl_altering_stmt (gimple t)
/* A call also alters control flow if it does not return. */
if (flags & ECF_NORETURN)
return true;
+
+ /* TM ending statements have backedges out of the transaction.
+ Return true so we split the basic block containing
+ them. */
+ if ((flags & ECF_TM_OPS)
+ && is_tm_ending_fndecl (gimple_call_fndecl (t)))
+ return true;
}
break;