On 29/05/15 20:40, Jason Merrill wrote:
On 05/29/2015 09:18 AM, Ramana Radhakrishnan wrote:
+static tree
+build_atomic_load_byte (tree src, HOST_WIDE_INT model)

This function needs a comment.  The C++ changes are OK with that.

Jason


I'm assuming your review and rth's review constitute an OK.

Given no regressions on aarch64-none-linux-gnu, arm-none-linux-gnueabihf and powerpc, I've applied the attached patch.

Ramana

2015-06-04  Ramana Radhakrishnan  <ramana.radhakrish...@arm.com>

        PR c++/66192
        PR target/66200
        * doc/tm.texi: Regenerate.
        * doc/tm.texi.in (TARGET_RELAXED_ORDERING): Delete.
        * target.def (TARGET_RELAXED_ORDERING): Likewise.
        * config/alpha/alpha.c (TARGET_RELAXED_ORDERING): Likewise.
        * config/ia64/ia64.c (TARGET_RELAXED_ORDERING): Likewise.
        * config/rs6000/rs6000.c (TARGET_RELAXED_ORDERING): Likewise.
        * config/sparc/linux.h (SPARC_RELAXED_ORDERING): Likewise.
        * config/sparc/linux64.h (SPARC_RELAXED_ORDERING): Likewise.
        * config/sparc/sparc.c (TARGET_RELAXED_ORDERING): Likewise.
        * config/sparc/sparc.h (SPARC_RELAXED_ORDERING): Likewise.
        * system.h (TARGET_RELAXED_ORDERING): Poison.

2015-06-04  Ramana Radhakrishnan  <ramana.radhakrish...@arm.com>

        PR c++/66192
        PR target/66200
        * cp-tree.h (get_guard_cond): Adjust declaration
        * decl.c (expand_static_init): Use atomic load acquire
        and adjust call to get_guard_cond.
        * decl2.c (build_atomic_load_byte): New function.
        (get_guard_cond): Handle thread_safety.
        (one_static_initialization_or_destruction): Adjust call to
        get_guard_cond.
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog       (revision 224117)
+++ gcc/ChangeLog       (working copy)
@@ -1,3 +1,18 @@
+2015-06-04  Ramana Radhakrishnan  <ramana.radhakrish...@arm.com>
+
+       PR c++/66192
+       PR target/66200
+       * doc/tm.texi: Regenerate.
+       * doc/tm.texi.in (TARGET_RELAXED_ORDERING): Delete.
+       * target.def (TARGET_RELAXED_ORDERING): Likewise.
+       * config/alpha/alpha.c (TARGET_RELAXED_ORDERING): Likewise.
+       * config/ia64/ia64.c (TARGET_RELAXED_ORDERING): Likewise.
+       * config/rs6000/rs6000.c (TARGET_RELAXED_ORDERING): Likewise.
+       * config/sparc/linux.h (SPARC_RELAXED_ORDERING): Likewise.
+       * config/sparc/linux64.h (SPARC_RELAXED_ORDERING): Likewise.
+       * config/sparc/sparc.c (TARGET_RELAXED_ORDERING): Likewise.
+       * config/sparc/sparc.h (SPARC_RELAXED_ORDERING): Likewise.
+
 2015-06-04  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_override_options): Unconditionally
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c    (revision 224117)
+++ gcc/config/alpha/alpha.c    (working copy)
@@ -9987,12 +9987,6 @@
 #undef TARGET_EXPAND_BUILTIN_VA_START
 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
 
-/* The Alpha architecture does not require sequential consistency.  See
-   http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
-   for an example of how it can be violated in practice.  */
-#undef TARGET_RELAXED_ORDERING
-#define TARGET_RELAXED_ORDERING true
-
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE alpha_option_override
 
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c      (revision 224117)
+++ gcc/config/ia64/ia64.c      (working copy)
@@ -630,11 +630,6 @@
 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
   ia64_libgcc_floating_mode_supported_p
 
-/* ia64 architecture manual 4.4.7: ... reads, writes, and flushes may occur
-   in an order different from the specified program order.  */
-#undef TARGET_RELAXED_ORDERING
-#define TARGET_RELAXED_ORDERING true
-
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P ia64_legitimate_constant_p
 #undef TARGET_LEGITIMATE_ADDRESS_P
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 224117)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -1620,17 +1620,6 @@
 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
 #endif
 
-/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
-   The PowerPC architecture requires only weak consistency among
-   processors--that is, memory accesses between processors need not be
-   sequentially consistent and memory accesses among processors can occur
-   in any order. The ability to order memory accesses weakly provides
-   opportunities for more efficient use of the system bus. Unless a
-   dependency exists, the 604e allows read operations to precede store
-   operations.  */
-#undef TARGET_RELAXED_ORDERING
-#define TARGET_RELAXED_ORDERING true
-
 #ifdef HAVE_AS_TLS
 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
Index: gcc/config/sparc/linux.h
===================================================================
--- gcc/config/sparc/linux.h    (revision 224117)
+++ gcc/config/sparc/linux.h    (working copy)
@@ -139,12 +139,6 @@
 /* Static stack checking is supported by means of probes.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
 
-/* Linux currently uses RMO in uniprocessor mode, which is equivalent to
-   TMO, and TMO in multiprocessor mode.  But they reserve the right to
-   change their minds.  */
-#undef SPARC_RELAXED_ORDERING
-#define SPARC_RELAXED_ORDERING true
-
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
Index: gcc/config/sparc/linux64.h
===================================================================
--- gcc/config/sparc/linux64.h  (revision 224117)
+++ gcc/config/sparc/linux64.h  (working copy)
@@ -253,12 +253,6 @@
 /* Static stack checking is supported by means of probes.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
 
-/* Linux currently uses RMO in uniprocessor mode, which is equivalent to
-   TMO, and TMO in multiprocessor mode.  But they reserve the right to
-   change their minds.  */
-#undef SPARC_RELAXED_ORDERING
-#define SPARC_RELAXED_ORDERING true
-
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c    (revision 224117)
+++ gcc/config/sparc/sparc.c    (working copy)
@@ -808,9 +808,6 @@
 #define TARGET_ATTRIBUTE_TABLE sparc_attribute_table
 #endif
 
-#undef TARGET_RELAXED_ORDERING
-#define TARGET_RELAXED_ORDERING SPARC_RELAXED_ORDERING
-
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE sparc_option_override
 
Index: gcc/config/sparc/sparc.h
===================================================================
--- gcc/config/sparc/sparc.h    (revision 224117)
+++ gcc/config/sparc/sparc.h    (working copy)
@@ -106,17 +106,6 @@
 
 #define SPARC_DEFAULT_CMODEL CM_32
 
-/* The SPARC-V9 architecture defines a relaxed memory ordering model (RMO)
-   which requires the following macro to be true if enabled.  Prior to V9,
-   there are no instructions to even talk about memory synchronization.
-   Note that the UltraSPARC III processors don't implement RMO, unlike the
-   UltraSPARC II processors.  Niagara, Niagara-2, and Niagara-3 do not
-   implement RMO either.
-
-   Default to false; for example, Solaris never enables RMO, only ever uses
-   total memory ordering (TMO).  */
-#define SPARC_RELAXED_ORDERING false
-
 /* Do not use the .note.GNU-stack convention by default.  */
 #define NEED_INDICATE_EXEC_STACK 0
 
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog    (revision 224117)
+++ gcc/cp/ChangeLog    (working copy)
@@ -1,3 +1,15 @@
+2015-06-04  Ramana Radhakrishnan  <ramana.radhakrish...@arm.com>
+
+       PR c++/66192
+       PR target/66200
+       * cp-tree.h (get_guard_cond): Adjust declaration
+       * decl.c (expand_static_init): Use atomic load acquire
+       and adjust call to get_guard_cond.
+       * decl2.c (build_atomic_load_byte): New function.
+       (get_guard_cond): Handle thread_safety.
+       (one_static_initialization_or_destruction): Adjust call to
+       get_guard_cond.
+
 2015-06-03  Jason Merrill  <ja...@redhat.com>
 
        PR c++/44282
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h    (revision 224117)
+++ gcc/cp/cp-tree.h    (working copy)
@@ -5491,7 +5491,7 @@
 extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
 extern tree cp_build_parm_decl                 (tree, tree);
 extern tree get_guard                          (tree);
-extern tree get_guard_cond                     (tree);
+extern tree get_guard_cond                     (tree, bool);
 extern tree set_guard                          (tree);
 extern tree get_tls_wrapper_fn                 (tree);
 extern void mark_needed                                (tree);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c       (revision 224117)
+++ gcc/cp/decl.c       (working copy)
@@ -7227,7 +7227,7 @@
         looks like:
 
           static <type> guard;
-          if (!guard.first_byte) {
+          if (!__atomic_load (guard.first_byte)) {
             if (__cxa_guard_acquire (&guard)) {
               bool flag = false;
               try {
@@ -7257,17 +7257,12 @@
       /* Create the guard variable.  */
       guard = get_guard (decl);
 
-      /* This optimization isn't safe on targets with relaxed memory
-        consistency.  On such targets we force synchronization in
-        __cxa_guard_acquire.  */
-      if (!targetm.relaxed_ordering || !thread_guard)
-       {
-         /* Begin the conditional initialization.  */
-         if_stmt = begin_if_stmt ();
-         finish_if_stmt_cond (get_guard_cond (guard), if_stmt);
-         then_clause = begin_compound_stmt (BCS_NO_SCOPE);
-       }
+      /* Begin the conditional initialization.  */
+      if_stmt = begin_if_stmt ();
 
+      finish_if_stmt_cond (get_guard_cond (guard, thread_guard), if_stmt);
+      then_clause = begin_compound_stmt (BCS_NO_SCOPE);
+
       if (thread_guard)
        {
          tree vfntype = NULL_TREE;
@@ -7335,12 +7330,9 @@
          finish_if_stmt (inner_if_stmt);
        }
 
-      if (!targetm.relaxed_ordering || !thread_guard)
-       {
-         finish_compound_stmt (then_clause);
-         finish_then_clause (if_stmt);
-         finish_if_stmt (if_stmt);
-       }
+      finish_compound_stmt (then_clause);
+      finish_then_clause (if_stmt);
+      finish_if_stmt (if_stmt);
     }
   else if (DECL_THREAD_LOCAL_P (decl))
     tls_aggregates = tree_cons (init, decl, tls_aggregates);
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c      (revision 224117)
+++ gcc/cp/decl2.c      (working copy)
@@ -3034,6 +3034,27 @@
   return guard;
 }
 
+/* Return an atomic load of src with the appropriate memory model.  */
+
+static tree
+build_atomic_load_byte (tree src, HOST_WIDE_INT model)
+{
+  tree ptr_type = build_pointer_type (char_type_node);
+  tree mem_model = build_int_cst (integer_type_node, model);
+  tree t, addr, val;
+  unsigned int size;
+  int fncode;
+
+  size = tree_to_uhwi (TYPE_SIZE_UNIT (char_type_node));
+
+  fncode = BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
+  t = builtin_decl_implicit ((enum built_in_function) fncode);
+
+  addr = build1 (ADDR_EXPR, ptr_type, src);
+  val = build_call_expr (t, 2, addr, mem_model);
+  return val;
+}
+
 /* Return those bits of the GUARD variable that should be set when the
    guarded entity is actually initialized.  */
 
@@ -3060,12 +3081,14 @@
    variable has already been initialized.  */
 
 tree
-get_guard_cond (tree guard)
+get_guard_cond (tree guard, bool thread_safe)
 {
   tree guard_value;
 
-  /* Check to see if the GUARD is zero.  */
-  guard = get_guard_bits (guard);
+  if (!thread_safe)
+    guard = get_guard_bits (guard);
+  else
+    guard = build_atomic_load_byte (guard, MEMMODEL_ACQUIRE);
 
   /* Mask off all but the low bit.  */
   if (targetm.cxx.guard_mask_bit ())
@@ -3681,7 +3704,7 @@
          /* When using __cxa_atexit, we never try to destroy
             anything from a static destructor.  */
          gcc_assert (initp);
-         guard_cond = get_guard_cond (guard);
+         guard_cond = get_guard_cond (guard, false);
        }
       /* If we don't have __cxa_atexit, then we will be running
         destructors from .fini sections, or their equivalents.  So,
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 224117)
+++ gcc/doc/tm.texi     (working copy)
@@ -11395,16 +11395,6 @@
 and scanf formatter settings.
 @end defmac
 
-@deftypevr {Target Hook} bool TARGET_RELAXED_ORDERING
-If set to @code{true}, means that the target's memory model does not
-guarantee that loads which do not depend on one another will access
-main memory in the order of the instruction stream; if ordering is
-important, an explicit memory barrier must be used.  This is true of
-many recent processors which implement a policy of ``relaxed,''
-``weak,'' or ``release'' memory consistency, such as Alpha, PowerPC,
-and ia64.  The default is @code{false}.
-@end deftypevr
-
 @deftypefn {Target Hook} {const char *} TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN 
(const_tree @var{typelist}, const_tree @var{funcdecl}, const_tree @var{val})
 If defined, this macro returns the diagnostic message when it is
 illegal to pass argument @var{val} to function @var{funcdecl}
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in  (revision 224117)
+++ gcc/doc/tm.texi.in  (working copy)
@@ -8143,8 +8143,6 @@
 and scanf formatter settings.
 @end defmac
 
-@hook TARGET_RELAXED_ORDERING
-
 @hook TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
 
 @hook TARGET_INVALID_CONVERSION
Index: gcc/system.h
===================================================================
--- gcc/system.h        (revision 224117)
+++ gcc/system.h        (working copy)
@@ -964,7 +964,7 @@
        TARGET_HANDLE_PRAGMA_EXTERN_PREFIX \
        TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN \
        TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD \
-       TARGET_MD_ASM_CLOBBERS
+       TARGET_MD_ASM_CLOBBERS TARGET_RELAXED_ORDERING
 
 /* Arrays that were deleted in favor of a functional interface.  */
  #pragma GCC poison built_in_decls implicit_built_in_decls
Index: gcc/target.def
===================================================================
--- gcc/target.def      (revision 224117)
+++ gcc/target.def      (working copy)
@@ -5785,19 +5785,6 @@
 this to be done.  The default is false.",
  bool, false)
 
-/* True if the target is allowed to reorder memory accesses unless
-   synchronization is explicitly requested.  */
-DEFHOOKPOD
-(relaxed_ordering,
- "If set to @code{true}, means that the target's memory model does not\n\
-guarantee that loads which do not depend on one another will access\n\
-main memory in the order of the instruction stream; if ordering is\n\
-important, an explicit memory barrier must be used.  This is true of\n\
-many recent processors which implement a policy of ``relaxed,''\n\
-``weak,'' or ``release'' memory consistency, such as Alpha, PowerPC,\n\
-and ia64.  The default is @code{false}.",
- bool, false)
-
 /* Returns true if we should generate exception tables for use with the
    ARM EABI.  The effects the encoding of function exception specifications.  
*/
 DEFHOOKPOD

Reply via email to