On 08/24/2011 10:23 AM, Andrew MacLeod wrote:
As I mentioned earlier, C++11 allows the memory model to be determined
at runtime. Rather than invoke a call to a runtime library or inline
a switch statement with all the valid options, just default to SEQ_CST
mode. This can easily be changed later if it is determined to be
needed.
The documentation in extend.texi looks like:
Note that the C++11 standard allows for the memory model
parameter
to be determined at runtime rather than at compile time. These
builtins will map any runtime value to __SYNC_MEM_SEQ_CST rather than
invoke a runtime library call or inline a switch statement. This is
standard compliant, safe, and the simplest approach for now.
Bootstrapped and no new regressions on x86_64-unknown-linux-gnu.
Andrew
Oops. Thats what I get for trying to do something before noon...
Index: ChangeLog.mm
===================================================================
*** ChangeLog.mm (revision 178024)
--- ChangeLog.mm (working copy)
***************
*** 1,3 ****
--- 1,9 ----
+ 2011-08-24 Andrew MacLeod <amacl...@redhat.com>
+
+ * builtins.c (get_memmodel): If the memory model is not a compile time
+ constant, default to SEQ_CST mode.
+ * doc/extend.texi: Document behaviour.
+
2011-08-23 Andrew MacLeod <amacl...@redhat.com>
* builtin-types.def (BT_CONST_VOLATILE_PTR): New primitive type.
Index: builtins.c
===================================================================
*** builtins.c (revision 177737)
--- builtins.c (working copy)
*************** get_memmodel (tree exp)
*** 5225,5240 ****
{
rtx op;
if (TREE_CODE (exp) != INTEGER_CST)
! {
! error ("invalid memory model argument to builtin");
! return MEMMODEL_RELAXED;
! }
op = expand_normal (exp);
if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
{
error ("invalid memory model argument to builtin");
! return MEMMODEL_RELAXED;
}
return (enum memmodel) INTVAL (op);
}
--- 5225,5240 ----
{
rtx op;
+ /* If the parameter is not a constant, it's a run time value so we'll just
+ convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */
if (TREE_CODE (exp) != INTEGER_CST)
! return MEMMODEL_SEQ_CST;
!
op = expand_normal (exp);
if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
{
error ("invalid memory model argument to builtin");
! return MEMMODEL_SEQ_CST;
}
return (enum memmodel) INTVAL (op);
}
Index: doc/extend.texi
===================================================================
*** doc/extend.texi (revision 177737)
--- doc/extend.texi (working copy)
*************** are not prevented from being speculated
*** 6732,6738 ****
@section Built-in functions for memory model aware atomic operations.
The following builtins approximately match the requirements for
! C++1x memory model. Many are similar to the ``__sync'' prefixed builtins, but
all also have a memory model parameter. These are all identified by being
prefixed with ``__sync_mem'', and most are overloaded such that they work
with multiple types.
--- 6732,6738 ----
@section Built-in functions for memory model aware atomic operations.
The following builtins approximately match the requirements for
! C++11 memory model. Many are similar to the ``__sync'' prefixed builtins, but
all also have a memory model parameter. These are all identified by being
prefixed with ``__sync_mem'', and most are overloaded such that they work
with multiple types.
*************** synchronization fences surrounding it in
*** 6748,6754 ****
Execution in this case is subject to the same restrictions as those builtins.
There are 6 different memory models which can be specified. These map to the
! same names in the C++1x standard. Refer there or to the GCC wiki on atomics
for
more detailed definitions. These memory models integrate both barriers to
code motion as well as synchronization requirements with other threads. These
are listed in approximately ascending order of strength.
--- 6748,6754 ----
Execution in this case is subject to the same restrictions as those builtins.
There are 6 different memory models which can be specified. These map to the
! same names in the C++11 standard. Refer there or to the GCC wiki on atomics
for
more detailed definitions. These memory models integrate both barriers to
code motion as well as synchronization requirements with other threads. These
are listed in approximately ascending order of strength.
*************** stores in all threads.
*** 6773,6782 ****
@end table
When implementing patterns for these builtins, the memory model parameter can
! be ignored as long as the pattern implements the most restrictive
__SYNC_MEM_SEQ_CST
! model. Any of the other memory models will execute correctly with this
! memory model but they may not execute as efficiently as they could with a more
! appropriate implemention of the relaxed requirements.
@item @var{type} __sync_mem_load (@var{type} *ptr, int memmodel)
@findex __sync_mem_load
--- 6773,6788 ----
@end table
When implementing patterns for these builtins, the memory model parameter can
! be ignored as long as the pattern implements the most restrictive
! __SYNC_MEM_SEQ_CST model. Any of the other memory models will execute
! correctly with this memory model but they may not execute as efficiently as
! they could with a more appropriate implemention of the relaxed requirements.
!
! Note that the C++11 standard allows for the memory model parameter to be
! determined at runtime rather than at compile time. These builtins will map
any
! runtime value to __SYNC_MEM_SEQ_CST rather than invoke a runtime library
! call or inline a switch statement. This is standard compliant, safe, and the
! simplest approach for now.
@item @var{type} __sync_mem_load (@var{type} *ptr, int memmodel)
@findex __sync_mem_load