Unify implementations of __builtin_mem_*_fence and __sync_synchronize.
authorRichard Henderson <rth@redhat.com>
Thu, 17 Nov 2011 19:29:04 +0000 (11:29 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 17 Nov 2011 19:29:04 +0000 (11:29 -0800)
* builtins.c (expand_builtin_mem_thread_fence): Remove.
(expand_builtin_mem_signal_fence): Remove.
(expand_builtin_atomic_thread_fence): Use expand_mem_thread_fence.
(expand_builtin_sync_synchronize): Likewise.
(expand_builtin_atomic_signal_fence): Use expand_mem_signal_fence.
* optabs.c (expand_asm_memory_barrier): Split out from
expand_builtin_mem_signal_fence.
(expand_mem_thread_fence): New, a combination of code from
expand_builtin_mem_thread_fence and expand_builtin_sync_synchronize.
(expand_mem_signal_fence): Moved and renamed from
expand_builtin_mem_signal_fence.
(expand_atomic_exchange): Use expand_mem_thread_fence.
(expand_atomic_load, expand_atomic_store): Likewise.
* expr.h, optabs.h: Update decls.

From-SVN: r181451

gcc/ChangeLog
gcc/builtins.c
gcc/expr.h
gcc/optabs.c
gcc/optabs.h

index 32da92a..95924c8 100644 (file)
@@ -1,3 +1,20 @@
+2011-11-17  Richard Henderson  <rth@redhat.com>
+
+       * builtins.c (expand_builtin_mem_thread_fence): Remove.
+       (expand_builtin_mem_signal_fence): Remove.
+       (expand_builtin_atomic_thread_fence): Use expand_mem_thread_fence.
+       (expand_builtin_sync_synchronize): Likewise.
+       (expand_builtin_atomic_signal_fence): Use expand_mem_signal_fence.
+       * optabs.c (expand_asm_memory_barrier): Split out from
+       expand_builtin_mem_signal_fence.
+       (expand_mem_thread_fence): New, a combination of code from
+       expand_builtin_mem_thread_fence and expand_builtin_sync_synchronize.
+       (expand_mem_signal_fence): Moved and renamed from
+       expand_builtin_mem_signal_fence.
+       (expand_atomic_exchange): Use expand_mem_thread_fence.
+       (expand_atomic_load, expand_atomic_store): Likewise.
+       * expr.h, optabs.h: Update decls.
+
 2011-11-17  Bin Cheng  <bin.cheng@arm.com>
 
        PR rtl-optimization/50663
index 9dc68cc..fe0260f 100644 (file)
@@ -5672,23 +5672,6 @@ expand_builtin_atomic_is_lock_free (tree exp)
   return NULL_RTX;
 }
 
-/* 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 (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:
        void __atomic_thread_fence (enum memmodel)
    EXP is the CALL_EXPR.  */
@@ -5696,46 +5679,8 @@ expand_builtin_mem_thread_fence (enum memmodel model)
 static void
 expand_builtin_atomic_thread_fence (tree exp)
 {
-  enum memmodel model;
-  
-  model = get_memmodel (CALL_EXPR_ARG (exp, 0));
-  expand_builtin_mem_thread_fence (model);
-}
-
-/* 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)
-{
-  if (HAVE_mem_signal_fence)
-    emit_insn (gen_mem_signal_fence (GEN_INT (model)));
-  else if (model != MEMMODEL_RELAXED)
-    {
-      rtx asm_op, clob;
-
-      /* By default 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.  */
-
-      /* Generate asm volatile("" : : : "memory") as the memory barrier.  */
-      asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
-                                    rtvec_alloc (0), rtvec_alloc (0),
-                                    rtvec_alloc (0), UNKNOWN_LOCATION);
-      MEM_VOLATILE_P (asm_op) = 1;
-
-      clob = gen_rtx_SCRATCH (VOIDmode);
-      clob = gen_rtx_MEM (BLKmode, clob);
-      clob = gen_rtx_CLOBBER (VOIDmode, clob);
-
-      emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
-    }
+  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
+  expand_mem_thread_fence (model);
 }
 
 /* Expand the __atomic_signal_fence intrinsic:
@@ -5745,10 +5690,8 @@ expand_builtin_mem_signal_fence (enum memmodel model)
 static void
 expand_builtin_atomic_signal_fence (tree exp)
 {
-  enum memmodel model;
-
-  model = get_memmodel (CALL_EXPR_ARG (exp, 0));
-  expand_builtin_mem_signal_fence (model);
+  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
+  expand_mem_signal_fence (model);
 }
 
 /* Expand the __sync_synchronize intrinsic.  */
@@ -5756,31 +5699,7 @@ expand_builtin_atomic_signal_fence (tree exp)
 static void
 expand_builtin_sync_synchronize (void)
 {
-  gimple x;
-  VEC (tree, gc) *v_clobbers;
-
-#ifdef HAVE_memory_barrier
-  if (HAVE_memory_barrier)
-    {
-      emit_insn (gen_memory_barrier ());
-      return;
-    }
-#endif
-
-  if (synchronize_libfunc != NULL_RTX)
-    {
-      emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
-      return;
-    }
-
-  /* If no explicit memory barrier instruction is available, create an
-     empty asm stmt with a memory clobber.  */
-  v_clobbers = VEC_alloc (tree, gc, 1);
-  VEC_quick_push (tree, v_clobbers,
-                 tree_cons (NULL, build_string (6, "memory"), NULL));
-  x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
-  gimple_asm_set_volatile (x, true);
-  expand_asm_stmt (x);
+  expand_mem_thread_fence (MEMMODEL_SEQ_CST);
 }
 
 \f
index 2cc8152..4b923a5 100644 (file)
@@ -254,7 +254,6 @@ extern void expand_builtin_setjmp_receiver (rtx);
 extern rtx expand_builtin_saveregs (void);
 extern void expand_builtin_trap (void);
 extern rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
-extern void expand_builtin_mem_thread_fence (enum memmodel);
 \f
 /* Functions from expr.c:  */
 
index 171756b..2468efd 100644 (file)
@@ -7378,7 +7378,7 @@ expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model,
          if (model == MEMMODEL_SEQ_CST
              || model == MEMMODEL_RELEASE
              || model == MEMMODEL_ACQ_REL)
-           expand_builtin_mem_thread_fence (model);
+           expand_mem_thread_fence (model);
 
          create_output_operand (&ops[0], target, mode);
          create_fixed_operand (&ops[1], mem);
@@ -7403,7 +7403,7 @@ expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model,
              if (model == MEMMODEL_SEQ_CST
                  || model == MEMMODEL_RELEASE
                  || model == MEMMODEL_ACQ_REL)
-               expand_builtin_mem_thread_fence (model);
+               expand_mem_thread_fence (model);
 
              addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
              return emit_library_call_value (libfunc, target, LCT_NORMAL,
@@ -7556,6 +7556,76 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
   return true;
 }
 
+/* Generate asm volatile("" : : : "memory") as the memory barrier.  */
+
+static void
+expand_asm_memory_barrier (void)
+{
+  rtx asm_op, clob;
+
+  asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
+                                rtvec_alloc (0), rtvec_alloc (0),
+                                rtvec_alloc (0), UNKNOWN_LOCATION);
+  MEM_VOLATILE_P (asm_op) = 1;
+
+  clob = gen_rtx_SCRATCH (VOIDmode);
+  clob = gen_rtx_MEM (BLKmode, clob);
+  clob = gen_rtx_CLOBBER (VOIDmode, clob);
+
+  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
+}
+
+/* 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
+#ifndef HAVE_memory_barrier
+# define HAVE_memory_barrier 0
+# define gen_memory_barrier()  (gcc_unreachable (), NULL_RTX)
+#endif
+
+void
+expand_mem_thread_fence (enum memmodel model)
+{
+  if (HAVE_mem_thread_fence)
+    emit_insn (gen_mem_thread_fence (GEN_INT (model)));
+  else if (model != MEMMODEL_RELAXED)
+    {
+      if (HAVE_memory_barrier)
+       emit_insn (gen_memory_barrier ());
+      else if (synchronize_libfunc != NULL_RTX)
+       emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
+      else
+       expand_asm_memory_barrier ();
+    }
+}
+
+/* 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
+
+void
+expand_mem_signal_fence (enum memmodel model)
+{
+  if (HAVE_mem_signal_fence)
+    emit_insn (gen_mem_signal_fence (GEN_INT (model)));
+  else if (model != MEMMODEL_RELAXED)
+    {
+      /* By default 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.  */
+      expand_asm_memory_barrier ();
+    }
+}
+
 /* This function expands the atomic load operation:
    return the atomically loaded value in MEM.
 
@@ -7598,13 +7668,13 @@ expand_atomic_load (rtx target, rtx mem, enum memmodel model)
     target = gen_reg_rtx (mode);
 
   /* Emit the appropriate barrier before the load.  */
-  expand_builtin_mem_thread_fence (model);
+  expand_mem_thread_fence (model);
 
   emit_move_insn (target, mem);
 
   /* For SEQ_CST, also emit a barrier after the load.  */
   if (model == MEMMODEL_SEQ_CST)
-    expand_builtin_mem_thread_fence (model);
+    expand_mem_thread_fence (model);
 
   return target;
 }
@@ -7645,7 +7715,7 @@ expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
            {
              /* lock_release is only a release barrier.  */
              if (model == MEMMODEL_SEQ_CST)
-               expand_builtin_mem_thread_fence (model);
+               expand_mem_thread_fence (model);
              return const0_rtx;
            }
        }
@@ -7665,13 +7735,13 @@ expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
 
   /* If there is no mem_store, default to a move with barriers */
   if (model == MEMMODEL_SEQ_CST || model == MEMMODEL_RELEASE)
-    expand_builtin_mem_thread_fence (model);
+    expand_mem_thread_fence (model);
 
   emit_move_insn (mem, val);
 
   /* For SEQ_CST, also emit a barrier after the load.  */
   if (model == MEMMODEL_SEQ_CST)
-    expand_builtin_mem_thread_fence (model);
+    expand_mem_thread_fence (model);
 
   return const0_rtx;
 }
index 654d276..ec13f6f 100644 (file)
@@ -978,6 +978,10 @@ extern bool can_atomic_exchange_p (enum machine_mode, bool);
 extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
                                            enum memmodel, enum memmodel);
 
+/* Generate memory barriers.  */
+extern void expand_mem_thread_fence (enum memmodel);
+extern void expand_mem_signal_fence (enum memmodel);
+
 /* Check whether an operation represented by the code CODE is a
    convert operation that is supported by the target platform in
    vector form */