On 09/21/12 20:32, Richard Henderson wrote:
On 09/21/2012 02:00 PM, Aldy Hernandez wrote:
+         /* ?? For TM_* builtin replacements, can we set this to FALSE??
+            Otherwise, do we need to propagate the may_irr bit?  */
+         node->local.tm_may_enter_irr = true;

Yes we can.  Indeed, I think we should have to insist on it.

Assert that the replacement is one of our TM builtins.  If we're
replacing anything else at this stage, something (else) bad has happened.


r~


How about this?
        PR middle-end/53850
        * trans-mem.c (expand_call_tm): Handle late built built-ins.

diff --git a/gcc/testsuite/gcc.dg/tm/pr53850.c 
b/gcc/testsuite/gcc.dg/tm/pr53850.c
new file mode 100644
index 0000000..ca2c604
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr53850.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O3" } */
+
+unsigned char pp[100];
+
+void
+foo (void)
+{
+  int i;
+  __transaction_atomic
+  {
+    for (i = 0; i < 100; ++i)
+      pp[i] = 0x33;
+  }
+}
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 242b470..ef384ac 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2296,8 +2296,31 @@ expand_call_tm (struct tm_region *region,
     }
 
   node = cgraph_get_node (fn_decl);
-  /* All calls should have cgraph here. */
-  gcc_assert (node);
+  /* All calls should have cgraph here.  */
+  if (!node)
+    {
+      /* We can have a nodeless call here if some pass after IPA-tm
+        added uninstrumented calls.  For example, loop distribution
+        can transform certain loop constructs into __builtin_mem*
+        calls.  In this case, see if we have a suitable TM
+        replacement and fill in the gaps.  */
+      gcc_assert (DECL_BUILT_IN_CLASS (fn_decl) == BUILT_IN_NORMAL);
+      enum built_in_function code = DECL_FUNCTION_CODE (fn_decl);
+      gcc_assert (code == BUILT_IN_MEMCPY
+                 || code == BUILT_IN_MEMMOVE
+                 || code == BUILT_IN_MEMSET);
+
+      tree repl = find_tm_replacement_function (fn_decl);
+      if (repl)
+       {
+         gimple_call_set_fndecl (stmt, repl);
+         update_stmt (stmt);
+         node = cgraph_create_node (repl);
+         node->local.tm_may_enter_irr = false;
+         return expand_call_tm (region, gsi);
+       }
+      gcc_unreachable ();
+    }
   if (node->local.tm_may_enter_irr)
     transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
 

Reply via email to