[RFC,cxx-mem-model] mem_signal_fence
diff mbox

Message ID 4EB016F9.90200@gmail.com
State New
Headers show

Commit Message

Richard Henderson Nov. 1, 2011, 3:57 p.m. UTC
Any comments on the expectation, or implementation of signal-fence below?
Should I make the distinction between the memory models here at all?

At minimum there's another typo in the ifdef section; we really need to
minimize those...


r~

Comments

Andrew MacLeod Nov. 2, 2011, 2:26 p.m. UTC | #1
On 11/01/2011 11:57 AM, Richard Henderson wrote:
> Any comments on the expectation, or implementation of signal-fence below?
> Should I make the distinction between the memory models here at all?

I think the expectation is that signal_fence is identical to 
thread_fence, except the compiler doesn't actually issue the hardware 
fence instruction. Just the barrier-ness to the compiler as well as any 
data dependencies the memory order imposes needs to be maintained.    
Since we don't have any directional barriers yet, I guess anything other 
than RELAXED needs to be a full barrier to the compiler.  someday when I 
have been energetic, we may get directional barriers and then we'll do 
something different.

Thats my understanding anyway
> At minimum there's another typo in the ifdef section; we really need to
> minimize those...
And good job at that! :-)   These are paths that have not been tested 
until someone implements the rtl patterns...   so any typo's would need 
to have been caught in the patch review :-)   I never claimed to 
understand the intricacies of RTL pattern machinery that well...

Andrew

Patch
diff mbox

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 756070f..34922a8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5530,16 +5530,18 @@  expand_builtin_atomic_is_lock_free (tree exp)
 /* This routine will either emit the mem_thread_fence pattern or issue a 
    sync_synchronize to generate a fence for memory model MEMMODEL.  */
 
+#ifndef HAVE_mem_thread_fence
+# define HAVE_mem_thread_fence 0
+# define gen_mem_thread_fence(x) (gcc_unreachable (), NULL_RTX)
+#endif
+
 void
 expand_builtin_mem_thread_fence (enum memmodel model)
 {
-  if (model == MEMMODEL_RELAXED)
-    return;
-#ifdef HAVE_mem_thread_fence
-  emit_insn (gen_mem_thread_fence (GEN_INT (model)));
-#else
-  expand_builtin_sync_synchronize ();
-#endif
+  if (HAVE_mem_thread_fence)
+    emit_insn (gen_mem_thread_fence (GEN_INT (model)));
+  else if (model != MEMMODEL_RELAXED)
+    expand_builtin_sync_synchronize ();
 }
 
 /* Expand the __atomic_thread_fence intrinsic:
@@ -5558,15 +5560,38 @@  expand_builtin_atomic_thread_fence (tree exp)
 /* This routine will either emit the mem_signal_fence pattern or issue a 
    sync_synchronize to generate a fence for memory model MEMMODEL.  */
 
+#ifndef HAVE_mem_signal_fence
+# define HAVE_mem_signal_fence 0
+# define gen_mem_signal_fence(x) (gcc_unreachable (), NULL_RTX)
+#endif
+
 static void
 expand_builtin_mem_signal_fence (enum memmodel model)
 {
-#ifdef HAVE_mem_signal_fence
-  emit_insn (gen_mem_signal_fence (memmodel));
-#else
-  if (model != MEMMODEL_RELAXED)
-    expand_builtin_sync_synchronize ();
-#endif
+  if (HAVE_mem_signal_fence)
+    emit_insn (gen_mem_signal_fence (GEN_INT (model)));
+  else
+    {
+      rtx x;
+
+      /* By default I expect that targets are coherent between a thread and
+	 the signal handler running on the same thread.  Thus this really
+	 becomes a compiler barrier, in that stores must not be sunk past
+	 (or raised above) a given point.  */
+      switch (model)
+	{
+	case MEMMODEL_RELAXED:
+	  break;
+	case MEMMODEL_SEQ_CST:
+	  gen_blockage ();
+	  break;
+	default:
+	  x = gen_rtx_SCRATCH (Pmode);
+	  x = gen_rtx_MEM (BLKmode, x);
+	  emit_insn (gen_rtx_USE (x));
+	  break;
+	}
+    }
 }
 
 /* Expand the __atomic_signal_fence intrinsic: