On 11/28/2011 11:42 AM, Joseph S. Myers wrote:
On Mon, 28 Nov 2011, Andrew MacLeod wrote:

That would be why cppbuiltin.c, defining __SIZEOF_POINTER__, needs to use
the POINTER_SIZE macro instead of directly using ptr_type_node.  You may
need to do something similar.

   /* ptr_type_node can't be used here since ptr_mode is only set when
      toplev calls backend_init which is not done with -E switch.  */
   cpp_define_formatted (pfile, "__SIZEOF_POINTER__=%d",
                         POINTER_SIZE / BITS_PER_UNIT);

How bizarre... thanks you saved me some hair pulling I'm sure :-) That does work, here's a patch which does that.. bootstraps on x86_64-unknown-linux-gnu and has no new regressions. OK for mainline?

Andrew
        c-family
        * c-cpp-builtin.c (cpp_atomic_builtins):New.  Emit all atomic
        predefines in one place.  Add LOCK_FREE predefines.
        (c_cpp_builtins): Move Legacy HAVE_SYNC predefines to
        new func.

        libstdc++-v3
        * include/bits/atomic_base.h (ATOMIC_*_LOCK_FREE): Use new cpp
        predefined macros.
        * testsuite/29_atomics/headers/atomic/macros.cc: Add BOOL and POINTER
        macro checks.  Check for expected compile time values.

Index: gcc/c-family/c-cppbuiltin.c
===================================================================
*** gcc/c-family/c-cppbuiltin.c (revision 181698)
--- gcc/c-family/c-cppbuiltin.c (working copy)
*************** c_cpp_builtins_optimize_pragma (cpp_read
*** 568,573 ****
--- 568,684 ----
  }
  
  
