Re: [RFC][cxx-mem-model] mem_signal_fence

2011-11-02 Thread Andrew MacLeod

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



[RFC][cxx-mem-model] mem_signal_fence

2011-11-01 Thread Richard Henderson
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~
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: