Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 224117) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,18 @@ +2015-06-04 Ramana Radhakrishnan + + 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 * 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 + + 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 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 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