+ /* This function will emit cpp macros to indicate the presence of various lock
+    free atomic operations.  */
+    
+ static void
+ cpp_atomic_builtins (cpp_reader *pfile)
+ {
+   /* Set a flag for each size of object that compare and swap exists for up to
+      a 16 byte object.  */
+ #define SWAP_LIMIT  17
+   bool have_swap[SWAP_LIMIT];
+   unsigned int psize;
+ 
+   /* Clear the map of sizes compare_and swap exists for.  */
+   memset (have_swap, 0, sizeof (have_swap));
+ 
+   /* Tell source code if the compiler makes sync_compare_and_swap
+      builtins available.  */
+ #ifndef HAVE_sync_compare_and_swapqi
+ #define HAVE_sync_compare_and_swapqi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapqi
+ #define HAVE_atomic_compare_and_swapqi 0
+ #endif
+ 
+   if (HAVE_sync_compare_and_swapqi || HAVE_atomic_compare_and_swapqi)
+     {
+       cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+       have_swap[1] = true;
+     }
+ 
+ #ifndef HAVE_sync_compare_and_swaphi
+ #define HAVE_sync_compare_and_swaphi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swaphi
+ #define HAVE_atomic_compare_and_swaphi 0
+ #endif
+   if (HAVE_sync_compare_and_swaphi || HAVE_atomic_compare_and_swaphi)
+     {
+       cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+       have_swap[2] = true;
+     }
+ 
+ #ifndef HAVE_sync_compare_and_swapsi
+ #define HAVE_sync_compare_and_swapsi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapsi
+ #define HAVE_atomic_compare_and_swapsi 0
+ #endif
+   if (HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi)
+     {
+       cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+       have_swap[4] = true;
+     }
+ 
+ #ifndef HAVE_sync_compare_and_swapdi
+ #define HAVE_sync_compare_and_swapdi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapdi
+ #define HAVE_atomic_compare_and_swapdi 0
+ #endif
+   if (HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi)
+     {
+       cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+       have_swap[8] = true;
+     }
+ 
+ #ifndef HAVE_sync_compare_and_swapti
+ #define HAVE_sync_compare_and_swapti 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapti
+ #define HAVE_atomic_compare_and_swapti 0
+ #endif
+   if (HAVE_sync_compare_and_swapti || HAVE_atomic_compare_and_swapti)
+     {
+       cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
+       have_swap[16] = true;
+     }
+ 
+   /* Tell the source code about various types.  These map to the C++11 and C1x
+      macros where 2 indicates lock-free always, and 1 indicates sometimes
+      lock free.  */
+ #define SIZEOF_NODE(T) (tree_low_cst (TYPE_SIZE_UNIT (T), 1))
+ #define SWAP_INDEX(T) ((SIZEOF_NODE (T) < SWAP_LIMIT) ? SIZEOF_NODE (T) : 0)
+   builtin_define_with_int_value ("__GCC_ATOMIC_BOOL_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (boolean_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_CHAR_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (signed_char_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_CHAR16_T_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (char16_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_CHAR32_T_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (char32_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_WCHAR_T_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (wchar_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_SHORT_LOCK_FREE", 
+                     (have_swap[SWAP_INDEX (short_integer_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_INT_LOCK_FREE", 
+                       (have_swap[SWAP_INDEX (integer_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_LONG_LOCK_FREE", 
+                     (have_swap[SWAP_INDEX (long_integer_type_node)]? 2 : 1));
+   builtin_define_with_int_value ("__GCC_ATOMIC_LLONG_LOCK_FREE", 
+               (have_swap[SWAP_INDEX (long_long_integer_type_node)]? 2 : 1));
+ 
+   /* ptr_type_node can't be used here since ptr_mode is only set when
+      toplev calls backend_init which is not done with -E  or pch.  */
+   psize = POINTER_SIZE / BITS_PER_UNIT;
+   if (psize >= SWAP_LIMIT)
+     psize = 0;
+   builtin_define_with_int_value ("__GCC_ATOMIC_POINTER_LOCK_FREE", 
+                       (have_swap[psize]? 2 : 1));
+ }
+ 
  /* Hook that registers front end and target-specific built-ins.  */
  void
  c_cpp_builtins (cpp_reader *pfile)
*************** c_cpp_builtins (cpp_reader *pfile)
*** 756,808 ****
    if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node))
      cpp_define (pfile, "__WCHAR_UNSIGNED__");
  
!   /* Tell source code if the compiler makes sync_compare_and_swap
!      builtins available.  */
! #ifndef HAVE_sync_compare_and_swapqi
! #define HAVE_sync_compare_and_swapqi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapqi
! #define HAVE_atomic_compare_and_swapqi 0
! #endif
!   if (HAVE_sync_compare_and_swapqi || HAVE_atomic_compare_and_swapqi)
!     cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
! 
! #ifndef HAVE_sync_compare_and_swaphi
! #define HAVE_sync_compare_and_swaphi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swaphi
! #define HAVE_atomic_compare_and_swaphi 0
! #endif
!   if (HAVE_sync_compare_and_swaphi || HAVE_atomic_compare_and_swaphi)
!     cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
! 
! #ifndef HAVE_sync_compare_and_swapsi
! #define HAVE_sync_compare_and_swapsi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapsi
! #define HAVE_atomic_compare_and_swapsi 0
! #endif
!   if (HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi)
!     cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
! 
! #ifndef HAVE_sync_compare_and_swapdi
! #define HAVE_sync_compare_and_swapdi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapdi
! #define HAVE_atomic_compare_and_swapdi 0
! #endif
!   if (HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi)
!     cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
! 
! #ifndef HAVE_sync_compare_and_swapti
! #define HAVE_sync_compare_and_swapti 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapti
! #define HAVE_atomic_compare_and_swapti 0
! #endif
!   if (HAVE_sync_compare_and_swapti || HAVE_atomic_compare_and_swapti)
!     cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
! 
  #ifdef DWARF2_UNWIND_INFO
    if (dwarf2out_do_cfi_asm ())
      cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM");
--- 867,874 ----
    if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node))
      cpp_define (pfile, "__WCHAR_UNSIGNED__");
  
!   cpp_atomic_builtins (pfile);
!     
  #ifdef DWARF2_UNWIND_INFO
    if (dwarf2out_do_cfi_asm ())
      cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM");
Index: libstdc++-v3/include/bits/atomic_base.h
===================================================================
*** libstdc++-v3/include/bits/atomic_base.h     (revision 181698)
--- libstdc++-v3/include/bits/atomic_base.h     (working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE_VERSION
*** 91,108 ****
  
    /// Lock-free Property
  
- #define LOCKFREE_PROP(T) (__atomic_always_lock_free (sizeof (T), 0) ? 2 : 1)
  
! #define ATOMIC_BOOL_LOCK_FREE         LOCKFREE_PROP (bool)
! #define ATOMIC_CHAR_LOCK_FREE                 LOCKFREE_PROP (char)
! #define ATOMIC_CHAR16_T_LOCK_FREE     LOCKFREE_PROP (char16_t)
! #define ATOMIC_CHAR32_T_LOCK_FREE     LOCKFREE_PROP (char32_t)
! #define ATOMIC_WCHAR_T_LOCK_FREE      LOCKFREE_PROP (wchar_t)
! #define ATOMIC_SHORT_LOCK_FREE                LOCKFREE_PROP (short)
! #define ATOMIC_INT_LOCK_FREE          LOCKFREE_PROP (int)
! #define ATOMIC_LONG_LOCK_FREE         LOCKFREE_PROP (long)
! #define ATOMIC_LLONG_LOCK_FREE                LOCKFREE_PROP (long long)
! #define ATOMIC_POINTER_LOCK_FREE      LOCKFREE_PROP (void *)
  
    // Base types for atomics.
    template<typename _IntTp>
--- 91,107 ----
  
    /// Lock-free Property
  
  
! #define ATOMIC_BOOL_LOCK_FREE         __GCC_ATOMIC_BOOL_LOCK_FREE
! #define ATOMIC_CHAR_LOCK_FREE         __GCC_ATOMIC_CHAR_LOCK_FREE
! #define ATOMIC_WCHAR_T_LOCK_FREE      __GCC_ATOMIC_WCHAR_T_LOCK_FREE
! #define ATOMIC_CHAR16_T_LOCK_FREE     __GCC_ATOMIC_CHAR16_T_LOCK_FREE
! #define ATOMIC_CHAR32_T_LOCK_FREE     __GCC_ATOMIC_CHAR32_T_LOCK_FREE
! #define ATOMIC_SHORT_LOCK_FREE                __GCC_ATOMIC_SHORT_LOCK_FREE
! #define ATOMIC_INT_LOCK_FREE          __GCC_ATOMIC_INT_LOCK_FREE
! #define ATOMIC_LONG_LOCK_FREE         __GCC_ATOMIC_LONG_LOCK_FREE
! #define ATOMIC_LLONG_LOCK_FREE                __GCC_ATOMIC_LLONG_LOCK_FREE
! #define ATOMIC_POINTER_LOCK_FREE      __GCC_ATOMIC_POINTER_LOCK_FREE
  
    // Base types for atomics.
    template<typename _IntTp>
Index: libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc
===================================================================
*** libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc  (revision 
181698)
--- libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc  (working copy)
***************
*** 20,25 ****
--- 20,29 ----
  
  #include <atomic>
  
+ #ifndef ATOMIC_BOOL_LOCK_FREE 
+ # error "ATOMIC_BOOL_LOCK_FREE must be a macro"
+ #endif
+ 
  #ifndef ATOMIC_CHAR_LOCK_FREE 
  # error "ATOMIC_CHAR_LOCK_FREE must be a macro"
  #endif
***************
*** 52,57 ****
--- 56,65 ----
  # error "ATOMIC_LLONG_LOCK_FREE must be a macro"
  #endif
  
+ #ifndef ATOMIC_POINTER_LOCK_FREE 
+ # error "ATOMIC_POINTER_LOCK_FREE must be a macro"
+ #endif
+ 
  #ifndef ATOMIC_FLAG_INIT
      #error "ATOMIC_FLAG_INIT_must_be_a_macro"
  #endif
*************** extern void abort(void);
*** 65,99 ****
  
  int main ()
  {
!  if (ATOMIC_CHAR_LOCK_FREE != 0 && ATOMIC_CHAR_LOCK_FREE != 1
!      && ATOMIC_CHAR_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_CHAR16_T_LOCK_FREE != 0 && ATOMIC_CHAR16_T_LOCK_FREE != 1
!      && ATOMIC_CHAR16_T_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_CHAR32_T_LOCK_FREE != 0 && ATOMIC_CHAR32_T_LOCK_FREE != 1
!      && ATOMIC_CHAR32_T_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_WCHAR_T_LOCK_FREE != 0 && ATOMIC_WCHAR_T_LOCK_FREE != 1
!      && ATOMIC_WCHAR_T_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_SHORT_LOCK_FREE != 0 && ATOMIC_SHORT_LOCK_FREE != 1
!      && ATOMIC_SHORT_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_INT_LOCK_FREE != 0 && ATOMIC_INT_LOCK_FREE != 1
!      && ATOMIC_INT_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_LONG_LOCK_FREE != 0 && ATOMIC_LONG_LOCK_FREE != 1
!      && ATOMIC_LONG_LOCK_FREE != 2)
     abort ();
  
!  if (ATOMIC_LLONG_LOCK_FREE != 0 && ATOMIC_LLONG_LOCK_FREE != 1
!      && ATOMIC_LLONG_LOCK_FREE != 2)
     abort ();
  }
--- 73,115 ----
  
  int main ()
  {
! #if (ATOMIC_BOOL_LOCK_FREE != 1 && ATOMIC_BOOL_LOCK_FREE != 2)
!    abort ();
! #endif
! 
! #if (ATOMIC_CHAR_LOCK_FREE != 1 && ATOMIC_CHAR_LOCK_FREE != 2)
!    abort ();
! #endif
! 
! #if (ATOMIC_CHAR16_T_LOCK_FREE != 1 && ATOMIC_CHAR16_T_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_CHAR32_T_LOCK_FREE != 1 && ATOMIC_CHAR32_T_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_WCHAR_T_LOCK_FREE != 1 && ATOMIC_WCHAR_T_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_SHORT_LOCK_FREE != 1 && ATOMIC_SHORT_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_INT_LOCK_FREE != 1 && ATOMIC_INT_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_LONG_LOCK_FREE != 1 && ATOMIC_LONG_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_LLONG_LOCK_FREE != 1 && ATOMIC_LLONG_LOCK_FREE != 2)
     abort ();
+ #endif
  
! #if (ATOMIC_POINTER_LOCK_FREE != 1 && ATOMIC_POINTER_LOCK_FREE != 2)
     abort ();
+ #endif
  }

Reply via email to